126 lines
2.7 KiB
TypeScript
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();
|
|
}
|
|
},
|
|
}));
|