linky-svelte/src/routes/login/username/+page.svelte
2024-05-11 23:01:04 +03:00

107 lines
No EOL
3.2 KiB
Svelte

<script lang="ts">
import AuthCheck from "../../../lib/components/AuthCheck.svelte";
import { db, user, userData } from "$lib/firebase";
import { doc, getDoc, writeBatch} from "firebase/firestore";
let username = "";
let loading = false;
let isAvailable = false;
let isLowercase = false;
let debounceTimer: NodeJS.Timeout;
const re = /^(?=[a-zA-Z0-9._]{3,16}$)(?!.*[_.]{2})[^_.].*[^_.]$/;
$: isValid = username.length > 3 && username.length < 16 && re.test(username);
$: isTouched = username.length > 0;
$: isTaken = isValid && !isAvailable && !loading
async function checkAvailability() {
isAvailable = false;
clearTimeout(debounceTimer);
if (username = username.toLowerCase())
isLowercase
loading = true;
debounceTimer = setTimeout(async () => {
console.log("checking availability of", username);
const ref = doc(db, "usernames", username);
const exists = await getDoc(ref).then((doc) => doc.exists());
isAvailable = !exists;
loading = false;
}, 500);
}
async function confirmUsername() {
console.log("confirming username", username);
const batch = writeBatch(db);
batch.set(doc(db, "usernames", username.toLowerCase()), { uid: $user?.uid });
batch.set(doc(db, "users", $user!.uid), {
username,
photoURL: $user?.photoURL ?? null,
published: true,
bio: 'Bio',
});
await batch.commit();
username = '';
isAvailable = false;
}
</script>
<AuthCheck>
{#if $userData?.username}
<p class="text-lg">
Your Username is <span class="text-xl text-success font-bold">@{$userData.username}</span>
</p>
<p class=" text-sm">Username cannot be changed</p>
<a class="btn btn-primary" href="/login/photo">UPLOAD PROFILE IMAGE</a>
{:else}
<h2>Username</h2>
<form class="w-2/5 lowercase" on:submit|preventDefault={confirmUsername}>
<input
type="text"
placeholder="Username"
draggable="true"
class="input w-full"
bind:value={username}
on:input={checkAvailability}
class:input-error={(!isValid && isTouched)}
class:input-warning={isTaken}
class:input-success={isAvailable && isValid && !loading}
/>
<div class="my-4 min-h-16 px-8 w-full">
{#if loading}
<p class="text-secondary">Checking availability of @{username}...</p>
{/if}
{#if !isValid && isTouched}
<p class="text-error text-sm">
must be 3-16 characters long, alphanumeric only
</p>
{/if}
{#if isValid && !isAvailable && !loading}
<p class="text-warning text-sm">
@{username} is not available
</p>
{/if}
{#if isLowercase}
<p class="text-error text-sm">must be lowercase</p>
{/if}
{#if isAvailable && isValid && !isLowercase}
<button class="btn btn-success lowercase">Confirm username @{username} </button>
{/if}
</div>
</form>
{/if}
</AuthCheck>