Files
hspguard/web/src/store/verify.ts

126 lines
2.7 KiB
TypeScript

import { create } from "zustand";
import type { UserProfile } from "@/types";
import {
confirmEmailApi,
finishVerificationApi,
requestEmailOtpApi,
type ConfirmEmailRequest,
} from "@/api/verify";
import { useAuth } from "./auth";
import { uploadAvatarApi } from "@/api/avatar";
export type VerifyStep = "email" | "avatar" | "review";
export interface IVerifyState {
step: VerifyStep | null | false;
redirect: string | null;
requesting: boolean;
requested: boolean;
confirming: boolean;
uploading: boolean;
verifying: boolean;
}
export interface IVerifyActions {
loadStep: (profile: UserProfile) => void;
requestOTP: () => Promise<void>;
confirmOTP: (req: ConfirmEmailRequest) => Promise<void>;
uploadAvatar: (image: File) => Promise<void>;
verify: () => Promise<void>;
setRedirect: (redirect: string) => void;
reset: () => void;
}
const initialState: IVerifyState = {
step: null,
redirect: null,
requesting: false,
requested: false,
confirming: false,
uploading: false,
verifying: false,
};
export const useVerify = create<IVerifyState & IVerifyActions>((set, get) => ({
...initialState,
reset: () => set(initialState),
loadStep: (profile) => {
if (!profile.email_verified) {
set({ step: "email" });
return;
}
if (!profile.avatar_verified) {
set({ step: "avatar" });
return;
}
if (!profile.verified) {
set({ step: "review" });
return;
}
set({ step: false });
},
requestOTP: async () => {
set({ requesting: true, requested: false });
try {
await requestEmailOtpApi();
set({ requested: true });
} catch (err) {
console.log("ERR: Failed to request OTP:", err);
} finally {
set({ requesting: false });
}
},
confirmOTP: async (req: ConfirmEmailRequest) => {
set({ confirming: true });
try {
await confirmEmailApi(req);
await useAuth.getState().authenticate();
} catch (err) {
console.log("ERR: Failed to request OTP:", err);
} finally {
set({ confirming: false });
}
},
uploadAvatar: async (image) => {
set({ uploading: true });
try {
await uploadAvatarApi(image);
await useAuth.getState().authenticate();
} catch (err) {
console.log("ERR: Failed to request OTP:", err);
} finally {
set({ uploading: false });
}
},
setRedirect: (redirect) => {
set({ redirect });
},
verify: async () => {
set({ verifying: true });
try {
await finishVerificationApi();
useAuth.getState().authenticate();
} catch (err) {
console.log("ERR: Failed to finish verification:", err);
} finally {
set({ verifying: false });
get().reset();
}
},
}));