feat: Ladeanzeige als Mountainbike-Laufrad
Stollenreifen, Felge, gekreuzte Speichen, Nabe — gezeichnet in currentColor und groessengesteuert wie ein Lucide-Icon, damit es den LoaderCircle ueberall ersetzen kann. Das Ventil sitzt bewusst nur an einer Stelle: Ohne diese Unwucht sieht ein achtfach symmetrisches Rad im Stillstand aus, egal wie schnell es sich dreht. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P32KoesVtABd6xWsqMKzhr
This commit is contained in:
parent
7ac5e9ab4f
commit
69588528e8
3 changed files with 43 additions and 4 deletions
39
frontend/src/lib/components/Spinner.svelte
Normal file
39
frontend/src/lib/components/Spinner.svelte
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<script lang="ts">
|
||||
/**
|
||||
* Ladeanzeige als Mountainbike-Laufrad: Stollenreifen, Felge, gekreuzte
|
||||
* Speichen, Nabe. Das Ventil sitzt bewusst nur an einer Stelle — ohne diese
|
||||
* Unwucht sieht ein achtfach symmetrisches Rad im Stillstand aus, egal wie
|
||||
* schnell es sich dreht.
|
||||
*
|
||||
* Zeichnet in `currentColor` und richtet sich nach der uebergebenen
|
||||
* Groessenklasse, laesst sich also wie ein Lucide-Icon einsetzen.
|
||||
*/
|
||||
let { class: className = 'size-6' }: { class?: string } = $props()
|
||||
</script>
|
||||
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="animate-spin {className}"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<!-- Stollen: 14 Segmente auf dem Umfang 2πr = 60.95, also je 4.35 breit -->
|
||||
<circle cx="12" cy="12" r="9.7" stroke-dasharray="1.7 2.654" stroke-width="2.6" />
|
||||
<!-- Reifen -->
|
||||
<circle cx="12" cy="12" r="9.4" stroke-width="1.8" />
|
||||
<!-- Felge -->
|
||||
<circle cx="12" cy="12" r="7.3" stroke-width="1.1" />
|
||||
<!-- Speichen, gekreuzt gespannt wie an einem echten Laufrad -->
|
||||
<path
|
||||
d="M12.88 10.2L12 4.7M12.65 10.11L17.16 6.84M13.8 12.88L19.3 12M13.89 12.65L17.16 17.16M11.12 13.8L12 19.3M11.35 13.89L6.84 17.16M10.2 11.12L4.7 12M10.11 11.35L6.84 6.84"
|
||||
opacity=".5"
|
||||
stroke-linecap="round"
|
||||
stroke-width=".8"
|
||||
/>
|
||||
<!-- Nabe -->
|
||||
<circle cx="12" cy="12" fill="currentColor" r="1.9" stroke="none" />
|
||||
<!-- Ventil -->
|
||||
<path d="M12 8.4L12 6.6" stroke-linecap="round" stroke-width="1.3" />
|
||||
</svg>
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
import {auth} from '$lib/stores/pocketbase.svelte'
|
||||
import {goto} from '$app/navigation'
|
||||
import {onMount} from 'svelte'
|
||||
import {LoaderCircle} from 'lucide-svelte'
|
||||
import Spinner from '$lib/components/Spinner.svelte'
|
||||
|
||||
onMount(() => {
|
||||
goto(auth.user ? '/dashboard' : '/login', {replaceState: true})
|
||||
|
|
@ -10,5 +10,5 @@
|
|||
</script>
|
||||
|
||||
<div class="min-h-screen flex items-center justify-center">
|
||||
<LoaderCircle class="animate-spin" size="64"/>
|
||||
<Spinner class="size-16"/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
import { Card, CardContent, CardDescription, CardHeader } from '@/components/ui/card'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Label } from '@/components/ui/label'
|
||||
import { LoaderCircle } from 'lucide-svelte'
|
||||
import Spinner from '$lib/components/Spinner.svelte'
|
||||
import Logo from '$lib/components/Logo.svelte'
|
||||
|
||||
let email = $state('')
|
||||
|
|
@ -82,7 +82,7 @@
|
|||
|
||||
<Button type="submit" class="w-full" disabled={submitting}>
|
||||
{#if submitting}
|
||||
<LoaderCircle class="h-4 w-4 mr-2 animate-spin" />
|
||||
<Spinner class="mr-2 size-4" />
|
||||
Wird angemeldet…
|
||||
{:else}
|
||||
Anmelden
|
||||
|
|
|
|||
Loading…
Reference in a new issue