Skip to content

Commit ad5e6d7

Browse files
committed
i18n: translate admin module UI strings from Polish to English
Covers workout-structure (editor, exercise-form, group-form, hooks, utils/validate, utils/format) and workout-logs-notice.
1 parent 376a4d2 commit ad5e6d7

8 files changed

Lines changed: 54 additions & 54 deletions

File tree

src/app/(payload)/admin/modules/workout-logs-notice/workout-logs-notice.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ export async function WorkoutLogsNotice({ id, payload }: WorkoutLogsNoticeProps)
3939
}}
4040
>
4141
<div style={{ fontSize: 12, fontWeight: 700, marginBottom: 1 }}>
42-
Ten trening ma zapisane logi.
42+
This workout has recorded logs.
4343
</div>
4444
<div style={{ color: '#9a3412', fontSize: 10, lineHeight: 1 }}>
45-
Nie mozna usunac treningu ani cwiczen z zapisanymi seriami. Mozna edytowac opisy,
46-
dodawac nowe cwiczenia i grupy.
45+
Workouts and exercises with recorded sets cannot be deleted. You can edit descriptions
46+
and add new exercises and groups.
4747
</div>
4848
</div>
4949
)

src/app/(payload)/admin/modules/workout-structure/components/editor/editor.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,24 @@ export function WorkoutStructureEditor({
5151

5252
{exerciseRowsWithLogs.size === 0 && (
5353
<div style={s.infoMsg}>
54-
Brak zapisanych serii dla tego treningu. Dodanie pierwszej serii utworzy sesję automatycznie.
54+
No recorded sets for this workout. Adding the first set will create a session automatically.
5555
</div>
5656
)}
5757

5858
{sectionsWithFallback.map((section, si) => {
5959
const sectionGroups = groupsForSection(section.id)
6060
const sectionKey = section.id ?? `no-section-${si}`
6161
const sectionLabel =
62-
[section.title, section.subtitle].filter(Boolean).join(' · ') || 'Sekcja bez tytułu'
62+
[section.title, section.subtitle].filter(Boolean).join(' · ') || 'Untitled section'
6363

6464
return (
6565
<div key={sectionKey} style={s.sectionBlock}>
6666
<div style={s.sectionHeader}>
67-
{sections.length > 0 ? sectionLabel : 'Grupy treningu'}
67+
{sections.length > 0 ? sectionLabel : 'Workout groups'}
6868
</div>
6969

7070
{sectionGroups.length === 0 && (
71-
<div style={s.empty}>Brak grup w tej sekcji.</div>
71+
<div style={s.empty}>No groups in this section.</div>
7272
)}
7373

7474
{sectionGroups.map((group) => {
@@ -104,27 +104,27 @@ export function WorkoutStructureEditor({
104104
setEditingGroup(group.id)
105105
}}
106106
>
107-
Edytuj grupę
107+
Edit group
108108
</Button>
109109
{!groupsWithLogs.has(group.id) && (
110110
<Button
111111
buttonStyle="error"
112112
margin={false}
113113
disabled={deletingGroup === group.id}
114114
onClick={() => {
115-
if (confirm('Usunąć grupę i wszystkie jej ćwiczenia?')) {
115+
if (confirm('Delete group and all its exercises?')) {
116116
deleteGroup(group.id)
117117
}
118118
}}
119119
>
120-
{deletingGroup === group.id ? '…' : 'Usuń grupę'}
120+
{deletingGroup === group.id ? '…' : 'Delete group'}
121121
</Button>
122122
)}
123123
</div>
124124
</div>
125125
)}
126126

127-
{rows.length === 0 && editingGroup !== group.id && <div style={s.empty}>Brak ćwiczeń.</div>}
127+
{rows.length === 0 && editingGroup !== group.id && <div style={s.empty}>No exercises.</div>}
128128

129129
{rows.map((row) => (
130130
<div key={row.id}>
@@ -165,12 +165,12 @@ export function WorkoutStructureEditor({
165165
margin={false}
166166
disabled={deletingExercise === row.id}
167167
onClick={() => {
168-
if (confirm(`Usunąć ćwiczenie "${exerciseLabel(row)}"?`)) {
168+
if (confirm(`Delete exercise "${exerciseLabel(row)}"?`)) {
169169
deleteExercise(row.id)
170170
}
171171
}}
172172
>
173-
{deletingExercise === row.id ? '…' : 'Usuń'}
173+
{deletingExercise === row.id ? '…' : 'Delete'}
174174
</Button>
175175
)}
176176
</div>
@@ -199,7 +199,7 @@ export function WorkoutStructureEditor({
199199
}}
200200
extraButtonProps={{ style: { width: '100%', textAlign: 'left' } }}
201201
>
202-
+ Dodaj ćwiczenie
202+
+ Add exercise
203203
</Button>
204204
)}
205205
</div>
@@ -225,7 +225,7 @@ export function WorkoutStructureEditor({
225225
onClick={() => setAddingGroupFor(sectionKey)}
226226
extraButtonProps={{ style: { width: '100%', textAlign: 'left' } }}
227227
>
228-
+ Dodaj grupę do tej sekcji
228+
+ Add group to this section
229229
</Button>
230230
)}
231231
</div>

src/app/(payload)/admin/modules/workout-structure/components/editor/hooks/use-workout-mutations.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ export function useWorkoutMutations(
1818
await sdk.delete({ collection: 'workout-groups', id: groupId })
1919
setGroups((prev) => prev.filter((g) => g.id !== groupId))
2020
setExerciseRows((prev) => prev.filter((r) => r.group !== groupId))
21-
toast.success('Grupa usunięta')
21+
toast.success('Group deleted')
2222
} catch (e) {
23-
toast.error(e instanceof Error ? e.message : 'Nie można usunąć grupy')
23+
toast.error(e instanceof Error ? e.message : 'Failed to delete group')
2424
} finally {
2525
setDeletingGroup(null)
2626
}
@@ -31,9 +31,9 @@ export function useWorkoutMutations(
3131
try {
3232
await sdk.delete({ collection: 'workout-exercise-rows', id: rowId })
3333
setExerciseRows((prev) => prev.filter((r) => r.id !== rowId))
34-
toast.success('Ćwiczenie usunięte')
34+
toast.success('Exercise deleted')
3535
} catch (e) {
36-
toast.error(e instanceof Error ? e.message : 'Nie można usunąć ćwiczenia')
36+
toast.error(e instanceof Error ? e.message : 'Failed to delete exercise')
3737
} finally {
3838
setDeletingExercise(null)
3939
}

src/app/(payload)/admin/modules/workout-structure/components/exercise-form/exercise-form.tsx

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const exerciseRelField: SingleRelationshipFieldClient = {
2121
type: 'relationship',
2222
relationTo: 'exercises',
2323
hasMany: false,
24-
label: 'Ćwiczenie (katalog)',
24+
label: 'Exercise (catalog)',
2525
} as SingleRelationshipFieldClient
2626

2727
function FormFields({ isEdit, onCancel }: { isEdit: boolean; onCancel: () => void }) {
@@ -31,10 +31,10 @@ function FormFields({ isEdit, onCancel }: { isEdit: boolean; onCancel: () => voi
3131
<>
3232
<div style={s.formRow}>
3333
<div style={{ flex: '0 0 64px' }}>
34-
<TextField path="numer" field={textField('numer', 'Numer', '1a')} />
34+
<TextField path="numer" field={textField('numer', 'No.', '1a')} />
3535
</div>
3636
<div style={{ flex: '0 0 80px' }}>
37-
<TextField path="rounds" field={textField('rounds', 'Serie', '4')} validate={validateRounds} />
37+
<TextField path="rounds" field={textField('rounds', 'Sets', '4')} validate={validateRounds} />
3838
</div>
3939
<div style={{ flex: 1 }}>
4040
<RelationshipField path="exercise" field={exerciseRelField} />
@@ -43,13 +43,13 @@ function FormFields({ isEdit, onCancel }: { isEdit: boolean; onCancel: () => voi
4343

4444
<div style={s.formRow}>
4545
<div style={{ flex: 1 }}>
46-
<TextField path="note" field={textField('note', 'Uwaga / wariant', 'opcjonalnie')} />
46+
<TextField path="note" field={textField('note', 'Note / variant', 'optional')} />
4747
</div>
4848
</div>
4949

5050
<div style={s.formRow}>
5151
<div style={{ flex: '1 1 70px' }}>
52-
<TextField path="reps" field={textField('reps', 'Powt.', '8')} validate={validateRepsOrKg} />
52+
<TextField path="reps" field={textField('reps', 'Reps', '8')} validate={validateRepsOrKg} />
5353
</div>
5454
<div style={{ flex: '1 1 70px' }}>
5555
<TextField path="kg" field={textField('kg', 'KG', '60')} validate={validateKgOrReps} />
@@ -61,7 +61,7 @@ function FormFields({ isEdit, onCancel }: { isEdit: boolean; onCancel: () => voi
6161
<TextField path="tut" field={textField('tut', 'TUT', '3-0-1')} />
6262
</div>
6363
<div style={{ flex: '1 1 90px' }}>
64-
<TextField path="rest" field={textField('rest', 'Przerwa', '90 sek')} />
64+
<TextField path="rest" field={textField('rest', 'Rest', '90 sec')} />
6565
</div>
6666
</div>
6767

@@ -70,7 +70,7 @@ function FormFields({ isEdit, onCancel }: { isEdit: boolean; onCancel: () => voi
7070
Anuluj
7171
</Button>
7272
<Button buttonStyle="primary" margin={false} type="submit" disabled={processing}>
73-
{processing ? 'Zapisuję…' : isEdit ? 'Zapisz ćwiczenie' : 'Dodaj ćwiczenie'}
73+
{processing ? 'Saving…' : isEdit ? 'Save exercise' : 'Add exercise'}
7474
</Button>
7575
</div>
7676
</>
@@ -119,17 +119,17 @@ export function ExerciseForm({ groupId, nextOrder, initial, onSaved, onCancel }:
119119
const normalizedGroup =
120120
typeof doc.group === 'object' && doc.group !== null ? (doc.group as { id: number }).id : doc.group
121121

122-
toast.success(isEdit ? 'Ćwiczenie zaktualizowane' : 'Ćwiczenie dodane')
122+
toast.success(isEdit ? 'Exercise updated' : 'Exercise added')
123123
onSaved({ ...doc, group: normalizedGroup, exercise: exerciseObj } as ExerciseRow)
124124
} catch (e) {
125-
toast.error(e instanceof Error ? e.message : 'Błąd zapisu')
125+
toast.error(e instanceof Error ? e.message : 'Save failed')
126126
}
127127
}
128128

129129
return (
130130
<div style={s.formBox}>
131131
<div style={{ ...s.label, fontWeight: 700, color: 'var(--theme-text)', marginBottom: 10 }}>
132-
{isEdit ? 'Edytuj ćwiczenie' : 'Nowe ćwiczenie'}
132+
{isEdit ? 'Edit exercise' : 'New exercise'}
133133
</div>
134134

135135
<Form initialState={initialState} onSubmit={handleSubmit}>

src/app/(payload)/admin/modules/workout-structure/components/group-form/group-form.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
const protocolField: SelectFieldClient = {
2020
name: 'protocol',
2121
type: 'select',
22-
label: 'Protokół',
22+
label: 'Protocol',
2323
options: PROTOCOLS,
2424
} as SelectFieldClient
2525

@@ -43,7 +43,7 @@ function FormFields({ onCancel }: { onCancel: () => void }) {
4343
<>
4444
<div style={s.formRow}>
4545
<div style={{ flex: '1 1 200px' }}>
46-
<TextField path="label" field={textField('label', 'Nazwa grupy (opcjonalna)', 'np. Superset górny, Część A')} />
46+
<TextField path="label" field={textField('label', 'Group name (optional)', 'e.g. Upper superset, Part A')} />
4747
</div>
4848
</div>
4949

@@ -54,37 +54,37 @@ function FormFields({ onCancel }: { onCancel: () => void }) {
5454

5555
{protocol !== 'amrap' && protocol !== 'tabata' && (
5656
<div style={{ flex: '1 1 80px' }}>
57-
<TextField path="rounds" field={textField('rounds', 'Serie / rundy', 'np. 4, 1-3')} validate={validateRounds} />
57+
<TextField path="rounds" field={textField('rounds', 'Sets / rounds', 'e.g. 4, 1-3')} validate={validateRounds} />
5858
</div>
5959
)}
6060

6161
{protocol === 'amrap' && (
6262
<div style={{ flex: '1 1 80px' }}>
63-
<TextField path="durationMinutes" field={textField('durationMinutes', 'Czas (min)', '10')} validate={validateDurationMinutes} />
63+
<TextField path="durationMinutes" field={textField('durationMinutes', 'Duration (min)', '10')} validate={validateDurationMinutes} />
6464
</div>
6565
)}
6666

6767
{protocol === 'emom' && (
6868
<div style={{ flex: '1 1 80px' }}>
69-
<TextField path="intervalSeconds" field={textField('intervalSeconds', 'Interwał (s)')} validate={validateIntervalSeconds} />
69+
<TextField path="intervalSeconds" field={textField('intervalSeconds', 'Interval (s)')} validate={validateIntervalSeconds} />
7070
</div>
7171
)}
7272

7373
{protocol === 'tabata' && (
7474
<>
7575
<div style={{ flex: '1 1 70px' }}>
76-
<TextField path="workSeconds" field={textField('workSeconds', 'Praca (s)')} validate={validateWorkSeconds} />
76+
<TextField path="workSeconds" field={textField('workSeconds', 'Work (s)')} validate={validateWorkSeconds} />
7777
</div>
7878
<div style={{ flex: '1 1 70px' }}>
79-
<TextField path="restSeconds" field={textField('restSeconds', 'Odpoczynek (s)')} validate={validateRestSeconds} />
79+
<TextField path="restSeconds" field={textField('restSeconds', 'Rest (s)')} validate={validateRestSeconds} />
8080
</div>
8181
</>
8282
)}
8383
</div>
8484

8585
<div style={s.formRow}>
8686
<div style={{ flex: '1 1 160px' }}>
87-
<TextField path="restBetweenRounds" field={textField('restBetweenRounds', 'Przerwa między rundami', 'np. 90 sek')} />
87+
<TextField path="restBetweenRounds" field={textField('restBetweenRounds', 'Rest between rounds', 'e.g. 90 sec')} />
8888
</div>
8989
</div>
9090

@@ -93,7 +93,7 @@ function FormFields({ onCancel }: { onCancel: () => void }) {
9393
Anuluj
9494
</Button>
9595
<Button buttonStyle="primary" margin={false} type="submit" disabled={processing}>
96-
{processing ? 'Zapisuję…' : 'Zapisz grupę'}
96+
{processing ? 'Saving…' : 'Save group'}
9797
</Button>
9898
</div>
9999
</>
@@ -133,17 +133,17 @@ export function GroupForm({ sectionRowId, nextOrder, initial, onSaved, onCancel
133133
const doc = isEdit
134134
? await sdk.update({ collection: 'workout-groups', id: initial!.id, data: body as unknown as WorkoutGroup })
135135
: await sdk.create({ collection: 'workout-groups', data: body as unknown as WorkoutGroup })
136-
toast.success(isEdit ? 'Grupa zaktualizowana' : 'Grupa dodana')
136+
toast.success(isEdit ? 'Group updated' : 'Group added')
137137
onSaved(doc as unknown as Group)
138138
} catch (e) {
139-
toast.error(e instanceof Error ? e.message : 'Błąd zapisu')
139+
toast.error(e instanceof Error ? e.message : 'Save failed')
140140
}
141141
}
142142

143143
return (
144144
<div style={s.formBox}>
145145
<div style={{ ...s.label, fontWeight: 700, color: 'var(--theme-text)', marginBottom: 10 }}>
146-
{isEdit ? 'Edytuj grupę' : 'Nowa grupa'}
146+
{isEdit ? 'Edit group' : 'New group'}
147147
</div>
148148

149149
<Form initialState={initialState} onSubmit={handleSubmit}>

src/app/(payload)/admin/modules/workout-structure/utils/format.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,21 @@ export const groupLabel = (g: Group): string => {
66
const d = g.durationMinutes
77
if (p === 'emom') return r ? `EMOM · ${r} min` : 'EMOM'
88
if (p === 'amrap') return d ? `AMRAP · ${d} min` : 'AMRAP'
9-
if (p === 'for_time') return r ? `For Time · ${r} rund` : 'For Time'
9+
if (p === 'for_time') return r ? `For Time · ${r} rounds` : 'For Time'
1010
if (p === 'tabata') return 'Tabata'
11-
return r ? `${r} serie` : 'Standard'
11+
return r ? `${r} sets` : 'Standard'
1212
}
1313

1414
export const exerciseLabel = (row: ExerciseRow): string =>
1515
row.exercise?.name ?? row.note ?? '—'
1616

1717
export const exerciseMeta = (row: ExerciseRow): string => {
1818
const parts: string[] = []
19-
if (row.rounds) parts.push(`${row.rounds} serie`)
20-
if (row.reps) parts.push(`${row.reps} powt.`)
19+
if (row.rounds) parts.push(`${row.rounds} sets`)
20+
if (row.reps) parts.push(`${row.reps} reps`)
2121
if (row.kg) parts.push(`${row.kg} kg`)
2222
if (row.rir) parts.push(`RIR ${row.rir}`)
2323
if (row.tut) parts.push(`TUT ${row.tut}`)
24-
if (row.rest) parts.push(`przerwa ${row.rest}`)
24+
if (row.rest) parts.push(`rest ${row.rest}`)
2525
return parts.join(' · ')
2626
}

src/app/(payload)/admin/modules/workout-structure/utils/validate.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,40 @@ import type { TextFieldValidation } from 'payload'
33
type SiblingData = Record<string, unknown>
44

55
export const validateRounds: TextFieldValidation = (value) => {
6-
if (value && !/^[\d\-]+$/.test(String(value))) return 'Format: liczba lub zakres (np. 4, 3–4)'
6+
if (value && !/^[\d\-]+$/.test(String(value))) return 'Format: number or range (e.g. 4, 3–4)'
77
return true
88
}
99

1010
export const validateRepsOrKg: TextFieldValidation = (value, { siblingData }) => {
11-
if (!value && !(siblingData as SiblingData)?.kg) return 'Podaj powtórzenia lub obciążenie'
11+
if (!value && !(siblingData as SiblingData)?.kg) return 'Enter reps or load'
1212
return true
1313
}
1414

1515
export const validateKgOrReps: TextFieldValidation = (value, { siblingData }) => {
16-
if (!value && !(siblingData as SiblingData)?.reps) return 'Podaj powtórzenia lub obciążenie'
16+
if (!value && !(siblingData as SiblingData)?.reps) return 'Enter reps or load'
1717
return true
1818
}
1919

2020
export const validateDurationMinutes: TextFieldValidation = (value, { siblingData }) => {
2121
if ((siblingData as SiblingData)?.protocol === 'amrap' && (!value || isNaN(Number(value))))
22-
return 'Podaj czas (minuty)'
22+
return 'Enter duration (minutes)'
2323
return true
2424
}
2525

2626
export const validateIntervalSeconds: TextFieldValidation = (value, { siblingData }) => {
2727
if ((siblingData as SiblingData)?.protocol === 'emom' && (!value || isNaN(Number(value))))
28-
return 'Podaj interwał (sekundy)'
28+
return 'Enter interval (seconds)'
2929
return true
3030
}
3131

3232
export const validateWorkSeconds: TextFieldValidation = (value, { siblingData }) => {
3333
if ((siblingData as SiblingData)?.protocol === 'tabata' && (!value || isNaN(Number(value))))
34-
return 'Podaj czas pracy'
34+
return 'Enter work duration'
3535
return true
3636
}
3737

3838
export const validateRestSeconds: TextFieldValidation = (value, { siblingData }) => {
3939
if ((siblingData as SiblingData)?.protocol === 'tabata' && (!value || isNaN(Number(value))))
40-
return 'Podaj czas odpoczynku'
40+
return 'Enter rest duration'
4141
return true
4242
}

src/app/(payload)/admin/modules/workout-structure/workout-structure.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export async function WorkoutStructureView({
1515
if (!docId || docId === 'create' || !payload) {
1616
return (
1717
<div style={{ padding: '24px', color: 'var(--theme-elevation-500)', fontSize: 14 }}>
18-
Najpierw zapisz trening, aby zarządzać strukturą.
18+
Save the workout first to manage its structure.
1919
</div>
2020
)
2121
}

0 commit comments

Comments
 (0)