diff --git a/.env.development b/.env.development index c1da8f0..60ff508 100644 --- a/.env.development +++ b/.env.development @@ -1 +1 @@ -VITE_API_URL=http://localhost:8088 +VITE_API_URL=/dev-api diff --git a/certs/localhost+2-key.pem b/certs/localhost+2-key.pem new file mode 100644 index 0000000..44df0dd --- /dev/null +++ b/certs/localhost+2-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1GqPn9O+FRM+a +hQvEAjgjI7HXdRdeRJsX3K2BqNGYBR8Lat4fMskY4Es7WYNCDl9d/fFQd+K/gpjj +sRnX0Bf3CYjVNlhTqdwoOFBPGUQ4i8fuSRM4rDvAq4enb+7RVWjE53MGgqQ0RdRQ +Hyx95pEWTz0FzpNlzOzEGEdv8zBwbwgZBU73F4aCDNY0FLaaKepr1/NqdUA8xZYo +sAbJvIkWJ/QS2F2/WwQZYQ3TLWtg4/2uDpGWbpQUwRnWZ7ma+Gcz/hJwQhoml4q4 +bHXrIAsCz/NFNYs7K5wCmIdTjLw2PcETJSEQMbGSk7CMIuiUd0ShVDfpBROIAlmF +XAheZ/lNAgMBAAECggEAT1H7t/xva89XnjXnkVHnhHx9yABg28jwpOLim4d1RT/4 ++Oc1ojR8H4kdakEqXCQvYNt4deYMShTJIfDPgNaDqI9kfv3ucbZT1snTYtGOL7YJ +OzSGVqwY/6ohIBTGZKkj2hoFJzTQ9pQfCXid5Aa4RS0vbPutU0kN6lU39LBu5s79 +8MGGu70Qcd63BRpyOxKbbWCbZ0S/7JRShng0GA8ILBvMCZdzZ7RZktpa+bA7Q6i7 +PM5zxxmxygmFQXOAizTB2KoeLEu/qb44kypK6aw9nMKEZebqzuF5bOFMlCR67Cfx +QblFW0JQckef7DCc4ThPEnAXwEPSlsv2P//dbX1TgQKBgQDctIA/GZmzSXVtsUws +aPPeAvKMWGFSGsq/9rcy2G7KBTHBQW5/763T6N7HKVpZwRaabiSxgrZekd6d9oTP +XWpmnFQZgtLRtXLPXilCK8Udoi6HejGuXWvviFdfPUqhPh3tw6uCaFO7qT4pUiwO +hTq4W5Cm+xy/q12m7cEDfoPeMwKBgQDSEOdQY5f5C6YrZvG2zrTZUvS8VW4NFhkY +vSZBGqiACYGKq/7erMoAdtLrcYBnEMiLufn+tSInflw2I+ALEo4r2lcBAQncXuWj +gnpM+DpTwRfZmGYs3jXA5eVRRzG0FBFLFyiBE62f0tvJjALB7V7vfpCswJGvPIyb +p2P16jZKfwKBgQCn4VkoJlYGzZrYTKPvqAnQV5ed7+BfbufIq2dg8scbPmZBZX8j +K/KinaFQB4Glgj2qTJv2tsH4H6chqxINFjbIRKOoIB4yzH2/hRWHMvomd2ZDQUyn +IILo2mHznRC2pCRp5owAj1EaDzusfMfsZ6Vp9KSMj7inhzeesX0/Ji4yhwKBgHgh +sJc5jYSgU9RIV/0qcyRBm7JEzN3xAEM0kLb0rt4iEZIjUGs5t3/SdEavLzZB096M +adpu7exWCBfyJkNOxj1v7Qem92OuZXc/u/9eicSyDZij3fLU1TrOfnkf1N3eCBHA +WaqPfWCELqsxRbZvsDYYVFZm/imP3/14GeNdoNSzAoGALFD3YdZ5bIETcD8hwXd7 +P9HXPQZag919fFe0dhPDauC5dgvgfLF2d88q0MPCqMK6ngTMVzrMh4X/u0XH1N3v +LiQEBp4P0EX1z5DEj8eLajV0JgOyt1zzymZ3Jk7DDyfcYl+bVetB2R9Gd3MuV98t +Sz72wO/jh1/w+SN07F9VS0w= +-----END PRIVATE KEY----- diff --git a/certs/localhost+2.pem b/certs/localhost+2.pem new file mode 100644 index 0000000..92a211e --- /dev/null +++ b/certs/localhost+2.pem @@ -0,0 +1,26 @@ +-----BEGIN CERTIFICATE----- +MIIETjCCAragAwIBAgIQJ0x1ttig1msjzZOJWJwnITANBgkqhkiG9w0BAQsFADB7 +MR4wHAYDVQQKExVta2NlcnQgZGV2ZWxvcG1lbnQgQ0ExKDAmBgNVBAsMH+uwse2W +peuLqFxiYWVreWFuZ2RhbkDrsLHtlqXri6gxLzAtBgNVBAMMJm1rY2VydCDrsLHt +lqXri6hcYmFla3lhbmdkYW5A67Cx7Zal64uoMB4XDTI1MTIwNzEwMDIyNVoXDTI4 +MDMwNzEwMDIyNVowUzEnMCUGA1UEChMebWtjZXJ0IGRldmVsb3BtZW50IGNlcnRp +ZmljYXRlMSgwJgYDVQQLDB/rsLHtlqXri6hcYmFla3lhbmdkYW5A67Cx7Zal64uo +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtRqj5/TvhUTPmoULxAI4 +IyOx13UXXkSbF9ytgajRmAUfC2reHzLJGOBLO1mDQg5fXf3xUHfiv4KY47EZ19AX +9wmI1TZYU6ncKDhQTxlEOIvH7kkTOKw7wKuHp2/u0VVoxOdzBoKkNEXUUB8sfeaR +Fk89Bc6TZczsxBhHb/MwcG8IGQVO9xeGggzWNBS2minqa9fzanVAPMWWKLAGybyJ +Fif0Ethdv1sEGWEN0y1rYOP9rg6Rlm6UFMEZ1me5mvhnM/4ScEIaJpeKuGx16yAL +As/zRTWLOyucApiHU4y8Nj3BEyUhEDGxkpOwjCLolHdEoVQ36QUTiAJZhVwIXmf5 +TQIDAQABo3YwdDAOBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEw +HwYDVR0jBBgwFoAU9/lqZ9lo2f1oLg+JnBYubfpE4OEwLAYDVR0RBCUwI4IJbG9j +YWxob3N0hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABMA0GCSqGSIb3DQEBCwUAA4IB +gQBNsZYSSGE6m3ve8bPGISSdlSU/pi1GVqOC4xxVD8JUeGNZeYAv8AJQ6w/496wK +KTFL6PDOavHW37mWBEgz+fZe2AjOZK/hz/eOcKHTFhVRZo1snt5VuLk4PtAGmgn8 +xyyQUz/2wwlTqb0AgLrt1hLTnbSIWvBnFl3VdCnH0E2xsIPZUMFzcjVHTERJWvAS +IanurnpeO/W3uNduu7UmGk03GDzTG8dXwVsSSE/HoXxscXSIP9qMvKOPeQvucd+X +XkaYUkbjDhwoKqDB0rDmvbPkFcsAGuq8qpbPPavhoXgtdqO30lZfbTPWPq1qz99S +nW9ihMfmwarw5s/LCXiQO70nMbcZMZ6UAqEhX4UUfGD0j5jHe3fPOyT4v0lLfmxp +P4eoSiWoIfp/f9ZBn9zca5km9iGNT+n1Jrt6fOTIycPVu2gE7S4qXcHhVHWondle +bMFLGbjZ75Qwc9HdnoY7Do8Vj+CPvSfhAAPehPf8D1GVlazmiuHql4fny1qbGw// +YEQ= +-----END CERTIFICATE----- diff --git a/src/App.tsx b/src/App.tsx index c8e841e..5d79990 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -10,16 +10,20 @@ import { HomePage } from './ui/page/home/HomePage'; import type { AuthData } from './data/AuthData'; import { useEffect } from 'react'; import { ScheduleMainPage } from './ui/page/schedule/ScheduleMainPage'; +import { BaseNetwork } from './network/BaseNetwork'; function App() { const { authData, login } = useAuthStore(); + const baseNetwork = new BaseNetwork(); useEffect(() => { const autoLogin = localStorage.getItem('autoLogin') === 'true'; if (autoLogin) { - const stored = localStorage.getItem('auth-storage'); - if (stored) { - const storedAuthData = JSON.parse(stored).state as AuthData; - login(storedAuthData); + try { + (async () => { + await baseNetwork.refreshToken(); + })(); + } catch (err) { + localStorage.setItem('autoLogin', 'false'); } } }, []); @@ -35,6 +39,7 @@ function App() { } path={PageRouting["SIGN_UP"].path} /> } path={PageRouting["RESET_PASSWORD"].path} /> } path="*" /> + } path={"/"} /> {/* 자동로그인용 대기 화면 */} > : <> } path="*" /> diff --git a/src/const/schedule/ScheduleStatus.ts b/src/const/schedule/ScheduleStatus.ts new file mode 100644 index 0000000..e48ec75 --- /dev/null +++ b/src/const/schedule/ScheduleStatus.ts @@ -0,0 +1 @@ +export type ScheduleStatus = 'yet' | 'completed'; \ No newline at end of file diff --git a/src/const/schedule/ScheduleType.ts b/src/const/schedule/ScheduleType.ts new file mode 100644 index 0000000..5874a39 --- /dev/null +++ b/src/const/schedule/ScheduleType.ts @@ -0,0 +1 @@ +export type ScheduleType = 'once' | 'daily' | 'weekly' | 'aweekly' | 'monthly' | 'annual'; diff --git a/src/data/AuthData.ts b/src/data/AuthData.ts index 6b3e939..a3028a3 100644 --- a/src/data/AuthData.ts +++ b/src/data/AuthData.ts @@ -1,4 +1,3 @@ export type AuthData = { accessToken: string; - refreshToken: string; } \ No newline at end of file diff --git a/src/data/form/createSchedule.schema.ts b/src/data/form/createSchedule.schema.ts new file mode 100644 index 0000000..3df7dfa --- /dev/null +++ b/src/data/form/createSchedule.schema.ts @@ -0,0 +1,22 @@ +import * as z from 'zod'; + +export const CreateScheduleSchema = z.object({ + name: z + .string() + , startDate: z + .date() + , endDate: z + .date() + , status: z + .string() + , content: z + .string() + , type: z + .string() + , style: z + .string() + , startTime: z + .string() + , endTime: z + .string() +}); \ No newline at end of file diff --git a/src/data/form/updateSchedule.schema.ts b/src/data/form/updateSchedule.schema.ts new file mode 100644 index 0000000..eff9853 --- /dev/null +++ b/src/data/form/updateSchedule.schema.ts @@ -0,0 +1,24 @@ +import * as z from 'zod'; + +export const UpdateScheduleSchema = z.object({ + id: z + .string() + , name: z + .string() + , startDate: z + .date() + , endDate: z + .date() + , status: z + .string() + .default("yet") + , type: z + .string() + .default("once") + , style: z + .string() + , startTime: z + .string() + , endTime: z + .string() +}); \ No newline at end of file diff --git a/src/data/request/index.ts b/src/data/request/index.ts index 9482f4a..efab6e9 100644 --- a/src/data/request/index.ts +++ b/src/data/request/index.ts @@ -5,4 +5,9 @@ export * from './account/SignupRequest'; export * from './account/LoginRequest'; export * from './account/SendResetPasswordCodeRequest'; export * from './account/VerifyResetPasswordCodeRequest'; -export * from './account/ResetPasswordRequest'; \ No newline at end of file +export * from './account/ResetPasswordRequest'; + +export * from './schedule/CreateScheduleRequest'; +export * from './schedule/DeleteScheduleRequest'; +export * from './schedule/ScheduleListRequest'; +export * from './schedule/UpdateScheduleRequest'; \ No newline at end of file diff --git a/src/data/request/schedule/CreateScheduleRequest.ts b/src/data/request/schedule/CreateScheduleRequest.ts new file mode 100644 index 0000000..e781cf9 --- /dev/null +++ b/src/data/request/schedule/CreateScheduleRequest.ts @@ -0,0 +1,39 @@ +import type { ScheduleStatus } from "@/const/schedule/ScheduleStatus"; +import type { ScheduleType } from "@/const/schedule/ScheduleType"; + +export class CreateScheduleRequest { + name: string; + content: string; + startDate: Date; + endDate: Date; + status: ScheduleStatus; + type: ScheduleType; + startTime: string; + endTime: string; + style: string; + participantList: string[]; + + constructor ( + name: string, + content: string, + startDate: Date, + endDate: Date, + status: ScheduleStatus, + type: ScheduleType, + startTime: string, + endTime: string, + style: string, + participantList: string[] + ) { + this.name = name; + this.content = content; + this.startDate = startDate; + this.endDate = endDate; + this.status = status; + this.type = type; + this.startTime = startTime; + this.endTime = endTime; + this.style = style; + this.participantList = participantList; + } +} \ No newline at end of file diff --git a/src/data/request/schedule/DeleteScheduleRequest.ts b/src/data/request/schedule/DeleteScheduleRequest.ts new file mode 100644 index 0000000..b2cf217 --- /dev/null +++ b/src/data/request/schedule/DeleteScheduleRequest.ts @@ -0,0 +1,7 @@ +export class DeleteScheduleRequest { + id: string; + + constructor(id: string) { + this.id = id; + } +} \ No newline at end of file diff --git a/src/data/request/schedule/ScheduleListRequest.ts b/src/data/request/schedule/ScheduleListRequest.ts new file mode 100644 index 0000000..3e2e742 --- /dev/null +++ b/src/data/request/schedule/ScheduleListRequest.ts @@ -0,0 +1,13 @@ +import type { ScheduleStatus } from "@/const/schedule/ScheduleStatus"; +import type { ScheduleType } from "@/const/schedule/ScheduleType"; + +export class ScheduleListRequest { + filterAccountIdList?: string[]; + filterStartDate?: Date; + filterEndDate?: Date; + filterDate?: Date; + filterTypeList?: ScheduleType[]; + filterStyleList?: string[]; + filterStatusList?: ScheduleStatus[]; + filterName?: string; +} \ No newline at end of file diff --git a/src/data/request/schedule/UpdateScheduleRequest.ts b/src/data/request/schedule/UpdateScheduleRequest.ts new file mode 100644 index 0000000..e79a977 --- /dev/null +++ b/src/data/request/schedule/UpdateScheduleRequest.ts @@ -0,0 +1,42 @@ +import type { ScheduleStatus } from "@/const/schedule/ScheduleStatus"; +import type { ScheduleType } from "@/const/schedule/ScheduleType"; + +export class UpdateScheduleRequest { + id: string; + name: string; + content: string; + startDate: Date; + endDate: Date; + status: 'yet' | 'completed'; + type: 'once' | 'daily' | 'weekly' | 'aweekly' | 'monthly' | 'annual'; + startTime: string; + endTime: string; + style: string; + participantList: string[]; + + constructor ( + id: string, + name: string, + content: string, + startDate: Date, + endDate: Date, + status: ScheduleStatus, + type: ScheduleType, + startTime: string, + endTime: string, + style: string, + participantList: string[] + ) { + this.id = id; + this.name = name; + this.content = content; + this.startDate = startDate; + this.endDate = endDate; + this.status = status; + this.type = type; + this.startTime = startTime; + this.endTime = endTime; + this.style = style; + this.participantList = participantList; + } +} \ No newline at end of file diff --git a/src/data/response/account/LoginResponse.ts b/src/data/response/account/LoginResponse.ts index d2c9e62..0ddf520 100644 --- a/src/data/response/account/LoginResponse.ts +++ b/src/data/response/account/LoginResponse.ts @@ -2,5 +2,4 @@ import { BaseResponse } from "../BaseResponse"; export class LoginResponse extends BaseResponse { accessToken?: string; - refreshToken?: string; } \ No newline at end of file diff --git a/src/data/response/account/RefreshAccessTokenResponse.ts b/src/data/response/account/RefreshAccessTokenResponse.ts index f3f2643..fbdb8c4 100644 --- a/src/data/response/account/RefreshAccessTokenResponse.ts +++ b/src/data/response/account/RefreshAccessTokenResponse.ts @@ -2,5 +2,5 @@ import { BaseResponse } from "../BaseResponse"; export class RefreshAccessTokenResponse extends BaseResponse { accessToken!: string; - refreshToken!: string; + refreshToken?: string; } \ No newline at end of file diff --git a/src/data/response/index.ts b/src/data/response/index.ts index 492e48e..880e3e0 100644 --- a/src/data/response/index.ts +++ b/src/data/response/index.ts @@ -5,4 +5,7 @@ export * from './account/SignupResponse'; export * from './account/LoginResponse'; export * from './account/SendResetPasswordCodeResponse'; export * from './account/VerifyResetPasswordCodeResponse'; -export * from './account/ResetPasswordResponse'; \ No newline at end of file +export * from './account/ResetPasswordResponse'; + +export * from './schedule/CreateScheduleResponse'; +export * from './schedule/UpdateScheduleResponse'; diff --git a/src/data/response/schedule/CreateScheduleResponse.ts b/src/data/response/schedule/CreateScheduleResponse.ts new file mode 100644 index 0000000..994d913 --- /dev/null +++ b/src/data/response/schedule/CreateScheduleResponse.ts @@ -0,0 +1,3 @@ +import { BaseResponse } from "../BaseResponse"; + +export class CreateScheduleResponse extends BaseResponse {} \ No newline at end of file diff --git a/src/data/response/schedule/UpdateScheduleResponse.ts b/src/data/response/schedule/UpdateScheduleResponse.ts new file mode 100644 index 0000000..ef3b0d2 --- /dev/null +++ b/src/data/response/schedule/UpdateScheduleResponse.ts @@ -0,0 +1,3 @@ +import { BaseResponse } from "../BaseResponse"; + +export class UpdateScheduleResponse extends BaseResponse {} \ No newline at end of file diff --git a/src/network/BaseNetwork.ts b/src/network/BaseNetwork.ts index 7dce6eb..68404d5 100644 --- a/src/network/BaseNetwork.ts +++ b/src/network/BaseNetwork.ts @@ -18,7 +18,7 @@ export class BaseNetwork { constructor() { this.instance = axios.create({ - baseURL: import.meta.env.VITE_API_URL || "http://localhost:3000", + baseURL: import.meta.env.VITE_API_URL || "https://localhost:3000", timeout: 10_000, withCredentials: true, headers: { @@ -40,7 +40,24 @@ export class BaseNetwork { if (reqConfig.authPass) { return config; } - const accessToken = localStorage.getItem("accessToken"); + + let accessToken = useAuthStore.getState().authData?.accessToken; + + if (!accessToken) { + const authStorage = localStorage.getItem('auth-storage'); + if (authStorage) { + try { + const parsedState = JSON.parse(authStorage).state; + accessToken = parsedState.authData?.accessToken || null; + + if (accessToken) { + useAuthStore.getState().login({ accessToken }); + } + } catch (e) { + console.error("Failed to parse auth-storage for Access Token:", e); + } + } + } if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}`; } @@ -77,9 +94,8 @@ export class BaseNetwork { private async handleRefreshToken(originalRequest: AxiosRequestConfig) { const authData = useAuthStore.getState().authData; - const refreshToken = authData?.refreshToken; - if (!authData || !refreshToken) { + if (!authData) { useAuthStore.getState().logout(); return Promise.reject("no refresh token"); } @@ -141,7 +157,7 @@ export class BaseNetwork { const authData: AuthData = JSON.parse(storedAuth).state; - if (!authData || !authData.refreshToken) { + if (!authData) { localStorage.setItem('autoLogin', 'false'); throw new Error; } @@ -149,20 +165,16 @@ export class BaseNetwork { const result = await this.get( '/account/refresh-access-token', { - headers: { - Authorization: `Bearer ${authData.refreshToken}` - } + withCredentials: true } ); if (!result.data.success) throw new Error; const newAccessToken = result.data.accessToken; - const newRefreshToken = result.data.refreshToken; useAuthStore.getState().login({ - accessToken: newAccessToken, - refreshToken: newRefreshToken + accessToken: newAccessToken }); } } \ No newline at end of file diff --git a/src/network/ScheduleNetwork.ts b/src/network/ScheduleNetwork.ts new file mode 100644 index 0000000..a52a230 --- /dev/null +++ b/src/network/ScheduleNetwork.ts @@ -0,0 +1,43 @@ +import type { CreateScheduleRequest } from "@/data/request/schedule/CreateScheduleRequest"; +import { BaseNetwork } from "./BaseNetwork" +import type { UpdateScheduleRequest } from "@/data/request/schedule/UpdateScheduleRequest"; +import type { DeleteScheduleRequest } from "@/data/request/schedule/DeleteScheduleRequest"; +import type { ScheduleListRequest } from "@/data/request/schedule/ScheduleListRequest"; + +export class ScheduleNetwork extends BaseNetwork { + private baseUrl = "/schedule"; + + async getList(data: ScheduleListRequest) { + return await this.post( + this.baseUrl, + data + ); + } + + async getDetail(id: string) { + return await this.get( + `${this.baseUrl}/${id}` + ); + } + + async create(data: CreateScheduleRequest) { + return await this.post( + `${this.baseUrl}/create`, + data + ); + } + + async update(data: UpdateScheduleRequest) { + return await this.post( + `${this.baseUrl}/update`, + data + ); + } + + async del(data: DeleteScheduleRequest) { + return await this.post( + `${this.baseUrl}/delete`, + data + ); + } +} \ No newline at end of file diff --git a/src/ui/component/popover/ColorPickPopover.tsx b/src/ui/component/popover/ColorPickPopover.tsx index 669b811..0dba42c 100644 --- a/src/ui/component/popover/ColorPickPopover.tsx +++ b/src/ui/component/popover/ColorPickPopover.tsx @@ -11,8 +11,7 @@ export const ColorPickPopover = ({ setColor }: ColorPickPopoverProps) => { const [seeMore, setSeeMore] = useState(false); const { getMainPaletteList, - getExtraPaletteList, - getCustomColor + getExtraPaletteList } = usePalette(); const mainPaletteList = getMainPaletteList(); const extraPaletteList = getExtraPaletteList(); diff --git a/src/ui/component/popover/SchedulePopover.tsx b/src/ui/component/popover/SchedulePopover.tsx index 9d98220..4e32c45 100644 --- a/src/ui/component/popover/SchedulePopover.tsx +++ b/src/ui/component/popover/SchedulePopover.tsx @@ -7,6 +7,12 @@ 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 { ArrowLeft, PenSquare, X } from 'lucide-react'; interface ScheduleSheetProps { date: Date | undefined; @@ -16,22 +22,94 @@ interface ScheduleSheetProps { export const SchedulePopover = ({ date, popoverSide, popoverAlign }: ScheduleSheetProps) => { const { - ColorPaletteType, - getPaletteNameList, - getMainPaletteList, - getAllPaletteList, - getCustomColor, getPaletteByKey, - getStyle } = usePalette(); const defaultColor = getPaletteByKey('Black'); const [scheduleColor, setScheduleColor] = useState(defaultColor); const [colorPopoverOpen, setColorPopoverOpen] = useState(false); + const [mode, setMode] = useState<'list' | 'detail' | 'create' | 'edit'>('list'); const selectColor = (color: ColorPaletteType) => { setScheduleColor(color); setColorPopoverOpen(false); } + const createScheduleForm = useForm>({ + resolver: zodResolver(CreateScheduleSchema), + defaultValues: { + name: "", + startDate: date, + endDate: date, + content: "", + startTime: "", + endTime: "", + type: "once", + status: "yet", + style: defaultColor.style, + } + }); + + const Content = () => { + switch(mode) { + case 'list': + return ( + + setMode('create')}/> + + ); + case 'create': + return ( + + + + + + + + + ( + + + + + )} + /> + + setMode('list')} + > + + 닫기 + + + ) + default: return (<>>) + } + } + return ( - - - - - - - - - + {} ) diff --git a/src/ui/page/account/login/LoginPage.tsx b/src/ui/page/account/login/LoginPage.tsx index d78f985..3901b68 100644 --- a/src/ui/page/account/login/LoginPage.tsx +++ b/src/ui/page/account/login/LoginPage.tsx @@ -70,8 +70,7 @@ export default function LoginPage() { setIsLoading(false); if (res.data.success) { const data = { - accessToken: res.data.accessToken!, - refreshToken: res.data.refreshToken! + accessToken: res.data.accessToken! }; login({...data}); if (autoLogin) { diff --git a/vite.config.ts b/vite.config.ts index a364a9c..a8c5752 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,12 +2,37 @@ import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' import tailwindcss from '@tailwindcss/vite' import path from 'path' +import * as fs from 'fs' + +const certPath = path.resolve(__dirname, 'certs'); + // https://vite.dev/config/ export default defineConfig({ server: { host: '0.0.0.0', - port: 5185 + port: 5185, + https: { + key: fs.readFileSync(path.join(certPath, 'localhost+2-key.pem')), + cert: fs.readFileSync(path.join(certPath, 'localhost+2.pem')) + }, + proxy: { + '/local-api': { + target: 'https://localhost:3000', + secure: false, + ws: true, + changeOrigin: true, + rewrite: (path) => path.replace(/^\/local-api/, ''), + }, + '/dev-api': { + target: 'https://localhost:8088', + secure: false, + ws: true, + changeOrigin: true, + rewrite: (path) => path.replace(/^\/dev-api/, ''), + } + } }, + plugins: [ react(), tailwindcss()