Our Personal Data Server from scratch!
tranquil.farm
oauth
atproto
pds
rust
postgresql
objectstorage
fun
1<script lang="ts">
2 import { _ } from '../lib/i18n'
3 import { getFullUrl } from '../lib/router.svelte'
4 import { routes } from '../lib/types/routes'
5
6 interface Props {
7 active: 'passkey' | 'password' | 'sso'
8 ssoAvailable?: boolean
9 oauthRequestUri?: string | null
10 }
11
12 let { active, ssoAvailable = true, oauthRequestUri = null }: Props = $props()
13
14 function buildOauthUrl(route: string): string {
15 const url = getFullUrl(route)
16 return oauthRequestUri ? `${url}?request_uri=${encodeURIComponent(oauthRequestUri)}` : url
17 }
18
19 const passkeyUrl = $derived(buildOauthUrl(routes.oauthRegister))
20 const passwordUrl = $derived(buildOauthUrl(routes.oauthRegisterPassword))
21 const ssoUrl = $derived(buildOauthUrl(routes.oauthRegisterSso))
22</script>
23
24<div class="account-type-switcher">
25 <a href={passkeyUrl} class="switcher-option" class:active={active === 'passkey'}>
26 {$_('register.passkeyAccount')}
27 </a>
28 <a href={passwordUrl} class="switcher-option" class:active={active === 'password'}>
29 {$_('register.passwordAccount')}
30 </a>
31 {#if ssoAvailable || active === 'sso'}
32 <a href={ssoUrl} class="switcher-option" class:active={active === 'sso'}>
33 {$_('register.ssoAccount')}
34 </a>
35 {:else}
36 <span class="switcher-option disabled">
37 {$_('register.ssoAccount')}
38 </span>
39 {/if}
40</div>
41
42<style>
43 .account-type-switcher {
44 display: flex;
45 gap: var(--space-2);
46 padding: var(--space-1);
47 background: var(--bg-secondary);
48 border-radius: var(--radius-lg);
49 margin-bottom: var(--space-6);
50 }
51
52 .switcher-option {
53 flex: 1;
54 display: flex;
55 align-items: center;
56 justify-content: center;
57 gap: var(--space-2);
58 padding: var(--space-3) var(--space-4);
59 border-radius: var(--radius-md);
60 text-decoration: none;
61 color: var(--text-secondary);
62 font-weight: var(--font-medium);
63 transition: all 0.15s ease;
64 }
65
66 .switcher-option:hover {
67 color: var(--text-primary);
68 background: var(--bg-tertiary);
69 }
70
71 .switcher-option.active {
72 background: var(--bg-primary);
73 color: var(--text-primary);
74 box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
75 }
76
77 .switcher-option.disabled {
78 opacity: 0.4;
79 cursor: not-allowed;
80 }
81
82 .switcher-option.disabled:hover {
83 color: var(--text-secondary);
84 background: transparent;
85 }
86</style>