diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index 323f6cc..3aa2c45 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,5 +1,6 @@
import { BrowserRouter, Navigate, Route, Routes } from "react-router-dom";
import Activate from "./pages/Activate";
+import Drawer from "./pages/Drawer";
import Home from "./pages/Home";
import Register from "./pages/Register";
import VerifyEmail from "./pages/VerifyEmail";
@@ -13,6 +14,7 @@ export default function App() {
} />
} />
} />
+ } />
} />
diff --git a/frontend/src/components/ui/FormField.tsx b/frontend/src/components/ui/FormField.tsx
index c61ef72..539e4a9 100644
--- a/frontend/src/components/ui/FormField.tsx
+++ b/frontend/src/components/ui/FormField.tsx
@@ -17,7 +17,12 @@ export default function FormField({
}: FormFieldProps) {
return (
-
{label}
+
+ {label}
+
(
+ "loading",
+ );
+ const hasCalled = useRef(false);
+ const navigate = useNavigate();
+
+ useEffect(() => {
+ if (!uidb64 || !token || hasCalled.current) return;
+
+ // prevent double api calls
+ hasCalled.current = true;
+
+ const activateAccount = async () => {
+ try {
+ await apiClient.get(`/activate/${uidb64}/${token}/`);
+ setStatus("success");
+ } catch (err) {
+ console.error("Activation error:", err);
+ setStatus("error");
+ }
+ };
+
+ activateAccount();
+ }, [uidb64, token]);
+
return (
-
-
Activate
+
+ {status === "loading" && (
+
+
+
Activating your account...
+
+ )}
+
+ {status === "success" && (
+
+
+
+
+
+ Account Activated!
+
+
+ Welcome to
+
+ Your identity is now verified and ready for timeless letters.
+
+
navigate("/login")}
+ >
+ Open Drawer
+
+
+ )}
+
+ {status === "error" && (
+
+
+
+
+
+ Activation Failed
+
+
+ The link might be expired or already used. Please try registering
+ again.
+
+
navigate("/onboard")}
+ >
+ Back to Registration
+
+
+ )}
);
}
diff --git a/frontend/src/pages/Drawer.tsx b/frontend/src/pages/Drawer.tsx
new file mode 100644
index 0000000..b89172c
--- /dev/null
+++ b/frontend/src/pages/Drawer.tsx
@@ -0,0 +1,15 @@
+import Logo from "../components/Logo";
+
+export default function Login() {
+ return (
+
+
+ Login to
+
+
+
+ Sign In
+
+
+ );
+}
diff --git a/frontend/src/pages/Register.tsx b/frontend/src/pages/Register.tsx
index 4e38d01..177d028 100644
--- a/frontend/src/pages/Register.tsx
+++ b/frontend/src/pages/Register.tsx
@@ -46,10 +46,10 @@ export default function Register() {
password: data.password,
});
navigate("/verify-email");
- } catch (err: any) {
+ } catch (err) {
console.error("Registration error:", err);
setApiError(
- err.response?.data?.message || "Registration failed. Please try again."
+ err.response?.data?.message || "Registration failed. Please try again.",
);
} finally {
setIsLoading(false);
@@ -109,7 +109,8 @@ export default function Register() {
/>
Choose a password you won't forget.
- There is no reset. If you lose it, your letters cannot be recovered.
+ There is no reset. {" "}
+ If you lose it, your letters cannot be recovered.
diff --git a/frontend/src/pages/VerifyEmail.tsx b/frontend/src/pages/VerifyEmail.tsx
index 8eb2023..f05c29c 100644
--- a/frontend/src/pages/VerifyEmail.tsx
+++ b/frontend/src/pages/VerifyEmail.tsx
@@ -5,7 +5,11 @@ export default function VerifyEmail() {
return (
-
+
@@ -25,7 +29,11 @@ export default function VerifyEmail() {
-
window.close()}>
+
window.close()}
+ onKeyDown={(e) => e.key === "Enter" && window.close()}
+ >
You can close this window now.