lang bugfix
All checks were successful
Build & Push Docker Image / docker (push) Successful in 1m50s

This commit is contained in:
Ahmed Darrazi 2025-12-18 23:35:27 +01:00
parent fd6ca8221f
commit 6ba9651f34
6 changed files with 63 additions and 63 deletions

View File

@ -4,48 +4,48 @@ import { format } from 'date-fns';
import { AlertCircle, Clock } from 'lucide-react';
import AssignmentDialog from './assignment-dialog';
// Function to format date
// Funktion zum Formatieren des Datums
const formatDate = (dateString: string | undefined) => {
if (!dateString) return 'N/A';
if (!dateString) return 'k.A.';
const date = new Date(dateString);
return format(date, 'MMMM dd, yyyy, hh:mm a');
};
// Function to check if deadline has passed
// Funktion zum Prüfen, ob die Frist abgelaufen ist
const isDeadlinePassed = (deadline: string) => {
if (!deadline) return false;
return new Date() > new Date(deadline);
};
// Function to get submission status
// Funktion, um den Abgabestatus zu ermitteln
const getSubmissionStatus = (assignment: CourseAssignment) => {
if (!assignment.submissions || assignment.submissions.length === 0) {
return { status: 'not_submitted', label: 'Not Submitted', variant: 'secondary' as const };
return { status: 'not_submitted', label: 'Nicht eingereicht', variant: 'secondary' as const };
}
const latestSubmission = assignment.submissions[0];
if (latestSubmission.status === 'graded') {
return { status: 'graded', label: 'Graded', variant: 'default' as const };
return { status: 'graded', label: 'Bewertet', variant: 'default' as const };
} else if (latestSubmission.is_late) {
return { status: 'late', label: 'Late Submission', variant: 'destructive' as const };
return { status: 'late', label: 'Verspätete Abgabe', variant: 'destructive' as const };
} else {
return { status: 'submitted', label: 'Submitted', variant: 'default' as const };
return { status: 'submitted', label: 'Eingereicht', variant: 'default' as const };
}
};
export const AssignmentColumns: ColumnDef<CourseAssignment>[] = [
{
accessorKey: 'title',
header: 'Title',
header: 'Titel',
cell: ({ row }) => {
const assignment = row.original;
return (
<div className="space-y-1 py-1">
<p className="font-medium">{assignment.title}</p>
<div className="text-muted-foreground flex items-center gap-4 text-sm">
<span>Total Marks: {assignment.total_mark}</span>
<span>Pass Marks: {assignment.pass_mark}</span>
<span>Gesamtpunktzahl: {assignment.total_mark}</span>
<span>Bestehenspunktzahl: {assignment.pass_mark}</span>
</div>
</div>
);
@ -53,7 +53,7 @@ export const AssignmentColumns: ColumnDef<CourseAssignment>[] = [
},
{
accessorKey: 'deadline',
header: 'Deadline',
header: 'Frist',
cell: ({ row }) => {
const assignment = row.original;
const deadlinePassed = isDeadlinePassed(assignment.deadline);
@ -68,7 +68,7 @@ export const AssignmentColumns: ColumnDef<CourseAssignment>[] = [
},
{
accessorKey: 'marks_obtained',
header: () => <div className="text-center">Obtained Marks</div>,
header: () => <div className="text-center">Erhaltene Punkte</div>,
cell: ({ row }) => {
const assignment = row.original;
const hasSubmission = assignment.submissions && assignment.submissions.length > 0;
@ -87,11 +87,11 @@ export const AssignmentColumns: ColumnDef<CourseAssignment>[] = [
<p className="font-semibold">
{latestSubmission?.marks_obtained} / {totalMarks}
</p>
{isLate && <p className="text-muted-foreground text-xs">(Late: Max {latestSubmission?.assignment?.late_total_mark})</p>}
{isLate && <p className="text-muted-foreground text-xs">(Verspätet: Max {latestSubmission?.assignment?.late_total_mark})</p>}
</div>
) : (
<div>
<p className="text-muted-foreground text-sm">Not Graded</p>
<p className="text-muted-foreground text-sm">Nicht bewertet</p>
<p className="text-muted-foreground text-xs">Max: {totalMarks}</p>
</div>
)}
@ -115,7 +115,7 @@ export const AssignmentColumns: ColumnDef<CourseAssignment>[] = [
},
{
id: 'actions',
header: () => <div className="text-right">Action</div>,
header: () => <div className="text-right">Aktion</div>,
cell: ({ row }) => {
const assignment = row.original;

View File

@ -21,12 +21,12 @@ const QuizIcon = ({ quiz, latestSubmission }: { quiz: SectionQuiz; latestSubmiss
return (
<div className="flex items-center gap-3">
{/* Quiz Icon */}
{/* Quiz-Symbol */}
<div className="bg-primary/10 flex h-12 w-12 items-center justify-center rounded-lg">
<ClipboardList className="text-primary h-6 w-6" />
</div>
{/* Quiz Info */}
{/* Quiz-Info */}
<div className="flex-1">
<div className="flex items-center gap-2">
<p className="text-primary text-base font-medium">{quiz.title}</p>
@ -37,7 +37,7 @@ const QuizIcon = ({ quiz, latestSubmission }: { quiz: SectionQuiz; latestSubmiss
)}
{!hasAttempted && (
<Badge variant="destructive" className="text-xs">
Not Submitted
Nicht eingereicht
</Badge>
)}
</div>
@ -90,15 +90,15 @@ const QuizStatus = ({ quiz, completed }: Props) => {
<QuizResultDialog quiz={quiz} submission={latestSubmission} />
) : (
<Button size="sm" asChild>
<Link
href={route('course.player', {
type: 'quiz',
watch_history: watchHistory.id,
lesson_id: quiz.id,
})}
>
{'Take Quiz'}
</Link>
<Link
href={route('course.player', {
type: 'quiz',
watch_history: watchHistory.id,
lesson_id: quiz.id,
})}
>
Quiz starten
</Link>
</Button>
)}
</div>
@ -112,7 +112,7 @@ const QuizStatus = ({ quiz, completed }: Props) => {
</div>
<div className="flex items-center gap-3">
{/* Marks Display */}
{/* Punkteanzeige */}
{hasAttempted && (
<div className="text-right">
<p className="text-sm font-medium text-gray-500">

View File

@ -25,7 +25,7 @@ const CourseQuizzes = () => {
section.section_quizzes.map((quiz) => <QuizStatus key={quiz.id} quiz={quiz} completed={completed} />)
) : (
<div className="px-4 py-3 text-center">
<p>There is no quiz added</p>
<p>Kein Quiz vorhanden</p>
</div>
)}
</AccordionContent>
@ -35,7 +35,7 @@ const CourseQuizzes = () => {
</Accordion>
) : (
<div className="p-6 text-center">
<p>There is no quiz added</p>
<p>Kein Quiz vorhanden</p>
</div>
)}
</>

View File

@ -10,21 +10,21 @@ const CourseResources = () => {
const { props } = usePage<StudentCourseProps>();
const { resources } = props;
// Function to format date in Bengali style if needed
// Funktion zum Formatieren von Datum/Uhrzeit (bei Bedarf auf Deutsch)
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return format(date, 'MMMM dd, yyyy, hh:mm a');
};
// Helper to handle file download
// Helferfunktion zum Herunterladen von Dateien
const handleDownload = async (resource: LessonResource, e: React.MouseEvent) => {
e.preventDefault();
try {
// For non-link resources, use the download endpoint
// Für nicht-verlinkte Ressourcen den Download-Endpunkt verwenden
const url = route('resources.download', resource.id);
window.open(url, '_blank');
} catch (error) {
// Fallback to direct download if the endpoint fails
// Fallback: Direktes Öffnen/Herunterladen, falls der Endpunkt fehlschlägt
window.open(resource.resource, '_blank');
}
};
@ -34,12 +34,12 @@ const CourseResources = () => {
{resources && resources.length > 0 ? (
resources.map((section, sectionIndex) => (
<Card key={section.id}>
{/* Module Header */}
{/* Modul-Überschrift */}
<div className="bg-muted rounded-t-lg px-4 py-3">
<h3 className="text-lg font-semibold">Module: {section.title}</h3>
<h3 className="text-lg font-semibold">Modul: {section.title}</h3>
</div>
{/* Lessons Table */}
{/* Lektionen-Tabelle */}
<div className="space-y-4 p-4">
{section.section_lessons && section.section_lessons.length > 0 ? (
section.section_lessons.map((lesson) =>
@ -48,7 +48,7 @@ const CourseResources = () => {
{/* Lesson Title */}
<div className="p-4">
<p className="text-base font-medium">
<span className="font-semibold">Lesson:</span> {lesson.title}
<span className="font-semibold">Lektion:</span> {lesson.title}
</p>
</div>
@ -57,9 +57,9 @@ const CourseResources = () => {
<Table>
<TableHeader className="bg-muted/50">
<TableRow>
<TableHead className="px-4 font-semibold">Title</TableHead>
<TableHead className="px-4 font-semibold">Date & Time</TableHead>
<TableHead className="px-4 text-right font-semibold">Action</TableHead>
<TableHead className="px-4 font-semibold">Titel</TableHead>
<TableHead className="px-4 font-semibold">Datum & Uhrzeit</TableHead>
<TableHead className="px-4 text-right font-semibold">Aktion</TableHead>
</TableRow>
</TableHeader>
<TableBody>
@ -73,13 +73,13 @@ const CourseResources = () => {
<Button asChild size="sm" variant="secondary">
<a target="_blank" href={resource.resource}>
<ExternalLink className="h-3 w-3" />
Check
Ansehen
</a>
</Button>
) : (
<Button size="sm" variant="secondary" onClick={(e) => handleDownload(resource, e)}>
<Download className="h-3 w-3" />
Download
Herunterladen
</Button>
)}
</div>
@ -93,14 +93,14 @@ const CourseResources = () => {
) : null,
)
) : (
<div className="text-muted-foreground py-8 text-center">No lessons found in this module.</div>
<div className="text-muted-foreground py-8 text-center">Keine Lektionen in diesem Modul gefunden.</div>
)}
</div>
</Card>
))
) : (
<div className="py-12 text-center">
<p className="text-muted-foreground text-lg">No resources available for this course yet.</p>
<p className="text-muted-foreground text-lg">Für diesen Kurs sind noch keine Ressourcen verfügbar.</p>
</div>
)}
</div>

View File

@ -25,7 +25,7 @@ const Quizzes = () => {
section.section_quizzes.map((quiz) => <QuizStatus key={quiz.id} quiz={quiz} completed={completed} />)
) : (
<div className="px-4 py-3 text-center">
<p>There is no quiz added</p>
<p>Kein Quiz vorhanden</p>
</div>
)}
</AccordionContent>
@ -35,7 +35,7 @@ const Quizzes = () => {
</Accordion>
) : (
<div className="p-6 text-center">
<p>There is no quiz added</p>
<p>Kein Quiz vorhanden</p>
</div>
)}
</>

View File

@ -10,21 +10,21 @@ const Resources = () => {
const { props } = usePage<StudentCourseProps>();
const { resources } = props;
// Function to format date in Bengali style if needed
// Funktion zum Formatieren von Datum/Uhrzeit (bei Bedarf auf Deutsch)
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return format(date, 'MMMM dd, yyyy, hh:mm a');
};
// Helper to handle file download
// Helferfunktion zum Herunterladen von Dateien
const handleDownload = async (resource: LessonResource, e: React.MouseEvent) => {
e.preventDefault();
try {
// For non-link resources, use the download endpoint
// Für nicht-verlinkte Ressourcen den Download-Endpunkt verwenden
const url = route('resources.download', resource.id);
window.open(url, '_blank');
} catch (error) {
// Fallback to direct download if the endpoint fails
// Fallback: Direktes Öffnen/Herunterladen, falls der Endpunkt fehlschlägt
window.open(resource.resource, '_blank');
}
};
@ -34,12 +34,12 @@ const Resources = () => {
{resources && resources.length > 0 ? (
resources.map((section, sectionIndex) => (
<Card key={section.id}>
{/* Module Header */}
{/* Modul-Überschrift */}
<div className="bg-muted rounded-t-lg px-4 py-3">
<h3 className="text-lg font-semibold">Module: {section.title}</h3>
<h3 className="text-lg font-semibold">Modul: {section.title}</h3>
</div>
{/* Lessons Table */}
{/* Lektionen-Tabelle */}
<div className="space-y-4 p-4">
{section.section_lessons && section.section_lessons.length > 0 ? (
section.section_lessons.map((lesson) =>
@ -48,7 +48,7 @@ const Resources = () => {
{/* Lesson Title */}
<div className="p-4">
<p className="text-base font-medium">
<span className="font-semibold">Lesson:</span> {lesson.title}
<span className="font-semibold">Lektion:</span> {lesson.title}
</p>
</div>
@ -57,9 +57,9 @@ const Resources = () => {
<Table>
<TableHeader className="bg-muted/50">
<TableRow>
<TableHead className="px-4 font-semibold">Title</TableHead>
<TableHead className="px-4 font-semibold">Date & Time</TableHead>
<TableHead className="px-4 text-right font-semibold">Action</TableHead>
<TableHead className="px-4 font-semibold">Titel</TableHead>
<TableHead className="px-4 font-semibold">Datum & Uhrzeit</TableHead>
<TableHead className="px-4 text-right font-semibold">Aktion</TableHead>
</TableRow>
</TableHeader>
<TableBody>
@ -73,13 +73,13 @@ const Resources = () => {
<Button asChild size="sm" variant="secondary">
<a target="_blank" href={resource.resource}>
<ExternalLink className="h-3 w-3" />
Check
Ansehen
</a>
</Button>
) : (
<Button size="sm" variant="secondary" onClick={(e) => handleDownload(resource, e)}>
<Download className="h-3 w-3" />
Download
Herunterladen
</Button>
)}
</div>
@ -93,14 +93,14 @@ const Resources = () => {
) : null,
)
) : (
<div className="text-muted-foreground py-8 text-center">No lessons found in this module.</div>
<div className="text-muted-foreground py-8 text-center">Keine Lektionen in diesem Modul gefunden.</div>
)}
</div>
</Card>
))
) : (
<div className="py-12 text-center">
<p className="text-muted-foreground text-lg">No resources available for this course yet.</p>
<p className="text-muted-foreground text-lg">Für diesen Kurs sind noch keine Ressourcen verfügbar.</p>
</div>
)}
</div>