generated from pricelees/issue-pr-template
[#44] 매장 기능 도입 #45
@ -28,7 +28,7 @@ export interface UserLoginSuccessResponse extends LoginSuccessResponse {
|
||||
|
||||
export interface AdminLoginSuccessResponse extends LoginSuccessResponse {
|
||||
type: AdminType;
|
||||
storeId: number | null;
|
||||
storeId: string | null;
|
||||
}
|
||||
|
||||
export interface CurrentUserContext {
|
||||
|
||||
@ -8,28 +8,28 @@ import type {
|
||||
ScheduleUpdateRequest
|
||||
} from './scheduleTypes';
|
||||
|
||||
export const fetchAvailableThemesByDate = async (date: string): Promise<AvailableThemeIdListResponse> => {
|
||||
return await apiClient.get<AvailableThemeIdListResponse>(`/schedules/themes?date=${date}`);
|
||||
export const fetchStoreAvailableThemesByDate = async (storeId: string, date: string): Promise<AvailableThemeIdListResponse> => {
|
||||
return await apiClient.get<AvailableThemeIdListResponse>(`/stores/${storeId}/themes?date=${date}`);
|
||||
};
|
||||
|
||||
export const fetchSchedulesByDateAndTheme = async (storeId: number, date: string, themeId: string): Promise<ScheduleRetrieveListResponse> => {
|
||||
return await apiClient.get<ScheduleRetrieveListResponse>(`/schedules?storeId=${storeId}&date=${date}&themeId=${themeId}`);
|
||||
export const fetchStoreSchedulesByDateAndTheme = async (storeId: string, date: string, themeId: string): Promise<ScheduleRetrieveListResponse> => {
|
||||
return await apiClient.get<ScheduleRetrieveListResponse>(`/stores/${storeId}/schedules?date=${date}&themeId=${themeId}`);
|
||||
};
|
||||
|
||||
export const fetchScheduleById = async (id: string): Promise<ScheduleDetailRetrieveResponse> => {
|
||||
return await apiClient.get<ScheduleDetailRetrieveResponse>(`/schedules/${id}`);
|
||||
}
|
||||
export const fetchScheduleDetailById = async (id: string): Promise<ScheduleDetailRetrieveResponse> => {
|
||||
return await apiClient.get<ScheduleDetailRetrieveResponse>(`/admin/schedules/${id}`);
|
||||
};
|
||||
|
||||
export const createSchedule = async (request: ScheduleCreateRequest): Promise<ScheduleCreateResponse> => {
|
||||
return await apiClient.post<ScheduleCreateResponse>('/schedules', request);
|
||||
export const createSchedule = async (storeId: string, request: ScheduleCreateRequest): Promise<ScheduleCreateResponse> => {
|
||||
return await apiClient.post<ScheduleCreateResponse>(`/admin/stores/${storeId}/schedules`, request);
|
||||
};
|
||||
|
||||
export const updateSchedule = async (id: string, request: ScheduleUpdateRequest): Promise<void> => {
|
||||
await apiClient.patch(`/schedules/${id}`, request);
|
||||
await apiClient.patch(`/admin/schedules/${id}`, request);
|
||||
};
|
||||
|
||||
export const deleteSchedule = async (id: string): Promise<void> => {
|
||||
await apiClient.del(`/schedules/${id}`);
|
||||
await apiClient.del(`/admin/schedules/${id}`);
|
||||
};
|
||||
|
||||
export const holdSchedule = async (id: string): Promise<void> => {
|
||||
|
||||
@ -2,12 +2,12 @@ import { type AuditInfo } from '@_api/common/commonTypes';
|
||||
import type { RegionInfoResponse } from '@_api/region/regionTypes';
|
||||
|
||||
export interface SimpleStoreResponse {
|
||||
id: number;
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface StoreDetailResponse {
|
||||
id: number;
|
||||
id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
contact: string;
|
||||
|
||||
@ -10,7 +10,7 @@ interface AdminAuthContextType {
|
||||
isAdmin: boolean;
|
||||
name: string | null;
|
||||
type: AdminType | null;
|
||||
storeId: number | null;
|
||||
storeId: string | null;
|
||||
loading: boolean;
|
||||
login: (data: Omit<LoginRequest, 'principalType'>) => Promise<AdminLoginSuccessResponse>;
|
||||
logout: () => Promise<void>;
|
||||
@ -22,7 +22,7 @@ export const AdminAuthProvider: React.FC<{ children: ReactNode }> = ({ children
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [name, setName] = useState<string | null>(null);
|
||||
const [type, setType] = useState<AdminType | null>(null);
|
||||
const [storeId, setStoreId] = useState<number | null>(null);
|
||||
const [storeId, setStoreId] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
@ -36,7 +36,7 @@ export const AdminAuthProvider: React.FC<{ children: ReactNode }> = ({ children
|
||||
setIsAdmin(true);
|
||||
setName(storedName);
|
||||
setType(storedType);
|
||||
setStoreId(storedStoreId ? parseInt(storedStoreId, 10) : null);
|
||||
setStoreId(storedStoreId ? storedStoreId : null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load admin auth state from storage", error);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {isLoginRequiredError} from '@_api/apiClient';
|
||||
import {fetchAvailableThemesByDate, fetchSchedulesByDateAndTheme, holdSchedule} from '@_api/schedule/scheduleAPI';
|
||||
import {fetchStoreAvailableThemesByDate, fetchStoreSchedulesByDateAndTheme, holdSchedule} from '@_api/schedule/scheduleAPI';
|
||||
import {type ScheduleRetrieveResponse, ScheduleStatus} from '@_api/schedule/scheduleTypes';
|
||||
import {fetchThemesByIds} from '@_api/theme/themeAPI';
|
||||
import {mapThemeResponse, type ThemeInfoResponse} from '@_api/theme/themeTypes';
|
||||
@ -35,7 +35,7 @@ const ReservationStep1Page: React.FC = () => {
|
||||
useEffect(() => {
|
||||
if (selectedDate) {
|
||||
const dateStr = selectedDate.toLocaleDateString('en-CA'); // yyyy-mm-dd
|
||||
fetchAvailableThemesByDate(dateStr)
|
||||
fetchStoreAvailableThemesByDate(dateStr)
|
||||
.then(res => {
|
||||
console.log('Available themes response:', res);
|
||||
const themeIds: string[] = res.themeIds;
|
||||
@ -69,7 +69,7 @@ const ReservationStep1Page: React.FC = () => {
|
||||
useEffect(() => {
|
||||
if (selectedDate && selectedTheme) {
|
||||
const dateStr = selectedDate.toLocaleDateString('en-CA');
|
||||
fetchSchedulesByDateAndTheme(dateStr, selectedTheme.id)
|
||||
fetchStoreSchedulesByDateAndTheme(dateStr, selectedTheme.id)
|
||||
.then(res => {
|
||||
setSchedules(res.schedules);
|
||||
setSelectedSchedule(null);
|
||||
|
||||
@ -2,8 +2,8 @@ import { isLoginRequiredError } from '@_api/apiClient';
|
||||
import {
|
||||
createSchedule,
|
||||
deleteSchedule,
|
||||
fetchScheduleById,
|
||||
fetchSchedulesByDateAndTheme,
|
||||
fetchScheduleDetailById,
|
||||
fetchStoreSchedulesByDateAndTheme,
|
||||
updateSchedule
|
||||
} from '@_api/schedule/scheduleAPI';
|
||||
import {
|
||||
@ -108,7 +108,7 @@ const AdminSchedulePage: React.FC = () => {
|
||||
const fetchSchedules = () => {
|
||||
const storeId = adminType === 'HQ' ? selectedStoreId : adminStoreId;
|
||||
if (storeId && selectedDate && selectedThemeId) {
|
||||
fetchSchedulesByDateAndTheme(Number(storeId), selectedDate, selectedThemeId)
|
||||
fetchStoreSchedulesByDateAndTheme(storeId, selectedDate, selectedThemeId)
|
||||
.then(res => setSchedules(res.schedules))
|
||||
.catch(err => {
|
||||
setSchedules([]);
|
||||
@ -147,8 +147,16 @@ const AdminSchedulePage: React.FC = () => {
|
||||
alert('시간 형식이 올바르지 않습니다. HH:MM 형식으로 입력해주세요.');
|
||||
return;
|
||||
}
|
||||
if (adminType !== 'STORE' || !adminStoreId) {
|
||||
alert('매장 관리자만 일정을 추가할 수 있습니다.');
|
||||
return;
|
||||
}
|
||||
if (!selectedDate || !selectedThemeId) {
|
||||
alert('날짜와 테마를 선택해주세요.');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await createSchedule({
|
||||
await createSchedule(adminStoreId, {
|
||||
date: selectedDate,
|
||||
themeId: selectedThemeId,
|
||||
time: newScheduleTime,
|
||||
@ -183,7 +191,7 @@ const AdminSchedulePage: React.FC = () => {
|
||||
if (!detailedSchedules[scheduleId]) {
|
||||
setIsLoadingDetails(true);
|
||||
try {
|
||||
const details = await fetchScheduleById(scheduleId);
|
||||
const details = await fetchScheduleDetailById(scheduleId);
|
||||
setDetailedSchedules(prev => ({ ...prev, [scheduleId]: details }));
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
@ -222,7 +230,7 @@ const AdminSchedulePage: React.FC = () => {
|
||||
status: editingSchedule.status,
|
||||
});
|
||||
// Refresh data
|
||||
const details = await fetchScheduleById(editingSchedule.id);
|
||||
const details = await fetchScheduleDetailById(editingSchedule.id);
|
||||
setDetailedSchedules(prev => ({ ...prev, [editingSchedule.id]: details }));
|
||||
setSchedules(schedules.map(s => s.id === editingSchedule.id ? { ...s, time: details.time, status: details.status } : s));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user