style: apply prettier formatting to all files
All checks were successful
Build and Push Backend Image / build (push) Successful in 46s
Build and Push Frontend Image / build (push) Successful in 5m12s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-04 22:27:54 +01:00
parent 18116072c9
commit efc7624ba3
184 changed files with 10327 additions and 10220 deletions

View File

@@ -1,180 +1,163 @@
<script lang="ts">
import { _ } from "svelte-i18n";
import { Card, CardContent, CardHeader } from "$lib/components/ui/card";
import { Button } from "$lib/components/ui/button";
import type { Recording } from "$lib/types";
import { cn } from "$lib/utils";
import { _ } from "svelte-i18n";
import { Card, CardContent, CardHeader } from "$lib/components/ui/card";
import { Button } from "$lib/components/ui/button";
import type { Recording } from "$lib/types";
import { cn } from "$lib/utils";
interface Props {
recording: Recording;
onPlay?: (id: string) => void;
onDelete?: (id: string) => void;
}
interface Props {
recording: Recording;
onPlay?: (id: string) => void;
onDelete?: (id: string) => void;
}
let { recording, onPlay, onDelete }: Props = $props();
let { recording, onPlay, onDelete }: Props = $props();
function formatDuration(ms: number): string {
const totalSeconds = Math.floor(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}
function formatDuration(ms: number): string {
const totalSeconds = Math.floor(ms / 1000);
const minutes = Math.floor(totalSeconds / 60);
const seconds = totalSeconds % 60;
return `${minutes}:${seconds.toString().padStart(2, "0")}`;
}
function getStatusColor(status: string): string {
switch (status) {
case "published":
return "text-green-400 bg-green-400/20";
case "draft":
return "text-yellow-400 bg-yellow-400/20";
case "archived":
return "text-red-400 bg-red-400/20";
default:
return "text-gray-400 bg-gray-400/20";
}
}
function getStatusColor(status: string): string {
switch (status) {
case "published":
return "text-green-400 bg-green-400/20";
case "draft":
return "text-yellow-400 bg-yellow-400/20";
case "archived":
return "text-red-400 bg-red-400/20";
default:
return "text-gray-400 bg-gray-400/20";
}
}
</script>
<Card
class="group hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 border-border/50 hover:border-primary/30 bg-card/50 backdrop-blur-sm"
class="group hover:shadow-lg hover:shadow-primary/10 transition-all duration-300 border-border/50 hover:border-primary/30 bg-card/50 backdrop-blur-sm"
>
<CardHeader class="pb-3">
<div class="flex items-start justify-between">
<div class="flex-1">
<div class="flex items-center gap-2 mb-2">
<h3
class="font-semibold text-card-foreground group-hover:text-primary transition-colors"
>
{recording.title}
</h3>
<span
class={cn(
"text-xs px-2 py-0.5 rounded-full",
getStatusColor(recording.status),
)}
>
{$_(`recording_card.status_${recording.status}`)}
</span>
</div>
{#if recording.description}
<p class="text-sm text-muted-foreground line-clamp-2">
{recording.description}
</p>
{/if}
</div>
</div>
</CardHeader>
<CardHeader class="pb-3">
<div class="flex items-start justify-between">
<div class="flex-1">
<div class="flex items-center gap-2 mb-2">
<h3 class="font-semibold text-card-foreground group-hover:text-primary transition-colors">
{recording.title}
</h3>
<span class={cn("text-xs px-2 py-0.5 rounded-full", getStatusColor(recording.status))}>
{$_(`recording_card.status_${recording.status}`)}
</span>
</div>
{#if recording.description}
<p class="text-sm text-muted-foreground line-clamp-2">
{recording.description}
</p>
{/if}
</div>
</div>
</CardHeader>
<CardContent class="space-y-4">
<!-- Stats Grid -->
<div class="grid grid-cols-3 gap-3">
<div
class="flex flex-col items-center p-3 rounded-lg bg-muted/30 border border-border/30"
>
<span class="icon-[ri--time-line] w-4 h-4 text-primary mb-1"></span>
<span class="text-xs text-muted-foreground"
>{$_("recording_card.duration")}</span
>
<span class="font-medium text-sm">{formatDuration(recording.duration)}</span>
</div>
<div
class="flex flex-col items-center p-3 rounded-lg bg-muted/30 border border-border/30"
>
<span class="icon-[ri--pulse-line] w-4 h-4 text-accent mb-1"></span>
<span class="text-xs text-muted-foreground">{$_("recording_card.events")}</span>
<span class="font-medium text-sm">{recording.events.length}</span>
</div>
<div
class="flex flex-col items-center p-3 rounded-lg bg-muted/30 border border-border/30"
>
<span class="icon-[ri--gamepad-line] w-4 h-4 text-primary mb-1"></span>
<span class="text-xs text-muted-foreground">{$_("recording_card.devices")}</span>
<span class="font-medium text-sm">{recording.device_info.length}</span>
</div>
</div>
<CardContent class="space-y-4">
<!-- Stats Grid -->
<div class="grid grid-cols-3 gap-3">
<div class="flex flex-col items-center p-3 rounded-lg bg-muted/30 border border-border/30">
<span class="icon-[ri--time-line] w-4 h-4 text-primary mb-1"></span>
<span class="text-xs text-muted-foreground">{$_("recording_card.duration")}</span>
<span class="font-medium text-sm">{formatDuration(recording.duration)}</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg bg-muted/30 border border-border/30">
<span class="icon-[ri--pulse-line] w-4 h-4 text-accent mb-1"></span>
<span class="text-xs text-muted-foreground">{$_("recording_card.events")}</span>
<span class="font-medium text-sm">{recording.events.length}</span>
</div>
<div class="flex flex-col items-center p-3 rounded-lg bg-muted/30 border border-border/30">
<span class="icon-[ri--gamepad-line] w-4 h-4 text-primary mb-1"></span>
<span class="text-xs text-muted-foreground">{$_("recording_card.devices")}</span>
<span class="font-medium text-sm">{recording.device_info.length}</span>
</div>
</div>
<!-- Device Info -->
<div class="space-y-1">
{#each recording.device_info.slice(0, 2) as device (device.name)}
<div
class="flex items-center gap-2 text-xs text-muted-foreground bg-muted/20 rounded px-2 py-1"
>
<span class="icon-[ri--rocket-line] w-3 h-3"></span>
<span>{device.name}</span>
<span class="text-xs opacity-60">{device.capabilities.join(", ")}</span>
</div>
{/each}
{#if recording.device_info.length > 2}
<div class="text-xs text-muted-foreground/60 px-2">
+{recording.device_info.length - 2} more device{recording.device_info.length -
2 >
1
? "s"
: ""}
</div>
{/if}
</div>
<!-- Device Info -->
<div class="space-y-1">
{#each recording.device_info.slice(0, 2) as device (device.name)}
<div
class="flex items-center gap-2 text-xs text-muted-foreground bg-muted/20 rounded px-2 py-1"
>
<span class="icon-[ri--rocket-line] w-3 h-3"></span>
<span>{device.name}</span>
<span class="text-xs opacity-60">{device.capabilities.join(", ")}</span>
</div>
{/each}
{#if recording.device_info.length > 2}
<div class="text-xs text-muted-foreground/60 px-2">
+{recording.device_info.length - 2} more device{recording.device_info.length - 2 > 1
? "s"
: ""}
</div>
{/if}
</div>
<!-- Tags -->
{#if recording.tags && recording.tags.length > 0}
<div class="flex flex-wrap gap-1">
{#each recording.tags as tag (tag)}
<span
class="text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary border border-primary/20"
>
{tag}
</span>
{/each}
</div>
{/if}
<!-- Tags -->
{#if recording.tags && recording.tags.length > 0}
<div class="flex flex-wrap gap-1">
{#each recording.tags as tag (tag)}
<span
class="text-xs px-2 py-0.5 rounded-full bg-primary/10 text-primary border border-primary/20"
>
{tag}
</span>
{/each}
</div>
{/if}
<!-- Metadata -->
<div class="flex items-center justify-between text-xs text-muted-foreground pt-2">
<div class="flex items-center gap-3">
<span>
{new Date(recording.date_created).toLocaleDateString()}
</span>
{#if recording.public}
<span class="flex items-center gap-1">
<span class="icon-[ri--global-line] w-3 h-3"></span>
{$_("recording_card.public")}
</span>
{:else}
<span class="flex items-center gap-1">
<span class="icon-[ri--lock-line] w-3 h-3"></span>
{$_("recording_card.private")}
</span>
{/if}
</div>
{#if recording.linked_video}
<span class="flex items-center gap-1 text-accent">
<span class="icon-[ri--video-line] w-3 h-3"></span>
{$_("recording_card.linked_video")}
</span>
{/if}
</div>
<!-- Metadata -->
<div class="flex items-center justify-between text-xs text-muted-foreground pt-2">
<div class="flex items-center gap-3">
<span>
{new Date(recording.date_created).toLocaleDateString()}
</span>
{#if recording.public}
<span class="flex items-center gap-1">
<span class="icon-[ri--global-line] w-3 h-3"></span>
{$_("recording_card.public")}
</span>
{:else}
<span class="flex items-center gap-1">
<span class="icon-[ri--lock-line] w-3 h-3"></span>
{$_("recording_card.private")}
</span>
{/if}
</div>
{#if recording.linked_video}
<span class="flex items-center gap-1 text-accent">
<span class="icon-[ri--video-line] w-3 h-3"></span>
{$_("recording_card.linked_video")}
</span>
{/if}
</div>
<!-- Actions -->
<div class="flex gap-2 pt-2">
{#if onPlay}
<Button
size="sm"
onclick={() => onPlay?.(recording.id)}
class="flex-1 cursor-pointer bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
<span class="icon-[ri--play-fill] w-4 h-4 mr-1"></span>
{$_("recording_card.play")}
</Button>
{/if}
{#if onDelete}
<Button
size="sm"
variant="outline"
onclick={() => onDelete?.(recording.id)}
class="cursor-pointer border-destructive/20 hover:bg-destructive/10 hover:text-destructive"
>
<span class="icon-[ri--delete-bin-line] w-4 h-4"></span>
</Button>
{/if}
</div>
</CardContent>
<!-- Actions -->
<div class="flex gap-2 pt-2">
{#if onPlay}
<Button
size="sm"
onclick={() => onPlay?.(recording.id)}
class="flex-1 cursor-pointer bg-gradient-to-r from-primary to-accent hover:from-primary/90 hover:to-accent/90"
>
<span class="icon-[ri--play-fill] w-4 h-4 mr-1"></span>
{$_("recording_card.play")}
</Button>
{/if}
{#if onDelete}
<Button
size="sm"
variant="outline"
onclick={() => onDelete?.(recording.id)}
class="cursor-pointer border-destructive/20 hover:bg-destructive/10 hover:text-destructive"
>
<span class="icon-[ri--delete-bin-line] w-4 h-4"></span>
</Button>
{/if}
</div>
</CardContent>
</Card>