-
Notifications
You must be signed in to change notification settings - Fork 1
Feat: card edit modal #68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e441cd0
35c7804
1ca3a1a
55af71e
875a08a
5eb52bc
8b82ef2
eb3fcb3
fe47f5a
746175a
62bd47d
446b9e9
98caeb1
883ae6e
617d7fd
1cff62d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,169 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { Icon } from '@pinback/design-system/icons'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| AutoDismissToast, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Button, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| DateTime, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Dropdown, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| InfoBox, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| PopupContainer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Switch, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Textarea, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Toast, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateDate, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| validateTime, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from '@pinback/design-system/ui'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { cn } from '@pinback/design-system/utils'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { useState } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ์ ํจ์ฑ ํจ์ import ๊ฒฝ๋ก ์ค๋ฅ ๊ฐ๋ฅ์ฑ
import {
AutoDismissToast,
Button,
DateTime,
Dropdown,
InfoBox,
PopupContainer,
Switch,
Textarea,
Toast,
- validateDate,
- validateTime,
} from '@pinback/design-system/ui';
import { cn } from '@pinback/design-system/utils';
import { useState } from 'react';
+import { validateDate, validateTime } from '../../utils/ValidateData';๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface CardEditModalProps { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose: () => void; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export default function CardEditModal({ onClose }: CardEditModalProps) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isRemindOn, setIsRemindOn] = useState(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [selected, setSelected] = useState<string | null>(null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isPopupOpen, setIsPopupOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // ์ ๋ ฅ ํ๋ ์ํ: ์๋ฒ์์ ๋ฐ์์ฌ ๋ฐ์ดํฐ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [title] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [source] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [memo, setMemo] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [categories] = useState<string[]>([]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [categoryTitle, setCategoryTitle] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [date, setDate] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [time, setTime] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [dateError, setDateError] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [timeError, setTimeError] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [toastIsOpen, setToastIsOpen] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [isPopError, setIsPopError] = useState(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const [errorTxt, setErrorTxt] = useState(''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const saveCategory = () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (categoryTitle.length > 20) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsPopError(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setErrorTxt('20์ ์ด๋ด๋ก ์์ฑํด์ฃผ์ธ์'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsPopupOpen(false); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleDateChange = (value: string) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setDate(value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setDateError(validateDate(value)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleTimeChange = (value: string) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setTime(value); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setTimeError(validateTime(value)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+56
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. time ์ ๋ ฅ์ ๋ํด ๋ถ๋ชจ onChange๊ฐ ํธ์ถ๋์ง ์์ ๊ฒ์ฆ/์ํ๊ฐ ๋์ํ์ง ์์ต๋๋ค Design System์
ํด๊ฒฐ ๋ฐฉ์(๊ถ์ฅ): DS์ // packages/design-system/src/components/dateTime/DateTime.tsx (์์ง)
- const next = (timeDigits + add).slice(0, 4);
+ const next = (timeDigits + add).slice(0, 4);
setTimeDigits(next);
setInput(formatTime12(next));
+ props.onChange?.(digitsToHHMM(next)); // NEW: ๋ถ๋ชจ๋ก 24h "HH:MM" ์ ๋ฌ
nextCaretRef.current = mapCaretByDigitsPos(next.length, 'time');
e.preventDefault();
... (delete/paste ์ฒ๋ฆฌ ์ง์ ์๋ ๋์ผํ๊ฒ ํธ์ถ ์ถ๊ฐ)
+function digitsToHHMM(digits: string) {
+ const h = digits.slice(0, 2).padStart(2, '0');
+ const m = digits.slice(2, 4).padStart(2, '0');
+ return `${h}:${m}`;
+}DS ๋ฐ์ ์ ์์ ๋์์ ์ํ์๋ฉด ๋ง์ ์ฃผ์ธ์. UI์์ time ๊ฒ์ฆ/ํ์๋ฅผ ๋นํ์ฑํํ๋ ๊ฐ๋ ์ ์ฉ์๋ ๋๋ฆด ์ ์์ต๋๋ค. Also applies to: 142-147 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const handleSwitchChange = (checked: boolean) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setIsRemindOn(checked); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex flex-col"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| role="dialog" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| aria-modal="true" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className={cn( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'w-[31.2rem] rounded-[1.2rem] bg-white px-[3.2rem] py-[2.4rem] shadow-xl', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 'flex flex-col gap-[1.6rem]' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {isPopupOpen && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <PopupContainer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isOpen={isPopupOpen} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={() => setIsPopupOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="input" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title="์นดํ ๊ณ ๋ฆฌ ์ถ๊ฐํ๊ธฐ" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| left="์ทจ์" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| right="ํ์ธ" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inputValue={categoryTitle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isError={isPopError} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| errortext={errorTxt} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onInputChange={setCategoryTitle} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| placeholder="์นดํ ๊ณ ๋ฆฌ ์ ๋ชฉ์ ์ ๋ ฅํด์ฃผ์ธ์" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onLeftClick={() => setIsPopupOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onRightClick={saveCategory} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <header className="flex items-center justify-between"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Icon name="logo" width={72} height={20} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="button" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| aria-label="๋ซ๊ธฐ" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick={onClose} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className="rounded-[0.6rem] p-[0.4rem] hover:bg-gray-100" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Icon name="ic_close" size={20} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </header> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <InfoBox title={title} source={source} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <section className="flex flex-col gap-[0.8rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="caption1-sb text-font-black-1">์นดํ ๊ณ ๋ฆฌ</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Dropdown | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| options={categories} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| selectedValue={selected} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onChange={(value) => setSelected(value)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| placeholder="์ ํํด์ฃผ์ธ์" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onAddItem={() => setIsPopupOpen(true)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addItemLabel="์ถ๊ฐํ๊ธฐ" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <section className="flex flex-col gap-[0.8rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="caption1-sb text-font-black-1">๋ฉ๋ชจ</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Textarea | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| placeholder="๋์ค์ ๋ด๊ฐ ๊บผ๋ด์ค ์ ์๊ฒ ์ด์ง ์ ์ด์ค!" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| maxLength={500} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| className="h-[12rem]" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value={memo} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onChange={(e) => setMemo(e.target.value)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <section className="flex flex-col gap-[1.2rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex items-center justify-between"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <p className="caption1-sb text-font-black-1">๋ฆฌ๋ง์ธ๋</p> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Switch checked={isRemindOn} onCheckedChange={handleSwitchChange} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="flex justify-between gap-[0.8rem]"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <DateTime | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="date" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state={dateError ? 'error' : isRemindOn ? 'default' : 'disabled'} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value={date} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onChange={handleDateChange} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <DateTime | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type="time" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| state={timeError ? 'error' : isRemindOn ? 'default' : 'disabled'} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| value={time} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onChange={handleTimeChange} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {dateError && <p className="body3-r text-error">{dateError}</p>} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {timeError && <p className="body3-r text-error">{timeError}</p>} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {/* TODO: onClick ์ถํ ์ ์ฅ api ์ฐ๊ฒฐํ ์คํจ/์ฑ๊ณต ์ฐ๊ฒฐ */} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Button onClick={() => setToastIsOpen(true)}>์ ์ฅํ๊ธฐ</Button> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| {toastIsOpen && ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <div className="absolute bottom-[2.4rem] left-1/2 -translate-x-1/2"> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <AutoDismissToast | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| duration={1000} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fadeMs={1000} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClose={() => setToastIsOpen(false)} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| <Toast text={`์ ์ฅ์ ์คํจํ์ด์.\n๋ค์ ์๋ํด์ฃผ์ธ์`} /> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </AutoDismissToast> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| )} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| export const validateDate = (value: string): string => { | ||
| const regex = /^(\d{4})\.(\d{2})\.(\d{2})$/; | ||
| const match = value.match(regex); | ||
|
|
||
| if (!match) return '์ ํจํ ๋ ์ง๋ฅผ ์์ฑํ์ธ์'; | ||
|
|
||
| const year = parseInt(match[1], 10); | ||
| const month = parseInt(match[2], 10); | ||
| const day = parseInt(match[3], 10); | ||
|
|
||
| if (month < 1 || month > 12) return '์ ํจํ ๋ ์ง๋ฅผ ์์ฑํ์ธ์'; | ||
|
|
||
| const testDate = new Date(year, month - 1, day); | ||
| if ( | ||
| testDate.getFullYear() !== year || | ||
| testDate.getMonth() !== month - 1 || | ||
| testDate.getDate() !== day | ||
| ) { | ||
| return '์ ํจํ ๋ ์ง๋ฅผ ์์ฑํ์ธ์'; | ||
| } | ||
|
|
||
| const today = new Date(); | ||
| today.setHours(0, 0, 0, 0); | ||
| if (testDate < today) return 'ํ์ฌ ์์ ์ดํ ๋ ์ง๋ก ์์ฑํ์ธ์'; | ||
|
|
||
| return ''; | ||
| }; | ||
|
|
||
| // ์๊ฐ ์ ํจ์ฑ ๊ฒ์ฌ | ||
| export const validateTime = (value: string | undefined): string => { | ||
| if (!value) return '์๊ฐ์ ์ ๋ ฅํ์ธ์'; | ||
|
|
||
| const clean = value.replace(/[^0-9:]/g, ''); | ||
| const regex = /^(\d{1,2}):(\d{1,2})$/; | ||
| const match = clean.match(regex); | ||
|
|
||
| if (!match) return '์ ํจํ ์๊ฐ์ ์์ฑํ์ธ์'; | ||
| const hour = parseInt(match[1], 10); | ||
| const minute = parseInt(match[2], 10); | ||
|
|
||
| if (hour < 0 || hour > 23 || minute < 0 || minute > 59) { | ||
| return '์ ํจํ ์๊ฐ์ ์์ฑํ์ธ์'; | ||
| } | ||
|
|
||
| return ''; | ||
| }; |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -5,7 +5,7 @@ interface InfoBoxProps { | |||||
| } | ||||||
| const InfoBox = ({ title, source, imgUrl }: InfoBoxProps) => { | ||||||
| return ( | ||||||
| <div className="border-main400 flex h-[6.8rem] w-[24.8rem] items-center justify-between gap-[0.8rem] rounded-[4px] border bg-white px-[0.8rem] py-[1.2rem]"> | ||||||
| <div className="border-main400 flex h-[6.8rem] w-[full] items-center justify-between gap-[0.8rem] rounded-[4px] border bg-white px-[0.8rem] py-[1.2rem]"> | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tailwind ํด๋์ค ์คํ:
- <div className="border-main400 flex h-[6.8rem] w-[full] items-center justify-between gap-[0.8rem] rounded-[4px] border bg-white px-[0.8rem] py-[1.2rem]">
+ <div className="border-main400 flex h-[6.8rem] w-full items-center justify-between gap-[0.8rem] rounded-[4px] border bg-white px-[0.8rem] py-[1.2rem]">๐ Committable suggestion
Suggested change
๐ค Prompt for AI Agents |
||||||
| <img className="h-[4.4rem] w-[4.4rem] rounded-[0.4rem]" src={imgUrl} /> | ||||||
| <div className="items-left flex flex-col justify-center gap-[0.2rem] text-left"> | ||||||
| <p className="sub3-sb w-[18rem] truncate">{title}</p> | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
์๊ฒ UI์์ชฝ์ผ๋ก ๋ค์ด๊ฐ์๋์??