<script setup lang="ts">
import { ref } from "vue";
import { useRouter } from "vue-router";
import { useI18n } from "vue-i18n";
import { GnButton, GnInput, GnCard, useToast } from "gnexus-ui-kit/vue";
import { useAuth } from "../stores/auth";
const auth = useAuth();
const router = useRouter();
const toast = useToast();
const { t } = useI18n();
const nickname = ref("");
const email = ref("");
const password = ref("");
const submitting = ref(false);
const error = ref<string | null>(null);
async function submit() {
submitting.value = true;
error.value = null;
try {
await auth.register(nickname.value, email.value, password.value);
await router.push("/");
toast.success({ title: t("auth.registerTitle"), text: `Welcome, ${auth.user.value?.nickname}` });
} catch (e) {
error.value = e instanceof Error && e.message.includes("409")
? "This email is already registered"
: t("auth.error");
} finally {
submitting.value = false;
}
}
</script>
<template>
<div class="auth-page">
<GnCard class="register-card">
<h1 class="register-title">{{ t("auth.registerTitle") }}</h1>
<form class="register-form" @submit.prevent="submit">
<GnInput v-model="nickname" :label="t('auth.nickname')" icon="ph-user" required />
<GnInput v-model="email" :label="t('auth.email')" icon="ph-envelope" type="email" required />
<GnInput
v-model="password"
:label="t('auth.password')"
icon="ph-key"
type="password"
help="At least 8 characters"
required
/>
<p v-if="error" class="register-error">{{ error }}</p>
<GnButton type="submit" variant="accent" :loading="submitting" icon="ph-user-plus">
{{ t("auth.registerSubmit") }}
</GnButton>
</form>
</GnCard>
<p class="auth-page-alt">
{{ t("auth.haveAccount") }}
<RouterLink to="/login">
<GnButton variant="secondary" size="sm">{{ t("nav.login") }}</GnButton>
</RouterLink>
</p>
</div>
</template>
<style scoped>
.auth-page {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16px;
padding: 24px;
}
.register-card {
width: min(420px, 100%);
padding: 24px;
}
.register-title {
margin: 0 0 16px;
font-size: 18px;
}
.register-form {
display: flex;
flex-direction: column;
gap: 14px;
align-items: flex-start;
}
.register-form > :deep(*) {
width: 100%;
}
.register-error {
color: var(--color-error, #f7768e);
font-size: 12px;
margin: 0;
}
.auth-page-alt {
display: flex;
align-items: center;
gap: 10px;
font-size: 13px;
opacity: 0.8;
}
.auth-page-alt a {
text-decoration: none;
}
</style>