Add missing translations for project templates and task details
continuous-integration/drone/push Build is passing

Adds new translation keys for project templates and task details in `en.json` and `de.json`, and updates `ProjectTemplate.tsx` to use these translations.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/iGgwDyZ
This commit is contained in:
paul-nothaft
2025-10-24 11:26:17 +00:00
parent 3c39346087
commit d5b045158a
4 changed files with 51 additions and 41 deletions
-4
View File
@@ -30,10 +30,6 @@ externalPort = 3000
localPort = 44261
externalPort = 3003
[[ports]]
localPort = 46755
externalPort = 4200
[env]
PORT = "5000"
+35 -35
View File
@@ -677,7 +677,7 @@ export default function ProjectTemplate({
{/* Closed Projects Section */}
<div className="space-y-4 mt-8">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">Closed Projects</h3>
<h3 className="text-lg font-semibold">{t('projectTemplate.closedProjects')}</h3>
<Input
placeholder="Filter closed projects..."
value={closedProjectsFilter}
@@ -1124,25 +1124,25 @@ export default function ProjectTemplate({
{/* Project Details */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<div className="space-y-2">
<label className="text-sm font-medium">Project Name</label>
<label className="text-sm font-medium">{t('projectTemplate.projectName')}</label>
<Input
value={selectedProject.name}
onChange={(e) => setSelectedProject({ ...selectedProject, name: e.target.value })}
placeholder="Enter project name"
placeholder={t('projectTemplate.projectNamePlaceholder')}
data-testid="input-edit-project-name"
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Description (Optional)</label>
<label className="text-sm font-medium">{t('projectTemplate.projectDescription')}</label>
<Input
value={selectedProject.description || ''}
onChange={(e) => setSelectedProject({ ...selectedProject, description: e.target.value })}
placeholder="Enter project description"
placeholder={t('projectTemplate.projectDescriptionPlaceholder')}
data-testid="input-edit-project-description"
/>
</div>
<div className="space-y-2">
<label className="text-sm font-medium">Status</label>
<label className="text-sm font-medium">{t('projectTemplate.status')}</label>
<Select
value={selectedProject.status}
onValueChange={(value: Project['status']) =>
@@ -1153,9 +1153,9 @@ export default function ProjectTemplate({
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="planning">Planning</SelectItem>
<SelectItem value="active">Active</SelectItem>
<SelectItem value="finished">Finished</SelectItem>
<SelectItem value="planning">{t('projectTemplate.planning')}</SelectItem>
<SelectItem value="active">{t('projectTemplate.active')}</SelectItem>
<SelectItem value="finished">{t('projectTemplate.finished')}</SelectItem>
</SelectContent>
</Select>
</div>
@@ -1163,7 +1163,7 @@ export default function ProjectTemplate({
{/* Planned End Date */}
<div className="space-y-2">
<label className="text-sm font-medium">Planned End Date (Optional)</label>
<label className="text-sm font-medium">{t('projectTemplate.plannedEndDate')}</label>
<Popover open={isPlannedEndDateCalendarOpen} onOpenChange={setIsPlannedEndDateCalendarOpen}>
<PopoverTrigger asChild>
<Button
@@ -1174,7 +1174,7 @@ export default function ProjectTemplate({
<CalendarIcon className="mr-2 h-4 w-4" />
{selectedProject.plannedEndDate
? selectedProject.plannedEndDate.toLocaleDateString()
: "Select planned end date"}
: t('projectTemplate.selectPlannedEndDate')}
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
@@ -1198,7 +1198,7 @@ export default function ProjectTemplate({
className="text-xs text-muted-foreground hover:text-destructive"
data-testid="button-clear-planned-end-date"
>
Clear date
{t('projectTemplate.clearDate')}
</Button>
)}
</div>
@@ -1206,7 +1206,7 @@ export default function ProjectTemplate({
{/* Tasks Section */}
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-lg font-semibold">Project Tasks</h3>
<h3 className="text-lg font-semibold">{t('projectTemplate.projectTasks')}</h3>
<Button
variant="outline"
size="sm"
@@ -1214,7 +1214,7 @@ export default function ProjectTemplate({
data-testid="button-add-task-edit"
>
<Plus className="w-4 h-4 mr-2" />
Add Task
{t('projectTemplate.addTask')}
</Button>
</div>
@@ -1227,29 +1227,29 @@ export default function ProjectTemplate({
<div className="space-y-3">
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
<div className="space-y-1">
<label className="text-xs font-medium text-muted-foreground">Task Title</label>
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.taskTitle')}</label>
<Input
value={taskForm.title || ''}
onChange={(e) => setTaskForm({...taskForm, title: e.target.value})}
placeholder="Enter task title"
placeholder={t('projectTemplate.enterTaskTitle')}
className="text-sm"
data-testid={`input-inline-task-title-${index}`}
/>
</div>
<div className="space-y-1">
<label className="text-xs font-medium text-muted-foreground">Description</label>
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.description')}</label>
<Input
value={taskForm.description || ''}
onChange={(e) => setTaskForm({...taskForm, description: e.target.value})}
placeholder="Enter task description"
placeholder={t('projectTemplate.enterTaskDescription')}
className="text-sm"
data-testid={`input-inline-task-description-${index}`}
/>
</div>
<div className="space-y-1">
<label className="text-xs font-medium text-muted-foreground">Priority</label>
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.priority')}</label>
<Select
value={taskForm.priority || 'medium'}
onValueChange={(value: ProjectTask['priority']) =>
@@ -1260,15 +1260,15 @@ export default function ProjectTemplate({
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="low">Low</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
<SelectItem value="high">High</SelectItem>
<SelectItem value="low">{t('priority.low')}</SelectItem>
<SelectItem value="medium">{t('priority.medium')}</SelectItem>
<SelectItem value="high">{t('priority.high')}</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1">
<label className="text-xs font-medium text-muted-foreground">Status</label>
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.status')}</label>
<Select
value={taskForm.status || 'todo'}
onValueChange={(value: ProjectTask['status']) =>
@@ -1279,15 +1279,15 @@ export default function ProjectTemplate({
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="todo">To Do</SelectItem>
<SelectItem value="inProgress">In Progress</SelectItem>
<SelectItem value="done">Done</SelectItem>
<SelectItem value="todo">{t('status.todo')}</SelectItem>
<SelectItem value="inProgress">{t('status.inProgress')}</SelectItem>
<SelectItem value="done">{t('status.done')}</SelectItem>
</SelectContent>
</Select>
</div>
<div className="space-y-1 md:col-span-2">
<label className="text-xs font-medium text-muted-foreground">Estimated Hours</label>
<label className="text-xs font-medium text-muted-foreground">{t('projectTemplate.estimatedHours')}</label>
<Input
type="number"
value={taskForm.estimatedHours || ''}
@@ -1307,7 +1307,7 @@ export default function ProjectTemplate({
onClick={handleCancelTaskEdit}
data-testid={`button-cancel-inline-edit-${index}`}
>
Cancel
{t('projectTemplate.cancel')}
</Button>
<Button
size="sm"
@@ -1315,7 +1315,7 @@ export default function ProjectTemplate({
disabled={!taskForm.title?.trim()}
data-testid={`button-save-inline-edit-${index}`}
>
Save Changes
{t('projectTemplate.save')}
</Button>
</div>
</div>
@@ -1345,13 +1345,13 @@ export default function ProjectTemplate({
) : null}
{task.timeTracked && task.timeTracked > 0 && (
<Badge variant="outline" className="text-xs bg-blue-50 text-blue-700 border-blue-200">
{Math.floor(task.timeTracked / 60)}h {task.timeTracked % 60}m tracked
{Math.floor(task.timeTracked / 60)}h {task.timeTracked % 60}m {t('projectTemplate.tracked')}
</Badge>
)}
{task.notes && task.notes.trim() && (
<Badge variant="outline" className="text-xs bg-green-50 text-green-700 border-green-200">
<FileText className="w-3 h-3 mr-1" />
Notes
{t('projectTemplate.notesLabel')}
</Badge>
)}
</div>
@@ -1365,7 +1365,7 @@ export default function ProjectTemplate({
handleOpenTaskDetails(task);
}}
data-testid={`button-details-task-${index}`}
title="View task details"
title={t('projectTemplate.viewTaskDetails')}
>
<FileText className="w-3 h-3" />
</Button>
@@ -1377,7 +1377,7 @@ export default function ProjectTemplate({
handleEditTask(index);
}}
data-testid={`button-edit-task-edit-${index}`}
title="Edit task"
title={t('projectTemplate.editTaskTooltip')}
>
<Edit className="w-3 h-3" />
</Button>
@@ -1389,7 +1389,7 @@ export default function ProjectTemplate({
handleRemoveTask(index);
}}
data-testid={`button-remove-task-edit-${index}`}
title="Remove task"
title={t('projectTemplate.removeTask')}
>
<Trash2 className="w-3 h-3" />
</Button>
@@ -1401,7 +1401,7 @@ export default function ProjectTemplate({
{projectTasks.length === 0 && (
<div className="text-center text-muted-foreground text-sm py-8 border-2 border-dashed border-muted rounded-lg">
No tasks in this project yet. Click "Add Task" to get started.
{t('projectTemplate.noTasksInProject')}
</div>
)}
</div>
+8 -1
View File
@@ -253,7 +253,14 @@
"projectDescriptionPlaceholder": "Projektbeschreibung eingeben (optional)",
"plannedEndDate": "Geplantes Enddatum",
"selectPlannedEndDate": "Geplantes Enddatum wählen",
"clearDate": "Datum löschen"
"clearDate": "Datum löschen",
"noTasksInProject": "Noch keine Aufgaben in diesem Projekt. Klicken Sie auf \"Aufgabe hinzufügen\", um zu beginnen.",
"closedProjects": "Abgeschlossene Projekte",
"viewTaskDetails": "Aufgabendetails anzeigen",
"editTaskTooltip": "Aufgabe bearbeiten",
"removeTask": "Aufgabe entfernen",
"tracked": "verfolgt",
"notesLabel": "Notizen"
},
"timeCompletion": {
"title": "Aufgabe abgeschlossen!",
+8 -1
View File
@@ -253,7 +253,14 @@
"projectDescriptionPlaceholder": "Enter project description (optional)",
"plannedEndDate": "Planned End Date",
"selectPlannedEndDate": "Select planned end date",
"clearDate": "Clear date"
"clearDate": "Clear date",
"noTasksInProject": "No tasks in this project yet. Click \"Add Task\" to get started.",
"closedProjects": "Closed Projects",
"viewTaskDetails": "View task details",
"editTaskTooltip": "Edit task",
"removeTask": "Remove task",
"tracked": "tracked",
"notesLabel": "Notes"
},
"timeCompletion": {
"title": "Task Completed!",