feat: 컨펌 & 얼럿 다이얼로그 스토어 생성

This commit is contained in:
2025-03-19 15:54:20 +09:00
parent 25a2ac5716
commit 6f0e1a6e40
7 changed files with 120 additions and 3 deletions
+5 -1
View File
@@ -3,13 +3,17 @@
import { ConfirmProvider } from "@frontend-opensource/use-react-hooks";
import { AuthWrapper } from "@/entities/auth";
import { QueryProvider, StoreProvider } from "@/shared/providers";
import { AlertDialog } from "@/shared/ui/alert-dialog";
const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
return (
<StoreProvider>
<QueryProvider>
<ConfirmProvider>
<AuthWrapper>{children}</AuthWrapper>
<AuthWrapper>
{children}
<AlertDialog />
</AuthWrapper>
</ConfirmProvider>
</QueryProvider>
</StoreProvider>
+14
View File
@@ -0,0 +1,14 @@
import { useStore } from "zustand";
import { useContext } from "react";
import type { AlertStore } from "../store/alert-store";
import { StoreContext } from "../providers/store-provider";
export const useAlertStore = <T>(selector: (store: AlertStore) => T): T => {
const storeContext = useContext(StoreContext);
if (!storeContext) {
throw new Error("useAlertStore must be used within StoreProvider");
}
return useStore(storeContext.alertStore, selector);
};
+1 -1
View File
@@ -1,6 +1,6 @@
import { useStore } from "zustand";
import { useContext } from "react";
import { type UserStore } from "@/shared/store/user-store";
import type { UserStore } from "../store/user-store";
import { StoreContext } from "../providers/store-provider";
export const useUserStore = <T>(selector: (store: UserStore) => T): T => {
@@ -1,9 +1,11 @@
"use client";
import { createContext, useRef } from "react";
import { createUserStore } from "@/shared/store/user-store";
import { createAlertStore } from "../store/alert-store";
import { createUserStore } from "../store/user-store";
type StoreContextType = {
alertStore: ReturnType<typeof createAlertStore>;
userStore: ReturnType<typeof createUserStore>;
};
@@ -15,6 +17,7 @@ export const StoreProvider = ({ children }: { children: React.ReactNode }) => {
const storeRef = useRef<StoreContextType | null>(null);
if (storeRef.current === null) {
storeRef.current = {
alertStore: createAlertStore(),
userStore: createUserStore(),
};
}
+22
View File
@@ -0,0 +1,22 @@
import { createStore } from "zustand/vanilla";
export type AlertState = {
alertMessage: string;
};
export type AlertActions = {
setAlertMessage: (message: string) => void;
};
export type AlertStore = AlertState & AlertActions;
export const defaultInitState: AlertState = {
alertMessage: "",
};
export const createAlertStore = (initState: AlertState = defaultInitState) => {
return createStore<AlertStore>()((set) => ({
...initState,
setAlertMessage: (alertMessage: string) => set(() => ({ alertMessage })),
}));
};
+28
View File
@@ -0,0 +1,28 @@
import {
Dialog,
DialogContent,
DialogFooter,
DialogClose,
Button,
} from "@common/components/ui";
import { useAlertStore } from "../lib/use-alert-store";
function AlertDialog() {
const { alertMessage, setAlertMessage } = useAlertStore((state) => state);
return (
<Dialog open={!!alertMessage} onOpenChange={() => setAlertMessage("")}>
<DialogContent aria-describedby={undefined}>
<div className="py-10">
<p className="text-center text-[1.4rem]">{alertMessage}</p>
</div>
<DialogFooter className="!justify-center">
<DialogClose asChild>
<Button>확인</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
export { AlertDialog };
+46
View File
@@ -0,0 +1,46 @@
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import {
Dialog,
DialogContent,
DialogFooter,
DialogClose,
Button,
type ButtonProps,
} from "@common/components/ui";
type ConfirmDialogProps = {
open: boolean;
confirmButtonProps?: ButtonProps & { label?: string };
cancelButtonProps?: ButtonProps & { label?: string };
};
function ConfirmDialog({
open,
confirmButtonProps,
cancelButtonProps,
}: ConfirmDialogProps) {
const { message, onConfirm, onCancel } = useConfirm();
return (
<Dialog open={open} onOpenChange={onCancel}>
<DialogContent aria-describedby={undefined}>
<div className="py-10">
<p className="text-center text-[1.4rem]">{message}</p>
</div>
<DialogFooter className="!justify-center">
<DialogClose asChild>
<Button onClick={onConfirm} {...confirmButtonProps}>
{confirmButtonProps?.label ?? "확인"}
</Button>
</DialogClose>
<DialogClose asChild>
<Button onClick={onCancel} color="white" {...cancelButtonProps}>
{cancelButtonProps?.label ?? "취소"}
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}
export { ConfirmDialog };