Skip to content

Commit 7d64dfd

Browse files
authored
Merge pull request #56 from Turtle-Hwan/feat/template
fix: when make new template, cannot find default icons
2 parents f225149 + 049cda7 commit 7d64dfd

File tree

3 files changed

+62
-15
lines changed

3 files changed

+62
-15
lines changed

src/apis/client.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,3 +366,40 @@ export async function patch<T = unknown>(
366366
): Promise<ApiResponse<T>> {
367367
return request<T>(url, "PATCH", data, config);
368368
}
369+
370+
/**
371+
* Public request function (no auth interceptor)
372+
* For public endpoints that don't require authentication
373+
*/
374+
export async function publicRequest<T = unknown>(
375+
url: string,
376+
method: string,
377+
body?: unknown,
378+
config?: RequestConfig
379+
): Promise<ApiResponse<T>> {
380+
try {
381+
const { headers = {}, params } = config || {};
382+
383+
const urlWithParams = buildUrl(url, params);
384+
const fullUrl = url.startsWith("http") ? urlWithParams : `${API_BASE_URL}${urlWithParams}`;
385+
386+
const response = await fetch(fullUrl, {
387+
method,
388+
headers: { "Content-Type": "application/json", ...headers },
389+
body: body ? JSON.stringify(body) : undefined,
390+
});
391+
392+
const data = await response.json();
393+
394+
if (!response.ok) {
395+
return { success: false, status: response.status, error: { code: "ERROR", message: data.message } };
396+
}
397+
398+
// Extract 'result' field if present (backend response format)
399+
const resultData = data && typeof data === 'object' && 'result' in data ? data.result : data;
400+
401+
return { success: true, status: response.status, data: resultData as T };
402+
} catch (error) {
403+
return { success: false, error: { code: "NETWORK_ERROR", message: String(error) } };
404+
}
405+
}

src/apis/icons.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Icon asset management
44
*/
55

6-
import { get, post, put, del, ENDPOINTS } from './client';
6+
import { get, post, put, del, publicRequest, ENDPOINTS } from './client';
77
import type { ApiResponse, Icon, CreateIconResponse, DeleteResponse } from '../types/api';
88

99
/**
@@ -21,10 +21,10 @@ export async function createIcon(
2121
}
2222

2323
/**
24-
* Get list of default system icons
24+
* Get list of default system icons (public endpoint, no auth required)
2525
*/
2626
export async function getDefaultIcons(): Promise<ApiResponse<Icon[]>> {
27-
return get<Icon[]>(ENDPOINTS.ICONS.DEFAULT);
27+
return publicRequest<Icon[]>(ENDPOINTS.ICONS.DEFAULT, "GET");
2828
}
2929

3030
/**

src/contexts/EditorContext.tsx

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -499,33 +499,43 @@ export const EditorProvider = ({ children, templateId, startFrom }: EditorProvid
499499
dispatch({ type: 'SET_LOADING', payload: true });
500500

501501
try {
502-
// Always fetch server icons first (for icon picker and template items)
503-
const iconsResult = await getDefaultIcons();
502+
// Fetch both default icons and user icons in parallel
503+
const [iconsResult, userIconsResult] = await Promise.allSettled([
504+
getDefaultIcons(),
505+
getMyIcons(),
506+
]);
504507

505508
console.log('[EditorContext] Icons API full response:', iconsResult);
506509

507-
// Parse icons from response
508-
// client.ts already extracts 'result' field, so iconsResult.data should be Icon[]
510+
// Parse default icons from response
509511
let defaultIcons: Icon[] = [];
510512

511-
if (iconsResult.success && iconsResult.data) {
512-
if (Array.isArray(iconsResult.data)) {
513-
defaultIcons = iconsResult.data;
514-
} else if (typeof iconsResult.data === 'object' && 'items' in iconsResult.data) {
513+
if (iconsResult.status === 'fulfilled' && iconsResult.value.success && iconsResult.value.data) {
514+
if (Array.isArray(iconsResult.value.data)) {
515+
defaultIcons = iconsResult.value.data;
516+
} else if (typeof iconsResult.value.data === 'object' && 'items' in iconsResult.value.data) {
515517
// Handle paginated response format
516-
defaultIcons = (iconsResult.data as { items: Icon[] }).items;
518+
defaultIcons = (iconsResult.value.data as { items: Icon[] }).items;
517519
} else {
518-
console.error('[EditorContext] Unexpected response structure:', iconsResult.data);
520+
console.error('[EditorContext] Unexpected response structure:', iconsResult.value.data);
519521
}
520-
} else {
521-
console.error('[EditorContext] Icons API failed:', iconsResult.error);
522+
} else if (iconsResult.status === 'rejected') {
523+
console.error('[EditorContext] Icons API failed:', iconsResult.reason);
522524
}
523525

524526
console.log('[EditorContext] Final defaultIcons count:', defaultIcons.length);
525527

526528
// Load server icons for icon picker (even if empty)
527529
dispatch({ type: 'LOAD_DEFAULT_ICONS', payload: defaultIcons });
528530

531+
// Load user icons for icon picker
532+
if (userIconsResult.status === 'fulfilled' && userIconsResult.value.success && userIconsResult.value.data) {
533+
const userIcons = Array.isArray(userIconsResult.value.data)
534+
? userIconsResult.value.data
535+
: (userIconsResult.value.data as { items: Icon[] }).items || [];
536+
dispatch({ type: 'LOAD_USER_ICONS', payload: userIcons });
537+
}
538+
529539
// Create template based on startFrom mode
530540
if (startFrom === 'empty') {
531541
// Empty template - no items, just icons for picker

0 commit comments

Comments
 (0)