mirror of
https://github.com/andwati/cymelle.git
synced 2026-10-18 08:22:54 +00:00
final
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||||
import { createContext, useContext, useState } from "react";
|
import { createContext, useContext, useEffect, useState } from "react";
|
||||||
import { login, logout, register } from "#/api/auth";
|
import { getCurrentUser, login, logout, register } from "#/api/auth";
|
||||||
import type { AuthUser, LoginRequest, RegisterRequest } from "#/types/auth";
|
import type { AuthUser, LoginRequest, RegisterRequest } from "#/types/auth";
|
||||||
|
|
||||||
type AuthContextValue = {
|
type AuthContextValue = {
|
||||||
@@ -21,6 +21,47 @@ export const authQueryKeys = {
|
|||||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const [user, setUser] = useState<AuthUser | null>(() => readStoredUser());
|
const [user, setUser] = useState<AuthUser | null>(() => readStoredUser());
|
||||||
|
const [isLoading, setIsLoading] = useState(() => readStoredUser() !== null);
|
||||||
|
const userId = user?.id;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
let cancelled = false;
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
setIsLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsLoading(true);
|
||||||
|
getCurrentUser()
|
||||||
|
.then((currentUser) => {
|
||||||
|
if (cancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
persistUser(currentUser);
|
||||||
|
setUser(currentUser);
|
||||||
|
queryClient.setQueryData(authQueryKeys.me, currentUser);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
if (cancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
persistUser(null);
|
||||||
|
setUser(null);
|
||||||
|
queryClient.clear();
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (!cancelled) {
|
||||||
|
setIsLoading(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
cancelled = true;
|
||||||
|
};
|
||||||
|
}, [queryClient, userId]);
|
||||||
|
|
||||||
const loginMutation = useMutation({
|
const loginMutation = useMutation({
|
||||||
mutationFn: login,
|
mutationFn: login,
|
||||||
@@ -60,7 +101,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|||||||
|
|
||||||
const value: AuthContextValue = {
|
const value: AuthContextValue = {
|
||||||
user,
|
user,
|
||||||
isLoading: false,
|
isLoading,
|
||||||
login: loginMutation.mutateAsync,
|
login: loginMutation.mutateAsync,
|
||||||
register: registerMutation.mutateAsync,
|
register: registerMutation.mutateAsync,
|
||||||
logout: logoutUser,
|
logout: logoutUser,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { createFileRoute, Link, useNavigate } from "@tanstack/react-router";
|
|||||||
import { CreditCard, ShoppingCart, Trash2 } from "lucide-react";
|
import { CreditCard, ShoppingCart, Trash2 } from "lucide-react";
|
||||||
import { useMemo, useState } from "react";
|
import { useMemo, useState } from "react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
import { ApiError } from "#/api/client";
|
||||||
import { AuthDialog } from "#/components/store/AuthDialog";
|
import { AuthDialog } from "#/components/store/AuthDialog";
|
||||||
import { QuantityStepper } from "#/components/store/QuantityStepper";
|
import { QuantityStepper } from "#/components/store/QuantityStepper";
|
||||||
import { SiteHeader } from "#/components/store/SiteHeader";
|
import { SiteHeader } from "#/components/store/SiteHeader";
|
||||||
@@ -129,6 +130,15 @@ function CartPage() {
|
|||||||
});
|
});
|
||||||
await navigate({ to: "/orders" });
|
await navigate({ to: "/orders" });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
if (error instanceof ApiError && error.status === 403) {
|
||||||
|
await logout();
|
||||||
|
setAuthMode("login");
|
||||||
|
toast.error("Sign in again", {
|
||||||
|
description: "Your session expired before checkout.",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
toast.error("Checkout failed", {
|
toast.error("Checkout failed", {
|
||||||
description:
|
description:
|
||||||
error instanceof Error
|
error instanceof Error
|
||||||
|
|||||||
Reference in New Issue
Block a user