diff --git a/frontend/src/components/editor/ComposeCanvas.tsx b/frontend/src/components/editor/ComposeCanvas.tsx index 52e6efc..da0cbd7 100644 --- a/frontend/src/components/editor/ComposeCanvas.tsx +++ b/frontend/src/components/editor/ComposeCanvas.tsx @@ -122,7 +122,7 @@ export function ComposeCanvas({ // re-calculates height based on content and applies the zoom transform const syncViewport = useCallback(() => { if (!(fabricRef.current && wrapperRef.current)) return; - textboxRef.current.initDimensions(); + textboxRef.current?.initDimensions(); const minHeight = initialData?.canvasHeight ?? DEFAULT_LOGICAL_HEIGHT; logicalSizeRef.current.height = measureLogicalContentHeight( diff --git a/frontend/src/components/editor/PostSealModal.tsx b/frontend/src/components/editor/PostSealModal.tsx index 607b4bf..1cf964f 100644 --- a/frontend/src/components/editor/PostSealModal.tsx +++ b/frontend/src/components/editor/PostSealModal.tsx @@ -63,7 +63,11 @@ export function PostSealModal({ type="button" data-testid="view-letter-btn" className="btn btn-primary btn-sm" - onClick={() => navigate(PATHS.read(sealedTargetId!))} + onClick={() => { + if (sealedTargetId) { + navigate(PATHS.read(sealedTargetId)); + } + }} > View letter diff --git a/frontend/src/hooks/useAuth.ts b/frontend/src/hooks/useAuth.ts index ca2b8ca..92b0415 100644 --- a/frontend/src/hooks/useAuth.ts +++ b/frontend/src/hooks/useAuth.ts @@ -32,7 +32,7 @@ export const useAuth = () => { const logout = async () => { try { await api.post(endpoints.LOGOUT); - } catch (_error) { + } catch { } finally { clearAuth(); setMasterKey(null); diff --git a/frontend/src/pages/Activate.tsx b/frontend/src/pages/Activate.tsx index 2f53023..9f3de48 100644 --- a/frontend/src/pages/Activate.tsx +++ b/frontend/src/pages/Activate.tsx @@ -7,99 +7,99 @@ import { endpoints, replacePathParams } from "../config/endpoints"; import { ROUTES } from "../config/routes"; export default function Activate() { - const { uidb64, token } = useParams(); - const [status, setStatus] = useState<"loading" | "success" | "error">( - "loading", - ); - const hasCalled = useRef(false); - const navigate = useNavigate(); + const { uidb64, token } = useParams(); + const [status, setStatus] = useState<"loading" | "success" | "error">( + "loading", + ); + const hasCalled = useRef(false); + const navigate = useNavigate(); - useEffect(() => { - if (!(uidb64 && token) || hasCalled.current) return; - hasCalled.current = true; + useEffect(() => { + if (!(uidb64 && token) || hasCalled.current) return; + hasCalled.current = true; - const activateAccount = async () => { - try { - const url = replacePathParams(endpoints.ACTIVATE, { - uidb64, - token, - }); - await publicApi.get(url); - setStatus("success"); - } catch (_err) { - setStatus("error"); - } - }; - - activateAccount(); - }, [uidb64, token]); - - return ( -
- {status === "loading" && ( -
- -

Activating your account...

-
- )} - - {status === "success" && ( -
-
- -
-

- You're in. -

-

- Welcome to -
- Just one more step and you can start writing timeless letters. -

-
- -
- )} + }; - {status === "error" && ( -
-
- -
-

Activation Failed

-

- The link might be expired or already used. Please try registering - again. -

-
- + activateAccount(); + }, [uidb64, token]); + + return ( +
+ {status === "loading" && ( +
+ +

Activating your account...

+
+ )} + + {status === "success" && ( +
+
+ +
+

+ You're in. +

+

+ Welcome to +
+ Just one more step and you can start writing timeless letters. +

+
+ +
+ )} + + {status === "error" && ( +
+
+ +
+

Activation Failed

+

+ The link might be expired or already used. Please try registering + again. +

+
+ +
+ )}
- )} -
- ); + ); }