issue #60
All checks were successful
Test CI / build (push) Successful in 16s

- 일정 참여자 화면 구현
This commit is contained in:
2025-12-09 22:01:18 +09:00
parent a30c2bbb32
commit 0c13854257
3 changed files with 81 additions and 30 deletions

View File

@@ -2,11 +2,9 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { ScrollArea } from "@/components/ui/scroll-area";
import { Textarea } from "@/components/ui/textarea";
import { cn } from "@/lib/utils";
import * as Mention from '@diceui/mention';
import { AtSign, PlusIcon, SearchIcon } from "lucide-react";
import { useRef, useState } from "react";
import { CircleSmall, PlusIcon, SearchIcon } from "lucide-react";
import { useEffect, useState } from "react";
const dummyUser = [
{
@@ -27,9 +25,34 @@ const dummyUser = [
}
]
export const ParticipantPopover = () => {
interface ParticipantPopoverProps {
participantList: string[];
setParticipantList: (list: string[]) => void;
}
export const ParticipantPopover = ({ participantList, setParticipantList }: ParticipantPopoverProps) => {
const [open, setOpen] = useState(false);
const [filterString, setFilterString] = useState('');
const [userList, setUserList] = useState(dummyUser);
const [tempList, setTempList] = useState(participantList);
const updateTempList = (accountId: string) => {
if (tempList.includes(accountId)) {
setTempList(tempList.filter((id) => id !== accountId));
} else {
setTempList([...tempList, accountId]);
}
}
const applyList = () => {
setParticipantList(tempList);
setOpen(false);
}
const cancelList = () => {
setOpen(false);
setTimeout(() => {
setTempList(participantList);
}, 150);
}
return (
<div className="w-full h-10 flex flex-row justify-start items-center">
@@ -55,6 +78,8 @@ export const ParticipantPopover = () => {
</Button>
</PopoverTrigger>
<PopoverContent
align="end"
side="right"
className="py-0 px-0 w-60 h-80 flex flex-col justify-start items-start"
>
<div
@@ -64,16 +89,53 @@ export const ParticipantPopover = () => {
<Input
placeholder="검색"
value={filterString}
onChange={(value) => setFilterString(value.target.value)}
className="shadow-none placeholder-indigo-300! focus-visible:placeholder-indigo-400! flex-1 focus-visible:ring-0 focus-visible:border-0 border-0"
/>
</div>
<ScrollArea
className="w-full h-60 flex flex-col"
>
{
userList.filter((user) => user.accountId.includes(filterString)).map((user, idx) => (
<div
className={cn(
"w-full h-10 flex flex-row items-center",
"hover:bg-indigo-50",
(idx !== dummyUser.length - 1)
? "border-b border-b-indigo-100"
: null
)}
onClick={() => updateTempList(user.accountId)}
>
<div
className="flex-11 flex flex-col"
>
<div className="pl-2 flex-1 text-sm align-middle">
{user.name}
</div>
<div className="pl-2 flex-1 text-[10px] text-gray-400 align-middle">
@{user.accountId}
</div>
</div>
<div
className="flex-1 flex items-center justify-center pr-2"
>
<div className={cn(
"w-5 h-5 rounded-full bg-gray-100 flex justify-center items-center",
!tempList.includes(user.accountId)
? "border-gray-200 border"
: "border-indigo-300 border-2"
)}>
{ tempList.includes(user.accountId) && <div className="w-2.5 h-2.5 rounded-full bg-indigo-300" />}
</div>
</div>
</div>
))
}
</ScrollArea>
<div
className="border-t border-t-indigo-300 w-full h-10 flex flex-row cursor-default"
className="border-t border-t-indigo-100 w-full h-10 flex flex-row cursor-default"
>
<div
className={cn(
@@ -81,6 +143,7 @@ export const ParticipantPopover = () => {
"bg-white text-indigo-300",
"hover:bg-indigo-300 hover:text-white"
)}
onClick={applyList}
>
</div>
@@ -90,6 +153,7 @@ export const ParticipantPopover = () => {
"bg-white text-red-400",
"hover:bg-red-400 hover:text-white"
)}
onClick={cancelList}
>
</div>

View File

@@ -1,26 +1,9 @@
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { PopoverContent } from '@/components/ui/popover';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import { useEffect, useState } from 'react';
import { usePalette } from '@/hooks/use-palette';
import { type ColorPaletteType } from '@/const/ColorPalette';
import { ColorPickPopover } from './ColorPickPopover';
import { Input } from '@/components/ui/input';
import { Controller, useForm } from 'react-hook-form';
import * as z from 'zod';
import { CreateScheduleSchema } from '@/data/form/createSchedule.schema';
import { zodResolver } from '@hookform/resolvers/zod';
import { Field, FieldError } from '@/components/ui/field';
import { PenSquare, X } from 'lucide-react';
import { ScheduleTypeLabel, type ScheduleType } from '@/const/schedule/ScheduleType';
import { useRecord } from '@/hooks/use-record';
import { TypePickPopover } from './TypePickPopover';
import { ScheduleDay } from '@/const/schedule/ScheduleDay';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { DatePickPopover } from './DatePickPopover';
import { format } from 'date-fns';
import { TimePickPopover } from './TimePickPopover';
import { useTime } from '@/hooks/use-time';
import { useState } from 'react';
import { PenSquare } from 'lucide-react';
import { ScheduleCreateContent } from './content/ScheduleCreateContent';
interface ScheduleSheetProps {

View File

@@ -64,7 +64,8 @@ export const ScheduleCreateContent = ({ date, open, setMode, popoverSide, popove
type,
status,
style,
dayList
dayList,
participantList
} = createScheduleForm.watch();
const selectColor = (color: ColorPaletteType) => {
@@ -239,7 +240,10 @@ export const ScheduleCreateContent = ({ date, open, setMode, popoverSide, popove
/>
)}
/>
<ParticipantPopover />
<ParticipantPopover
participantList={participantList}
setParticipantList={selectParticipant}
/>
</div>
)