80 lines
2.8 KiB
TypeScript
80 lines
2.8 KiB
TypeScript
"use client";
|
||
|
||
import React, { createContext, useContext, useEffect, useRef, useState } from "react";
|
||
import { SendMessageForm } from "@/app/components/SendMessageForm";
|
||
|
||
type MessageTarget = { receiverId: string; receiverNickname?: string | null } | null;
|
||
type Ctx = { openMessageModal: (target: { receiverId: string; receiverNickname?: string | null }) => void };
|
||
|
||
const MessageModalCtx = createContext<Ctx>({ openMessageModal: () => {} });
|
||
|
||
export function useMessageModal() {
|
||
return useContext(MessageModalCtx);
|
||
}
|
||
|
||
export function MessageModalProvider({ children }: { children: React.ReactNode }) {
|
||
const [target, setTarget] = useState<MessageTarget>(null);
|
||
const dialogRef = useRef<HTMLDivElement>(null);
|
||
|
||
const openMessageModal = (t: { receiverId: string; receiverNickname?: string | null }) => {
|
||
setTarget({ receiverId: t.receiverId, receiverNickname: t.receiverNickname ?? null });
|
||
};
|
||
|
||
const close = () => setTarget(null);
|
||
|
||
useEffect(() => {
|
||
function onKey(e: KeyboardEvent) {
|
||
if (e.key === "Escape") close();
|
||
}
|
||
document.addEventListener("keydown", onKey);
|
||
return () => document.removeEventListener("keydown", onKey);
|
||
}, []);
|
||
|
||
return (
|
||
<MessageModalCtx.Provider value={{ openMessageModal }}>
|
||
{children}
|
||
{target && (
|
||
<div
|
||
className="fixed inset-0 z-[1000] flex items-center justify-center"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
>
|
||
<div
|
||
className="absolute inset-0 bg-black/40"
|
||
onClick={close}
|
||
aria-hidden
|
||
/>
|
||
<div
|
||
ref={dialogRef}
|
||
className="relative z-[1001] w-[92%] max-w-[520px] rounded-lg bg-white shadow-xl border border-neutral-200"
|
||
>
|
||
<div className="px-5 py-3 border-b border-neutral-200 flex items-center justify-between">
|
||
<h3 className="text-base font-semibold text-neutral-900">쪽지 보내기</h3>
|
||
<button
|
||
onClick={close}
|
||
className="h-8 w-8 inline-flex items-center justify-center rounded-md hover:bg-neutral-100 cursor-pointer"
|
||
aria-label="닫기"
|
||
>
|
||
×
|
||
</button>
|
||
</div>
|
||
<div className="p-5">
|
||
<SendMessageForm receiverId={target.receiverId} receiverNickname={target.receiverNickname} onSent={close} />
|
||
</div>
|
||
<div className="px-5 pb-4 flex items-center justify-end">
|
||
<button
|
||
onClick={close}
|
||
className="h-9 px-4 rounded-md border border-neutral-300 bg-white text-sm hover:bg-neutral-100 cursor-pointer"
|
||
>
|
||
닫기
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
</MessageModalCtx.Provider>
|
||
);
|
||
}
|
||
|
||
|