Replace custom gqlFetch() with proper Apollo useQuery/useMutation hooks powered by codegen-generated TypedDocumentNode types. Key changes: - Add GraphQL SDL schema file and codegen config for typescript-vue-apollo - Replace all 28 raw .graphql imports with generated typed documents - Add 12 useQuery() hooks with cache-and-network fetch policy - Add 17 useMutation() hooks with surgical refetchQueries per mutation - Optimistic cache update for setContactInboxHidden (instant archive UX) - Fix contact list subtitle: show lastText instead of channel name - Migrate login page from gqlFetch to useMutation - WebSocket realtime now calls Apollo refetch instead of full data reload Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
40 lines
1.0 KiB
Vue
40 lines
1.0 KiB
Vue
<script setup lang="ts">
|
|
import CrmAuthLoginForm from "~~/app/components/workspace/auth/CrmAuthLoginForm.vue";
|
|
import { useMutation } from "@vue/apollo-composable";
|
|
import { LoginMutationDocument } from "~~/graphql/generated";
|
|
|
|
const phone = ref("");
|
|
const password = ref("");
|
|
const error = ref<string | null>(null);
|
|
const busy = ref(false);
|
|
|
|
const { mutate: doLogin } = useMutation(LoginMutationDocument);
|
|
|
|
async function submit() {
|
|
error.value = null;
|
|
busy.value = true;
|
|
try {
|
|
await doLogin({ 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>
|