refactor(control-center): Quick Controls 재디자인 및 플랜/잠금 결제 동선 정리

This commit is contained in:
2026-03-04 14:36:38 +09:00
parent 60cd093308
commit 3cddd3c1f4
21 changed files with 983 additions and 149 deletions

View File

@@ -7,6 +7,11 @@ import { cn } from '@/shared/lib/cn';
interface ToastPayload {
title: string;
description?: string;
durationMs?: number;
action?: {
label: string;
onClick: () => void;
};
}
interface ToastItem extends ToastPayload {
@@ -22,15 +27,20 @@ const ToastContext = createContext<ToastContextValue | null>(null);
export const ToastProvider = ({ children }: { children: ReactNode }) => {
const [toasts, setToasts] = useState<ToastItem[]>([]);
const removeToast = useCallback((id: number) => {
setToasts((current) => current.filter((toast) => toast.id !== id));
}, []);
const pushToast = useCallback((payload: ToastPayload) => {
const id = Date.now() + Math.floor(Math.random() * 10000);
const durationMs = payload.durationMs ?? 2400;
setToasts((current) => [...current, { id, ...payload }]);
window.setTimeout(() => {
setToasts((current) => current.filter((toast) => toast.id !== id));
}, 2400);
}, []);
removeToast(id);
}, durationMs);
}, [removeToast]);
const value = useMemo(() => ({ pushToast }), [pushToast]);
@@ -42,7 +52,7 @@ export const ToastProvider = ({ children }: { children: ReactNode }) => {
<div
key={toast.id}
className={cn(
'rounded-xl border border-white/15 bg-slate-950/92 px-4 py-3 text-sm text-white shadow-lg shadow-slate-950/60',
'pointer-events-auto rounded-xl border border-white/15 bg-slate-950/92 px-4 py-3 text-sm text-white shadow-lg shadow-slate-950/60',
'animate-[toast-in_180ms_ease-out] motion-reduce:animate-none',
)}
>
@@ -50,6 +60,20 @@ export const ToastProvider = ({ children }: { children: ReactNode }) => {
{toast.description ? (
<p className="mt-1 text-xs text-white/70">{toast.description}</p>
) : null}
{toast.action ? (
<div className="mt-2 flex justify-end">
<button
type="button"
onClick={() => {
toast.action?.onClick();
removeToast(toast.id);
}}
className="rounded-full border border-white/25 bg-white/[0.08] px-2.5 py-1 text-[11px] font-medium text-white/88 transition-colors hover:bg-white/[0.16]"
>
{toast.action.label}
</button>
</div>
) : null}
</div>
))}
</div>