Skip to content

Commit

Permalink
fix: agreement signing now updates in the UI correctly
Browse files Browse the repository at this point in the history
- Updated `useVerifyAuthentication` to return a promise that resolves after state updates, ensuring proper loading state management.
- Enhanced agreement signing component to utilize `verifyAuthentication` and invalidate queries after signing, improving data consistency.
- Refactored agreements list component to use `Suspense` for better loading handling and ensure fresh data on mount.
  • Loading branch information
Sampiiiii committed Jan 8, 2025
1 parent 019da35 commit d53a4c1
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 30 deletions.
33 changes: 19 additions & 14 deletions apps/forge/src/hooks/useVerifyAuthentication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,22 +61,26 @@ export const useVerifyAuthentication = () => {
const userData = response.data;
const lowercaseRoles = userData.roles.map((role) => role.name.toLowerCase());

// Update states sequentially
setUser(userData);
setOriginalUserRoles(lowercaseRoles);
setUserRoles(lowercaseRoles);
setAuthEffect(true);
isLoggedOutRef.current = false;

// Small delay before setting loading to false
setTimeout(() => {
if (mountedRef.current) {
setLoading(false);
}
}, 100);
// Return a promise that resolves when all state updates are complete
return new Promise<void>((resolve) => {
// Update states sequentially
setUser(userData);
setOriginalUserRoles(lowercaseRoles);
setUserRoles(lowercaseRoles);
setAuthEffect(true);
isLoggedOutRef.current = false;

// Resolve after a small delay to ensure state updates are processed
setTimeout(() => {
if (mountedRef.current) {
setLoading(false);
resolve();
}
}, 100);
});
}
} catch (error) {
console.error("Auth verification error:", error); // Debug log
console.error("Auth verification error:", error);
if (!mountedRef.current) {
setLoading(false);
return;
Expand Down Expand Up @@ -122,5 +126,6 @@ export const useVerifyAuthentication = () => {
return {
user,
loading: loading && !isLoggedOutRef.current, // Only show loading if not logged out
verifyAuthentication
};
};
45 changes: 37 additions & 8 deletions apps/forge/src/routes/_authenticated/sign-in/agreements/$id.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import { Button } from "@ui/components/ui/button";
import { Checkbox } from "@ui/components/ui/checkbox";
import { Label } from "@ui/components/ui/label";
import { Separator } from "@ui/components/ui/separator";
import { useState } from "react";
import { useState, useCallback } from "react";
import Markdown from "react-markdown";
import { toast } from "sonner";
import { useQueryClient } from "@tanstack/react-query";
import { useVerifyAuthentication } from "@/hooks/useVerifyAuthentication";
import { getAgreements } from "@/services/root/getAgreements";

export default function Component() {
const { id } = Route.useParams();
Expand All @@ -18,6 +21,38 @@ export default function Component() {
const [isChecked, setIsChecked] = useState<string | boolean>(false);
const user = useUser()!;
const navigator = useNavigate();
const queryClient = useQueryClient();
const { verifyAuthentication } = useVerifyAuthentication();

const handleSignAgreement = useCallback(async () => {
if (!isChecked) return;

try {
await axiosInstance.post(`/agreements/${id}`, { user });

await Promise.all([
verifyAuthentication(),
queryClient.invalidateQueries({ queryKey: ["agreements"] })
]);

await queryClient.ensureQueryData({
queryKey: ["agreements"],
queryFn: getAgreements
});

await new Promise(resolve => setTimeout(resolve, 100));

toast.success("Successfully signed agreement");

navigator({
to: "/sign-in/agreements",
replace: true
});
} catch (error) {
console.error("Error signing agreement:", error);
toast.error("Failed to sign agreement");
}
}, [isChecked, id, user, queryClient, verifyAuthentication, navigator]);

return (
<>
Expand Down Expand Up @@ -48,13 +83,7 @@ export default function Component() {
<Button
className="mt-4 w-full"
disabled={!isChecked}
onClick={async () => {
if (isChecked) {
await axiosInstance.post(`/agreements/${id}`, { user });
toast.success("Successfully signed agreement");
return navigator({ to: "/sign-in/agreements" });
}
}}
onClick={handleSignAgreement}
>
Confirm
</Button>
Expand Down
26 changes: 18 additions & 8 deletions apps/forge/src/routes/_authenticated/sign-in/agreements/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@ import { useQuery } from "@tanstack/react-query";
import { createFileRoute } from "@tanstack/react-router";
import { Loader } from "@ui/components/ui/loader";
import { AgreementCard } from "./-components/AgreementCard";
import { Suspense } from "react";

export default function Component() {
function AgreementsList() {
const roles = useUserRoles();
const { data: agreements, error, isPending } = useQuery({ queryKey: ["agreements"], queryFn: getAgreements }); // cannot use loader here
const { data: agreements = [] } = useQuery({
queryKey: ["agreements"],
queryFn: getAgreements,
refetchOnMount: "always",
staleTime: 0,
networkMode: "always"
});

const isRep = roles.includes("rep");
if (error) {
throw error;
}
if (isPending) {
return <Loader />;
}

// Filter agreements based on user roles
const filteredAgreements = agreements.filter((agreement) => {
Expand Down Expand Up @@ -49,6 +51,14 @@ export default function Component() {
);
}

export default function Component() {
return (
<Suspense fallback={<Loader />}>
<AgreementsList />
</Suspense>
);
}

export const Route = createFileRoute("/_authenticated/sign-in/agreements/")({
component: Component,
});

0 comments on commit d53a4c1

Please sign in to comment.