[st] feat: 입력 - 제출 시 imr 요청 및 상태 확인, 진행 progress bar 추가
This commit is contained in:
@@ -2,6 +2,7 @@ export { getCookie, setCookie, removeCookie } from "./cookie";
|
||||
export { useMutationWrapper } from "./use-mutation-wrapper";
|
||||
export { useAlertStore } from "./use-alert-store";
|
||||
export { useDataTable } from "./use-data-table";
|
||||
export { useGlobalProgressStore } from "./use-global-progress-store";
|
||||
export { useMenuStore } from "./use-menu-store";
|
||||
export { useUserStore } from "./use-user-store";
|
||||
export { usePrompt } from "./use-prompt";
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { useContext } from "react";
|
||||
import { useStore } from "zustand";
|
||||
import type { GlobalProgressStore } from "../store/global-progress-store";
|
||||
import { StoreContext } from "../providers/store-provider";
|
||||
|
||||
export const useGlobalProgressStore = <T>(
|
||||
selector: (store: GlobalProgressStore) => T,
|
||||
): T => {
|
||||
const storeContext = useContext(StoreContext);
|
||||
|
||||
if (!storeContext) {
|
||||
throw new Error("useGlobalProgressStore must be used within StoreProvider");
|
||||
}
|
||||
|
||||
return useStore(storeContext.globalProgressStore, selector);
|
||||
};
|
||||
@@ -4,6 +4,7 @@ import { createContext, useRef } from "react";
|
||||
import {
|
||||
createAlertStore,
|
||||
createAttachmentStore,
|
||||
createGlobalProgressStore,
|
||||
createMenuStore,
|
||||
createUserStore,
|
||||
} from "../store";
|
||||
@@ -11,6 +12,7 @@ import {
|
||||
type StoreContextType = {
|
||||
alertStore: ReturnType<typeof createAlertStore>;
|
||||
attachmentStore: ReturnType<typeof createAttachmentStore>;
|
||||
globalProgressStore: ReturnType<typeof createGlobalProgressStore>;
|
||||
menuStore: ReturnType<typeof createMenuStore>;
|
||||
userStore: ReturnType<typeof createUserStore>;
|
||||
};
|
||||
@@ -25,6 +27,7 @@ export const StoreProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
storeRef.current = {
|
||||
alertStore: createAlertStore(),
|
||||
attachmentStore: createAttachmentStore(),
|
||||
globalProgressStore: createGlobalProgressStore(),
|
||||
menuStore: createMenuStore(),
|
||||
userStore: createUserStore(),
|
||||
};
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import { createStore } from "zustand/vanilla";
|
||||
|
||||
export type GlobalProgressState = {
|
||||
visible: boolean;
|
||||
label: string;
|
||||
progress: number;
|
||||
};
|
||||
|
||||
export type GlobalProgressActions = {
|
||||
show: (payload?: { label?: string; progress?: number }) => void;
|
||||
setLabel: (label: string) => void;
|
||||
setProgress: (progress: number) => void;
|
||||
hide: () => void;
|
||||
};
|
||||
|
||||
export type GlobalProgressStore = GlobalProgressState & GlobalProgressActions;
|
||||
|
||||
export const defaultGlobalProgressState: GlobalProgressState = {
|
||||
visible: false,
|
||||
label: "진행 중...",
|
||||
progress: 0,
|
||||
};
|
||||
|
||||
export const createGlobalProgressStore = (
|
||||
initState: GlobalProgressState = defaultGlobalProgressState,
|
||||
) => {
|
||||
return createStore<GlobalProgressStore>()((set) => ({
|
||||
...initState,
|
||||
show: (payload) =>
|
||||
set(() => ({
|
||||
visible: true,
|
||||
label: payload?.label ?? defaultGlobalProgressState.label,
|
||||
progress: Math.max(0, Math.min(100, payload?.progress ?? 0)),
|
||||
})),
|
||||
setLabel: (label) => set(() => ({ label })),
|
||||
setProgress: (progress) =>
|
||||
set(() => ({ progress: Math.max(0, Math.min(100, progress)) })),
|
||||
hide: () =>
|
||||
set(() => ({
|
||||
visible: false,
|
||||
progress: 0,
|
||||
label: defaultGlobalProgressState.label,
|
||||
})),
|
||||
}));
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
export { createAlertStore } from "./alert-store";
|
||||
export { createAttachmentStore } from "./attachment-store";
|
||||
export { createGlobalProgressStore } from "./global-progress-store";
|
||||
export { createMenuStore, type BbsType } from "./menu-store";
|
||||
export { createUserStore, type IUserInfo } from "./user-store";
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
"use client";
|
||||
|
||||
import { Progress } from "@common/components";
|
||||
import { useGlobalProgressStore } from "@/shared/lib";
|
||||
|
||||
export const GlobalProgressOverlay = () => {
|
||||
const visible = useGlobalProgressStore((state) => state.visible);
|
||||
const label = useGlobalProgressStore((state) => state.label);
|
||||
const progress = useGlobalProgressStore((state) => state.progress);
|
||||
|
||||
if (!visible) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[999] bg-black/35 [data-theme='black']:bg-black/55 backdrop-blur-[1px] rounded-lg p-10 flex justify-center items-center">
|
||||
<div className="w-[34rem] rounded-md border border-border bg-background p-6 shadow-md">
|
||||
<p className="mb-3 text-center text-[1.3rem] text-foreground">
|
||||
{label} {progress}%
|
||||
</p>
|
||||
<Progress value={progress} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user