fixing labels in english

This commit is contained in:
Marek Maslowski
2026-04-04 22:00:35 +02:00
parent c9e3185ad0
commit 3413d3f77d
4 changed files with 49 additions and 31 deletions

View File

@@ -60,6 +60,7 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
const currentUser = useAuthStore(s => s.user)
const [connected, setConnected] = useState(false)
const [enabledProviders, setEnabledProviders] = useState<PhotoProvider[]>([])
const [availableProviders, setAvailableProviders] = useState<PhotoProvider[]>([])
const [selectedProvider, setSelectedProvider] = useState<string>('')
const [loading, setLoading] = useState(true)
@@ -198,6 +199,8 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
const enabledAddons = addonsRes?.addons || []
const photoProviders = enabledAddons.filter((a: any) => a.type === 'photo_provider' && a.enabled)
setEnabledProviders(photoProviders.map((a: any) => ({ id: a.id, name: a.name, icon: a.icon, config: a.config })))
// Test connection status for each enabled provider
const statusResults = await Promise.all(
photoProviders.map(async (provider: any) => {
@@ -389,10 +392,10 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', height: '100%', padding: 40, textAlign: 'center', ...font }}>
<Camera size={40} style={{ color: 'var(--text-faint)', marginBottom: 12 }} />
<h3 style={{ margin: '0 0 6px', fontSize: 16, fontWeight: 700, color: 'var(--text-primary)' }}>
{t('memories.notConnected')}
{t('memories.notConnected', { provider_name: enabledProviders.length === 1 ? enabledProviders[0]?.name : 'Photo provider' })}
</h3>
<p style={{ margin: 0, fontSize: 13, color: 'var(--text-muted)', maxWidth: 300 }}>
{t('memories.notConnectedHint')}
{enabledProviders.length === 1 ? t('memories.notConnectedHint', { provider_name: enabledProviders[0]?.name }) : t('memories.notConnectedMultipleHint', { provider_names: enabledProviders.map(p => p.name).join(', ') })}
</p>
</div>
)
@@ -439,14 +442,14 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
<div style={{ padding: '14px 20px', borderBottom: '1px solid var(--border-secondary)' }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
<h3 style={{ margin: 0, fontSize: 15, fontWeight: 700, color: 'var(--text-primary)' }}>
{t('memories.selectAlbum')}
{availableProviders.length > 1 ? t('memories.selectAlbumMultiple') : t('memories.selectAlbum', { provider_name: availableProviders.find(p => p.id === selectedProvider)?.name || 'Photo provider' })}
</h3>
<ProviderTabs />
<button onClick={() => setShowAlbumPicker(false)}
style={{ padding: '7px 14px', borderRadius: 10, border: '1px solid var(--border-primary)', background: 'none', fontSize: 12, cursor: 'pointer', fontFamily: 'inherit', color: 'var(--text-muted)' }}>
{t('common.cancel')}
</button>
</div>
<ProviderTabs />
</div>
<div style={{ flex: 1, overflowY: 'auto', padding: 12 }}>
{albumsLoading ? (
@@ -511,9 +514,8 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
<div style={{ padding: '14px 20px', borderBottom: '1px solid var(--border-secondary)' }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
<h3 style={{ margin: 0, fontSize: 15, fontWeight: 700, color: 'var(--text-primary)' }}>
{t('memories.selectPhotos')}
{availableProviders.length > 1 ? t('memories.selectPhotosMultiple') : t('memories.selectPhotos', { provider_name: availableProviders.find(p => p.id === selectedProvider)?.name || 'Photo provider' })}
</h3>
<ProviderTabs />
<div style={{ display: 'flex', gap: 8 }}>
<button onClick={() => { clearImageQueue(); setShowPicker(false) }}
style={{ padding: '7px 14px', borderRadius: 10, border: '1px solid var(--border-primary)', background: 'none', fontSize: 12, cursor: 'pointer', fontFamily: 'inherit', color: 'var(--text-muted)' }}>
@@ -530,6 +532,9 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
</button>
</div>
</div>
<div style={{ marginBottom: 10 }}>
<ProviderTabs />
</div>
{/* Filter tabs */}
<div style={{ display: 'flex', gap: 6 }}>
{startDate && endDate && (
@@ -573,6 +578,13 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
<div style={{ textAlign: 'center', padding: '60px 20px' }}>
<Camera size={36} style={{ color: 'var(--text-faint)', margin: '0 auto 10px', display: 'block' }} />
<p style={{ fontSize: 13, color: 'var(--text-muted)', margin: 0 }}>{t('memories.noPhotos')}</p>
{
pickerDateFilter && (
<p style={{ fontSize: 12, color: 'var(--text-faint)', margin: '0 0 16px' }}>
{t('memories.noPhotosHint', { provider_name: availableProviders.find(p => p.id === selectedProvider)?.name || 'Photo provider' })}
</p>
)
}
</div>
) : (() => {
// Group photos by month
@@ -761,12 +773,9 @@ export default function MemoriesPanel({ tripId, startDate, endDate }: MemoriesPa
{allVisible.length === 0 ? (
<div style={{ textAlign: 'center', padding: '60px 20px' }}>
<Camera size={40} style={{ color: 'var(--text-faint)', margin: '0 auto 12px', display: 'block' }} />
<p style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-secondary)', margin: '0 0 4px' }}>
<p style={{ fontSize: 14, fontWeight: 600, color: 'var(--text-secondary)', margin: '0 0 12px' }}>
{t('memories.noPhotos')}
</p>
<p style={{ fontSize: 12, color: 'var(--text-faint)', margin: '0 0 16px' }}>
{t('memories.noPhotosHint')}
</p>
<button onClick={openPicker}
style={{
display: 'inline-flex', alignItems: 'center', gap: 5, padding: '9px 18px', borderRadius: 10,

View File

@@ -1350,11 +1350,12 @@ const en: Record<string, string | { name: string; category: string }[]> = {
// Photos / Immich
'memories.title': 'Photos',
'memories.notConnected': 'Immich not connected',
'memories.notConnectedHint': 'Connect your Immich instance in Settings to see your trip photos here.',
'memories.notConnected': '{provider_name} not connected',
'memories.notConnectedHint': 'Connect your {provider_name} instance in Settings to be able add photos to this trip.',
'memories.notConnectedMultipleHint': 'Connect any of these photo providers: {provider_names} in Settings to be able add photos to this trip.',
'memories.noDates': 'Add dates to your trip to load photos.',
'memories.noPhotos': 'No photos found',
'memories.noPhotosHint': 'No photos found in Immich for this trip\'s date range.',
'memories.noPhotosHint': 'No photos found in {provider_name} for this trip\'s date range.',
'memories.photosFound': 'photos',
'memories.fromOthers': 'from others',
'memories.sharePhotos': 'Share photos',
@@ -1362,23 +1363,31 @@ const en: Record<string, string | { name: string; category: string }[]> = {
'memories.reviewTitle': 'Review your photos',
'memories.reviewHint': 'Click photos to exclude them from sharing.',
'memories.shareCount': 'Share {count} photos',
'memories.immichUrl': 'Immich Server URL',
'memories.immichApiKey': 'API Key',
//-------------------------
//todo section
'memories.providerUrl': 'Server URL',
'memories.providerApiKey': 'API Key',
'memories.providerUsername': 'Username',
'memories.providerPassword': 'Password',
'memories.testConnection': 'Test connection',
'memories.testFirst': 'Test connection first',
'memories.connected': 'Connected',
'memories.disconnected': 'Not connected',
'memories.connectionSuccess': 'Connected to Immich',
'memories.connectionError': 'Could not connect to Immich',
'memories.saved': 'Immich settings saved',
'memories.connectionSuccess': 'Connected to {provider_name}',
'memories.connectionError': 'Could not connect to {provider_name}',
'memories.saved': '{provider_name} settings saved',
'memories.saveError': 'Could not save {provider_name} settings',
//------------------------
'memories.addPhotos': 'Add photos',
'memories.linkAlbum': 'Link Album',
'memories.selectAlbum': 'Select Immich Album',
'memories.selectAlbum': 'Select {provider_name} Album',
'memories.selectAlbumMultiple': 'Select Album',
'memories.noAlbums': 'No albums found',
'memories.syncAlbum': 'Sync album',
'memories.unlinkAlbum': 'Unlink album',
'memories.photos': 'photos',
'memories.selectPhotos': 'Select photos from Immich',
'memories.selectPhotos': 'Select photos from {provider_name}',
'memories.selectPhotosMultiple': 'Select Photos',
'memories.selectHint': 'Tap photos to select them.',
'memories.selected': 'selected',
'memories.addSelected': 'Add {count} photos',

View File

@@ -262,9 +262,9 @@ export default function SettingsPage(): React.ReactElement {
try {
await apiClient.put(cfg.settings_put, buildProviderPayload(provider))
await refreshProviderConnection(provider)
toast.success(`${provider.name} settings saved`)
toast.success(t('memories.saved', { provider_name: provider.name }))
} catch {
toast.error(`Could not save ${provider.name} settings`)
toast.error(t('memories.saveError', { provider_name: provider.name }))
} finally {
setSaving(s => ({ ...s, [provider.id]: false }))
}
@@ -281,12 +281,12 @@ export default function SettingsPage(): React.ReactElement {
const ok = !!res.data?.connected
setProviderConnected(prev => ({ ...prev, [provider.id]: ok }))
if (ok) {
toast.success(`${provider.name} connected`)
toast.success(t('memories.connectionSuccess', { provider_name: provider.name }))
} else {
toast.error(`${provider.name} connection failed${res.data?.error ? `: ${String(res.data.error)}` : ''}`)
toast.error(`${t('memories.connectionError', { provider_name: provider.name })} ${res.data?.error ? `: ${String(res.data.error)}` : ''}`)
}
} catch {
toast.error(`${provider.name} connection failed`)
toast.error(t('memories.connectionError', { provider_name: provider.name }))
} finally {
setProviderTesting(prev => ({ ...prev, [provider.id]: false }))
}
@@ -367,7 +367,7 @@ export default function SettingsPage(): React.ReactElement {
<div className="space-y-3">
{fields.map(field => (
<div key={`${provider.id}-${field.key}`}>
<label className="block text-sm font-medium text-slate-700 mb-1.5">{field.label}</label>
<label className="block text-sm font-medium text-slate-700 mb-1.5">{t(`memories.${field.label}`)}</label>
<input
type={field.input_type || 'text'}
value={values[field.key] || ''}