59 lines
1.5 KiB
Vue
59 lines
1.5 KiB
Vue
<script setup lang="ts">
|
|
import CrmAuthLoginForm from "~~/app/components/workspace/auth/CrmAuthLoginForm.vue";
|
|
import loginMutation from "~~/graphql/operations/login.graphql?raw";
|
|
|
|
const phone = ref("");
|
|
const password = ref("");
|
|
const error = ref<string | null>(null);
|
|
const busy = ref(false);
|
|
|
|
async function gqlFetch<TData>(query: string, variables?: Record<string, unknown>) {
|
|
const headers = process.server ? useRequestHeaders(["cookie"]) : undefined;
|
|
const result = await $fetch<{ data?: TData; errors?: Array<{ message: string }> }>("/api/graphql", {
|
|
method: "POST",
|
|
headers,
|
|
body: { query, variables },
|
|
});
|
|
|
|
if (result.errors?.length) {
|
|
throw new Error(result.errors[0]?.message || "GraphQL request failed");
|
|
}
|
|
|
|
if (!result.data) {
|
|
throw new Error("GraphQL returned empty payload");
|
|
}
|
|
|
|
return result.data;
|
|
}
|
|
|
|
async function submit() {
|
|
error.value = null;
|
|
busy.value = true;
|
|
try {
|
|
await gqlFetch<{ login: { ok: boolean } }>(loginMutation, {
|
|
phone: phone.value,
|
|
password: password.value,
|
|
});
|
|
await navigateTo("/", { replace: true });
|
|
} catch (e: any) {
|
|
error.value = e?.data?.message || e?.message || "Login failed";
|
|
} finally {
|
|
busy.value = false;
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="h-[100dvh] overflow-hidden bg-base-200/35">
|
|
<CrmAuthLoginForm
|
|
:phone="phone"
|
|
:password="password"
|
|
:error="error"
|
|
:busy="busy"
|
|
@update:phone="phone = $event"
|
|
@update:password="password = $event"
|
|
@submit="submit"
|
|
/>
|
|
</div>
|
|
</template>
|