feat: migrate frontend React 18 → Svelte 5 + SvelteKit
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 22s
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 22s
Core logic portable (economy, balance, cosmetics, migrateSave) — zero rewrite. 136 tests green, identiques. Backend inchangé. - Svelte 5 runes stores (game, auth, toast) remplacent Zustand - SvelteKit adapter-static SPA (dist/ output, fallback index.html) - Tailwind v4 conservé, design system .gp-* porté - Transitions natives : slide, fly, scale, fade sur toute l'UI - Sidebar tabbée (Production/Evolution/Collection) + CollapsiblePanel - Mobile bottom sheet avec FAB toggle + backdrop blur - Click particles réactifs Svelte (plus de DOM impératif) - TadpoleSprite bounce + glow ring au clic - Guide refait en accordéon, Achievements avec filtres - a11y : focus-visible, Escape modals, aria-current, aria-labels - CI/CD adapté (tests + build + rsync) - Build 504K (vs ~1.2MB React)
This commit is contained in:
54
Frontend/src/routes/login/+page.svelte
Normal file
54
Frontend/src/routes/login/+page.svelte
Normal file
@@ -0,0 +1,54 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { fly, scale } from 'svelte/transition';
|
||||
import { quintOut, backOut } from 'svelte/easing';
|
||||
import { authStore } from '$lib/stores/auth.svelte';
|
||||
import { buildAuthUrl, saveVerifier } from '$lib/oauth';
|
||||
|
||||
const PROVIDERS = [
|
||||
{ id: 'discord', label: 'Discord', emoji: '🎮', color: '#5865F2' },
|
||||
{ id: 'github', label: 'GitHub', emoji: '🐙', color: '#333' },
|
||||
{ id: 'google', label: 'Google', emoji: '🌐', color: '#4285f4' },
|
||||
{ id: 'twitch', label: 'Twitch', emoji: '🎬', color: '#9146FF' },
|
||||
];
|
||||
|
||||
$effect(() => {
|
||||
if (authStore.user) goto('/', { replaceState: true });
|
||||
});
|
||||
|
||||
async function handleLogin(provider: string) {
|
||||
const redirectUri = `${window.location.origin}/callback`;
|
||||
const { url, verifier } = await buildAuthUrl(redirectUri, provider);
|
||||
saveVerifier(verifier);
|
||||
window.location.href = url;
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Connexion — Clickerz</title>
|
||||
</svelte:head>
|
||||
|
||||
<section>
|
||||
<div class="containererror">
|
||||
<div in:scale={{ duration: 400, start: 0.7, easing: backOut }}>
|
||||
<img src="/svg/tadpole.svg" alt="" class="w-24 h-24 mx-auto mb-2 opacity-60" />
|
||||
</div>
|
||||
<h1 in:fly={{ y: 20, delay: 100, duration: 400, easing: quintOut }}>Connexion</h1>
|
||||
<p class="message" in:fly={{ y: 15, delay: 200, duration: 400, easing: quintOut }}>
|
||||
Connecte-toi pour sauvegarder ta progression.
|
||||
</p>
|
||||
<div class="flex flex-col gap-3 mt-6 w-full max-w-xs mx-auto">
|
||||
{#each PROVIDERS as p, i}
|
||||
<button
|
||||
class="btn-return flex items-center justify-center gap-2 py-3! text-base!"
|
||||
onclick={() => handleLogin(p.id)}
|
||||
type="button"
|
||||
in:fly={{ y: 20, delay: 300 + i * 80, duration: 300, easing: quintOut }}
|
||||
>
|
||||
<span class="text-xl">{p.emoji}</span>
|
||||
Continuer avec {p.label}
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
Reference in New Issue
Block a user