refactor: migrate CRM data layer from manual gqlFetch to Apollo Client
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>
This commit is contained in:
@@ -1,39 +1,20 @@
|
||||
<script setup lang="ts">
|
||||
import CrmAuthLoginForm from "~~/app/components/workspace/auth/CrmAuthLoginForm.vue";
|
||||
import loginMutation from "~~/graphql/operations/login.graphql?raw";
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
const { mutate: doLogin } = useMutation(LoginMutationDocument);
|
||||
|
||||
async function submit() {
|
||||
error.value = null;
|
||||
busy.value = true;
|
||||
try {
|
||||
await gqlFetch<{ login: { ok: boolean } }>(loginMutation, {
|
||||
phone: phone.value,
|
||||
password: password.value,
|
||||
});
|
||||
await doLogin({ phone: phone.value, password: password.value });
|
||||
await navigateTo("/", { replace: true });
|
||||
} catch (e: any) {
|
||||
error.value = e?.data?.message || e?.message || "Login failed";
|
||||
|
||||
Reference in New Issue
Block a user