mirror of
https://github.com/chillpadclub/bedolaga-cabinet.git
synced 2026-07-30 02:23:47 +00:00
fix: landing list crash — title is now LocaleDict, not string
- Update LandingListItem.title type to LocaleDict - Add resolveLocaleDisplay() helper for extracting display string - Use resolveLocaleDisplay() in landing list and delete confirm
This commit is contained in:
@@ -108,7 +108,7 @@ export interface AdminLandingFeature {
|
|||||||
export interface LandingListItem {
|
export interface LandingListItem {
|
||||||
id: number;
|
id: number;
|
||||||
slug: string;
|
slug: string;
|
||||||
title: string;
|
title: LocaleDict;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
display_order: number;
|
display_order: number;
|
||||||
gift_enabled: boolean;
|
gift_enabled: boolean;
|
||||||
@@ -167,6 +167,13 @@ export type LandingUpdateRequest = Partial<LandingCreateRequest>;
|
|||||||
* If it's a string, wraps it as `{ ru: value }`.
|
* If it's a string, wraps it as `{ ru: value }`.
|
||||||
* If null/undefined, returns the fallback.
|
* If null/undefined, returns the fallback.
|
||||||
*/
|
*/
|
||||||
|
/** Extract best display string from a LocaleDict: ru → en → first available → '' */
|
||||||
|
export function resolveLocaleDisplay(dict: LocaleDict | string | null | undefined): string {
|
||||||
|
if (!dict) return '';
|
||||||
|
if (typeof dict === 'string') return dict;
|
||||||
|
return dict.ru || dict.en || Object.values(dict).find((v) => v?.trim()) || '';
|
||||||
|
}
|
||||||
|
|
||||||
export function toLocaleDict(
|
export function toLocaleDict(
|
||||||
value: string | LocaleDict | null | undefined,
|
value: string | LocaleDict | null | undefined,
|
||||||
fallback: LocaleDict = {},
|
fallback: LocaleDict = {},
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { useState, useCallback, useEffect, useRef } from 'react';
|
|||||||
import { useNavigate } from 'react-router';
|
import { useNavigate } from 'react-router';
|
||||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { adminLandingsApi, LandingListItem } from '../api/landings';
|
import { adminLandingsApi, LandingListItem, resolveLocaleDisplay } from '../api/landings';
|
||||||
import { useNotify } from '@/platform';
|
import { useNotify } from '@/platform';
|
||||||
import { copyToClipboard } from '../utils/clipboard';
|
import { copyToClipboard } from '../utils/clipboard';
|
||||||
import { getApiErrorMessage } from '../utils/api-error';
|
import { getApiErrorMessage } from '../utils/api-error';
|
||||||
@@ -137,7 +137,9 @@ function SortableLandingCard({
|
|||||||
{/* Content */}
|
{/* Content */}
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="mb-1 flex items-center gap-2">
|
<div className="mb-1 flex items-center gap-2">
|
||||||
<h3 className="truncate font-medium text-dark-100">{landing.title}</h3>
|
<h3 className="truncate font-medium text-dark-100">
|
||||||
|
{resolveLocaleDisplay(landing.title)}
|
||||||
|
</h3>
|
||||||
<span className="rounded bg-dark-800 px-2 py-0.5 text-xs text-dark-400">
|
<span className="rounded bg-dark-800 px-2 py-0.5 text-xs text-dark-400">
|
||||||
{landing.slug}
|
{landing.slug}
|
||||||
</span>
|
</span>
|
||||||
@@ -204,7 +206,7 @@ function SortableLandingCard({
|
|||||||
)}
|
)}
|
||||||
title={
|
title={
|
||||||
isPendingDelete
|
isPendingDelete
|
||||||
? t('admin.landings.deleteConfirm', { title: landing.title })
|
? t('admin.landings.deleteConfirm', { title: resolveLocaleDisplay(landing.title) })
|
||||||
: t('common.delete')
|
: t('common.delete')
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
Reference in New Issue
Block a user