mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-20 13:51:45 +00:00
fix(i18n): translate remaining German hardcoded strings in PhotoUpload
Replace 6 hardcoded German strings in PhotoUpload.tsx with t() calls:
- 'Tag verknüpfen' → t('photos.linkDay')
- 'Kein Tag' / 'Tag N' → t('photos.noDay') / t('photos.dayLabel')
- '{N} Foto(s) ausgewählt' → t('photos.photoSelected/photosSelected')
- 'bis zu 30 Fotos' hint → t('photos.fileTypeHint')
- 'Wird hochgeladen...' → t('common.uploading')
Add all 6 new keys to all 14 language files and update test
assertions from German strings to English equivalents.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -50,7 +50,7 @@ describe('PhotoUpload', () => {
|
||||
|
||||
it('FE-COMP-PHOTOUPLOAD-002: options section hidden before files are selected', () => {
|
||||
render(<PhotoUpload {...defaultProps} />)
|
||||
expect(screen.queryByText('Tag verknüpfen')).not.toBeInTheDocument()
|
||||
expect(screen.queryByText('Link Day')).not.toBeInTheDocument()
|
||||
expect(screen.queryByPlaceholderText('Optional caption...')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
@@ -65,27 +65,27 @@ describe('PhotoUpload', () => {
|
||||
render(<PhotoUpload {...defaultProps} />)
|
||||
await uploadFiles([makeFile()])
|
||||
expect(screen.getByAltText('photo.jpg')).toBeInTheDocument()
|
||||
expect(screen.getByText('Tag verknüpfen')).toBeInTheDocument()
|
||||
expect(screen.getByText('Link Day')).toBeInTheDocument()
|
||||
expect(screen.getByPlaceholderText('Optional caption...')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('FE-COMP-PHOTOUPLOAD-005: file count label updates correctly', async () => {
|
||||
render(<PhotoUpload {...defaultProps} />)
|
||||
await uploadFiles([makeFile('photo1.jpg'), makeFile('photo2.jpg')])
|
||||
expect(screen.getByText('2 Fotos ausgewählt')).toBeInTheDocument()
|
||||
expect(screen.getByText('2 Photos selected')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('FE-COMP-PHOTOUPLOAD-006: remove button removes a file from preview', async () => {
|
||||
render(<PhotoUpload {...defaultProps} />)
|
||||
await uploadFiles([makeFile('photo1.jpg'), makeFile('photo2.jpg')])
|
||||
expect(screen.getByText('2 Fotos ausgewählt')).toBeInTheDocument()
|
||||
expect(screen.getByText('2 Photos selected')).toBeInTheDocument()
|
||||
|
||||
// Remove buttons are inside `.relative.aspect-square` wrappers in the preview grid
|
||||
const removeButtons = document.querySelectorAll('.relative.aspect-square button')
|
||||
expect(removeButtons.length).toBe(2)
|
||||
await userEvent.click(removeButtons[0])
|
||||
|
||||
expect(screen.getByText('1 Foto ausgewählt')).toBeInTheDocument()
|
||||
expect(screen.getByText('1 Photo selected')).toBeInTheDocument()
|
||||
expect(screen.getAllByRole('img').length).toBe(1)
|
||||
})
|
||||
|
||||
@@ -146,7 +146,7 @@ describe('PhotoUpload', () => {
|
||||
await userEvent.click(getSubmitButton())
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText(/wird hochgeladen/i)).toBeInTheDocument()
|
||||
expect(screen.getAllByText(/uploading/i).length).toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
expect(getSubmitButton()).toBeDisabled()
|
||||
|
||||
@@ -90,7 +90,7 @@ export function PhotoUpload({ tripId, days, places, onUpload, onClose }: PhotoUp
|
||||
<>
|
||||
<p className="text-gray-600 font-medium">{t('photos.dropHereActive')}</p>
|
||||
<p className="text-gray-400 text-sm mt-1">{t('photos.clickToSelect')}</p>
|
||||
<p className="text-gray-400 text-xs mt-2">JPG, PNG, WebP · max. 10 MB · bis zu 30 Fotos</p>
|
||||
<p className="text-gray-400 text-xs mt-2">{t('photos.fileTypeHint')}</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -98,7 +98,7 @@ export function PhotoUpload({ tripId, days, places, onUpload, onClose }: PhotoUp
|
||||
{/* Preview grid */}
|
||||
{files.length > 0 && (
|
||||
<div>
|
||||
<p className="text-sm font-medium text-gray-700 mb-2">{files.length} Foto{files.length !== 1 ? 's' : ''} ausgewählt</p>
|
||||
<p className="text-sm font-medium text-gray-700 mb-2">{files.length} {t(files.length !== 1 ? 'photos.photosSelected' : 'photos.photoSelected')}</p>
|
||||
<div className="grid grid-cols-4 sm:grid-cols-6 gap-2 max-h-48 overflow-y-auto">
|
||||
{files.map((file, idx) => (
|
||||
<div key={idx} className="relative aspect-square group">
|
||||
@@ -126,15 +126,15 @@ export function PhotoUpload({ tripId, days, places, onUpload, onClose }: PhotoUp
|
||||
{files.length > 0 && (
|
||||
<div className="grid grid-cols-2 gap-3">
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">Tag verknüpfen</label>
|
||||
<label className="block text-xs font-medium text-gray-700 mb-1">{t('photos.linkDay')}</label>
|
||||
<select
|
||||
value={dayId}
|
||||
onChange={e => setDayId(e.target.value)}
|
||||
className="w-full border border-gray-200 rounded-lg px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-slate-900"
|
||||
>
|
||||
<option value="">Kein Tag</option>
|
||||
<option value="">{t('photos.noDay')}</option>
|
||||
{(days || []).map(day => (
|
||||
<option key={day.id} value={day.id}>Tag {day.day_number}</option>
|
||||
<option key={day.id} value={day.id}>{t('photos.dayLabel', { number: day.day_number })}</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
@@ -169,7 +169,7 @@ export function PhotoUpload({ tripId, days, places, onUpload, onClose }: PhotoUp
|
||||
<div className="bg-slate-50 rounded-lg p-3">
|
||||
<div className="flex items-center gap-2 mb-2">
|
||||
<div className="w-4 h-4 border-2 border-slate-900 border-t-transparent rounded-full animate-spin" />
|
||||
<span className="text-sm text-slate-900">Wird hochgeladen...</span>
|
||||
<span className="text-sm text-slate-900">{t('common.uploading')}</span>
|
||||
</div>
|
||||
<div className="w-full bg-slate-200 rounded-full h-1.5">
|
||||
<div
|
||||
|
||||
Reference in New Issue
Block a user