@voyantjs/crm-react 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +36 -0
  2. package/dist/client.d.ts +31 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +71 -0
  5. package/dist/hooks/index.d.ts +7 -0
  6. package/dist/hooks/index.d.ts.map +1 -0
  7. package/dist/hooks/index.js +6 -0
  8. package/dist/hooks/use-activities.d.ts +23 -0
  9. package/dist/hooks/use-activities.d.ts.map +1 -0
  10. package/dist/hooks/use-activities.js +38 -0
  11. package/dist/hooks/use-activity-mutation.d.ts +69 -0
  12. package/dist/hooks/use-activity-mutation.d.ts.map +1 -0
  13. package/dist/hooks/use-activity-mutation.js +60 -0
  14. package/dist/hooks/use-activity.d.ts +25 -0
  15. package/dist/hooks/use-activity.d.ts.map +1 -0
  16. package/dist/hooks/use-activity.js +34 -0
  17. package/dist/hooks/use-opportunities.d.ts +35 -0
  18. package/dist/hooks/use-opportunities.d.ts.map +1 -0
  19. package/dist/hooks/use-opportunities.js +41 -0
  20. package/dist/hooks/use-opportunity-mutation.d.ts +69 -0
  21. package/dist/hooks/use-opportunity-mutation.d.ts.map +1 -0
  22. package/dist/hooks/use-opportunity-mutation.js +41 -0
  23. package/dist/hooks/use-opportunity.d.ts +25 -0
  24. package/dist/hooks/use-opportunity.d.ts.map +1 -0
  25. package/dist/hooks/use-opportunity.js +20 -0
  26. package/dist/hooks/use-organization-mutation.d.ts +59 -0
  27. package/dist/hooks/use-organization-mutation.d.ts.map +1 -0
  28. package/dist/hooks/use-organization-mutation.js +41 -0
  29. package/dist/hooks/use-organization.d.ts +23 -0
  30. package/dist/hooks/use-organization.d.ts.map +1 -0
  31. package/dist/hooks/use-organization.js +20 -0
  32. package/dist/hooks/use-organizations.d.ts +29 -0
  33. package/dist/hooks/use-organizations.d.ts.map +1 -0
  34. package/dist/hooks/use-organizations.js +31 -0
  35. package/dist/hooks/use-people.d.ts +40 -0
  36. package/dist/hooks/use-people.d.ts.map +1 -0
  37. package/dist/hooks/use-people.js +41 -0
  38. package/dist/hooks/use-person-mutation.d.ts +82 -0
  39. package/dist/hooks/use-person-mutation.d.ts.map +1 -0
  40. package/dist/hooks/use-person-mutation.js +46 -0
  41. package/dist/hooks/use-person.d.ts +34 -0
  42. package/dist/hooks/use-person.d.ts.map +1 -0
  43. package/dist/hooks/use-person.js +28 -0
  44. package/dist/hooks/use-pipeline-mutation.d.ts +76 -0
  45. package/dist/hooks/use-pipeline-mutation.d.ts.map +1 -0
  46. package/dist/hooks/use-pipeline-mutation.js +76 -0
  47. package/dist/hooks/use-pipelines.d.ts +31 -0
  48. package/dist/hooks/use-pipelines.d.ts.map +1 -0
  49. package/dist/hooks/use-pipelines.js +42 -0
  50. package/dist/hooks/use-quote-mutation.d.ts +99 -0
  51. package/dist/hooks/use-quote-mutation.d.ts.map +1 -0
  52. package/dist/hooks/use-quote-mutation.js +70 -0
  53. package/dist/hooks/use-quote.d.ts +31 -0
  54. package/dist/hooks/use-quote.d.ts.map +1 -0
  55. package/dist/hooks/use-quote.js +37 -0
  56. package/dist/hooks/use-quotes.d.ts +24 -0
  57. package/dist/hooks/use-quotes.d.ts.map +1 -0
  58. package/dist/hooks/use-quotes.js +30 -0
  59. package/dist/hooks/use-stages.d.ts +37 -0
  60. package/dist/hooks/use-stages.d.ts.map +1 -0
  61. package/dist/hooks/use-stages.js +45 -0
  62. package/dist/index.d.ts +23 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +22 -0
  65. package/dist/provider.d.ts +39 -0
  66. package/dist/provider.d.ts.map +1 -0
  67. package/dist/provider.js +32 -0
  68. package/dist/query-keys.d.ts +85 -0
  69. package/dist/query-keys.d.ts.map +1 -0
  70. package/dist/query-keys.js +30 -0
  71. package/dist/schemas.d.ts +501 -0
  72. package/dist/schemas.d.ts.map +1 -0
  73. package/dist/schemas.js +179 -0
  74. package/package.json +75 -0
package/README.md ADDED
@@ -0,0 +1,36 @@
1
+ # @voyantjs/crm-react
2
+
3
+ React runtime package for Voyant CRM. Provides the shared `VoyantProvider`, typed fetch client, query keys, and TanStack Query hooks that power CRM-focused frontend experiences.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @voyantjs/crm-react @voyantjs/crm @tanstack/react-query react react-dom zod
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```tsx
14
+ import { VoyantProvider, usePeople } from "@voyantjs/crm-react"
15
+
16
+ function App() {
17
+ return (
18
+ <VoyantProvider baseUrl="/api">
19
+ <PeopleList />
20
+ </VoyantProvider>
21
+ )
22
+ }
23
+
24
+ function PeopleList() {
25
+ const { data } = usePeople()
26
+ return <>{data?.items.map((person) => <div key={person.id}>{person.firstName}</div>)}</>
27
+ }
28
+ ```
29
+
30
+ ## Relationship To The Registry
31
+
32
+ `@voyantjs/crm-react` is the runtime layer. Installable CRM UI blocks should come from the Voyant shadcn registry and depend on this package for hooks, client state, and provider wiring.
33
+
34
+ ## License
35
+
36
+ FSL-1.1-Apache-2.0
@@ -0,0 +1,31 @@
1
+ import type { z } from "zod";
2
+ /**
3
+ * Fetcher signature — compatible with the Fetch API, `cross-fetch`, or any
4
+ * custom wrapper. Consumers may pass their own to bake in authentication,
5
+ * tracing, or base URL rewriting.
6
+ */
7
+ export type VoyantFetcher = (url: string, init?: RequestInit) => Promise<Response>;
8
+ /**
9
+ * Default fetcher — uses the global `fetch` with `credentials: "include"` so
10
+ * session cookies are sent for same-origin deployments.
11
+ */
12
+ export declare const defaultFetcher: VoyantFetcher;
13
+ /**
14
+ * Typed error thrown by `fetchWithValidation` when the API returns a non-2xx
15
+ * response or when the body fails Zod validation.
16
+ */
17
+ export declare class VoyantApiError extends Error {
18
+ readonly status: number;
19
+ readonly body: unknown;
20
+ constructor(message: string, status: number, body: unknown);
21
+ }
22
+ export interface FetchWithValidationOptions {
23
+ baseUrl: string;
24
+ fetcher: VoyantFetcher;
25
+ }
26
+ /**
27
+ * Wraps a fetcher call, reads the JSON response, and validates it against a
28
+ * Zod schema. Throws `VoyantApiError` on transport, status, or parse failures.
29
+ */
30
+ export declare function fetchWithValidation<TOut>(path: string, schema: z.ZodType<TOut>, options: FetchWithValidationOptions, init?: RequestInit): Promise<TOut>;
31
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAE5B;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;AAElF;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,aACoB,CAAA;AAEjD;;;GAGG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;gBAEV,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO;CAM3D;AAaD,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,aAAa,CAAA;CACvB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAC5C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EACvB,OAAO,EAAE,0BAA0B,EACnC,IAAI,CAAC,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
package/dist/client.js ADDED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Default fetcher — uses the global `fetch` with `credentials: "include"` so
3
+ * session cookies are sent for same-origin deployments.
4
+ */
5
+ export const defaultFetcher = (url, init) => fetch(url, { credentials: "include", ...init });
6
+ /**
7
+ * Typed error thrown by `fetchWithValidation` when the API returns a non-2xx
8
+ * response or when the body fails Zod validation.
9
+ */
10
+ export class VoyantApiError extends Error {
11
+ status;
12
+ body;
13
+ constructor(message, status, body) {
14
+ super(message);
15
+ this.name = "VoyantApiError";
16
+ this.status = status;
17
+ this.body = body;
18
+ }
19
+ }
20
+ function extractErrorMessage(status, statusText, body) {
21
+ if (typeof body === "object" && body !== null && "error" in body) {
22
+ const err = body.error;
23
+ if (typeof err === "string")
24
+ return err;
25
+ if (typeof err === "object" && err !== null && "message" in err) {
26
+ return String(err.message);
27
+ }
28
+ }
29
+ return `Voyant API error: ${status} ${statusText}`;
30
+ }
31
+ /**
32
+ * Wraps a fetcher call, reads the JSON response, and validates it against a
33
+ * Zod schema. Throws `VoyantApiError` on transport, status, or parse failures.
34
+ */
35
+ export async function fetchWithValidation(path, schema, options, init) {
36
+ const url = joinUrl(options.baseUrl, path);
37
+ const headers = new Headers(init?.headers);
38
+ if (init?.body !== undefined && !headers.has("Content-Type")) {
39
+ headers.set("Content-Type", "application/json");
40
+ }
41
+ const response = await options.fetcher(url, { ...init, headers });
42
+ if (!response.ok) {
43
+ const body = await safeJson(response);
44
+ throw new VoyantApiError(extractErrorMessage(response.status, response.statusText, body), response.status, body);
45
+ }
46
+ if (response.status === 204) {
47
+ return schema.parse(undefined);
48
+ }
49
+ const body = await safeJson(response);
50
+ const parsed = schema.safeParse(body);
51
+ if (!parsed.success) {
52
+ throw new VoyantApiError(`Voyant API response failed validation: ${parsed.error.message}`, response.status, body);
53
+ }
54
+ return parsed.data;
55
+ }
56
+ async function safeJson(response) {
57
+ const text = await response.text();
58
+ if (!text)
59
+ return undefined;
60
+ try {
61
+ return JSON.parse(text);
62
+ }
63
+ catch {
64
+ return text;
65
+ }
66
+ }
67
+ function joinUrl(baseUrl, path) {
68
+ const trimmedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
69
+ const trimmedPath = path.startsWith("/") ? path : `/${path}`;
70
+ return `${trimmedBase}${trimmedPath}`;
71
+ }
@@ -0,0 +1,7 @@
1
+ export { useOrganization } from "./use-organization.js";
2
+ export { type CreateOrganizationInput, type UpdateOrganizationInput, useOrganizationMutation, } from "./use-organization-mutation.js";
3
+ export { type UseOrganizationsOptions, useOrganizations } from "./use-organizations.js";
4
+ export { type UsePeopleOptions, usePeople } from "./use-people.js";
5
+ export { type UsePersonOptions, usePerson } from "./use-person.js";
6
+ export { type CreatePersonInput, type UpdatePersonInput, usePersonMutation, } from "./use-person-mutation.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,uBAAuB,GACxB,MAAM,gCAAgC,CAAA;AACvC,OAAO,EAAE,KAAK,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACvF,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EAAE,KAAK,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAClE,OAAO,EACL,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,iBAAiB,GAClB,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,6 @@
1
+ export { useOrganization } from "./use-organization.js";
2
+ export { useOrganizationMutation, } from "./use-organization-mutation.js";
3
+ export { useOrganizations } from "./use-organizations.js";
4
+ export { usePeople } from "./use-people.js";
5
+ export { usePerson } from "./use-person.js";
6
+ export { usePersonMutation, } from "./use-person-mutation.js";
@@ -0,0 +1,23 @@
1
+ import { type ActivitiesListFilters } from "../query-keys.js";
2
+ export interface UseActivitiesOptions extends ActivitiesListFilters {
3
+ enabled?: boolean;
4
+ }
5
+ export declare function useActivities(options?: UseActivitiesOptions): import("@tanstack/react-query").UseQueryResult<{
6
+ data: {
7
+ id: string;
8
+ subject: string;
9
+ type: string;
10
+ ownerId: string | null;
11
+ status: string;
12
+ dueAt: string | null;
13
+ completedAt: string | null;
14
+ location: string | null;
15
+ description: string | null;
16
+ createdAt: string;
17
+ updatedAt: string;
18
+ }[];
19
+ total: number;
20
+ limit: number;
21
+ offset: number;
22
+ }, Error>;
23
+ //# sourceMappingURL=use-activities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-activities.d.ts","sourceRoot":"","sources":["../../src/hooks/use-activities.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,qBAAqB,EAAgB,MAAM,kBAAkB,CAAA;AAG3E,MAAM,WAAW,oBAAqB,SAAQ,qBAAqB;IACjE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB;;;;;;;;;;;;;;;;;UAwB/D"}
@@ -0,0 +1,38 @@
1
+ "use client";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { fetchWithValidation } from "../client.js";
4
+ import { useVoyantContext } from "../provider.js";
5
+ import { crmQueryKeys } from "../query-keys.js";
6
+ import { activityListResponse } from "../schemas.js";
7
+ export function useActivities(options = {}) {
8
+ const { baseUrl, fetcher } = useVoyantContext();
9
+ const { enabled = true, ...filters } = options;
10
+ return useQuery({
11
+ queryKey: crmQueryKeys.activitiesList(filters),
12
+ queryFn: () => {
13
+ const params = new URLSearchParams();
14
+ if (filters.search)
15
+ params.set("search", filters.search);
16
+ if (filters.ownerId)
17
+ params.set("ownerId", filters.ownerId);
18
+ if (filters.status)
19
+ params.set("status", filters.status);
20
+ if (filters.type)
21
+ params.set("type", filters.type);
22
+ if (filters.entityType)
23
+ params.set("entityType", filters.entityType);
24
+ if (filters.entityId)
25
+ params.set("entityId", filters.entityId);
26
+ if (filters.limit !== undefined)
27
+ params.set("limit", String(filters.limit));
28
+ if (filters.offset !== undefined)
29
+ params.set("offset", String(filters.offset));
30
+ const qs = params.toString();
31
+ return fetchWithValidation(`/v1/crm/activities${qs ? `?${qs}` : ""}`, activityListResponse, {
32
+ baseUrl,
33
+ fetcher,
34
+ });
35
+ },
36
+ enabled,
37
+ });
38
+ }
@@ -0,0 +1,69 @@
1
+ export interface CreateActivityInput {
2
+ subject: string;
3
+ type: string;
4
+ ownerId?: string | null;
5
+ status?: string;
6
+ dueAt?: string | null;
7
+ completedAt?: string | null;
8
+ location?: string | null;
9
+ description?: string | null;
10
+ [key: string]: unknown;
11
+ }
12
+ export type UpdateActivityInput = Partial<CreateActivityInput>;
13
+ export interface CreateActivityLinkInput {
14
+ entityType: string;
15
+ entityId: string;
16
+ role?: string;
17
+ }
18
+ export declare function useActivityMutation(): {
19
+ create: import("@tanstack/react-query").UseMutationResult<{
20
+ id: string;
21
+ subject: string;
22
+ type: string;
23
+ ownerId: string | null;
24
+ status: string;
25
+ dueAt: string | null;
26
+ completedAt: string | null;
27
+ location: string | null;
28
+ description: string | null;
29
+ createdAt: string;
30
+ updatedAt: string;
31
+ }, Error, CreateActivityInput, unknown>;
32
+ update: import("@tanstack/react-query").UseMutationResult<{
33
+ id: string;
34
+ subject: string;
35
+ type: string;
36
+ ownerId: string | null;
37
+ status: string;
38
+ dueAt: string | null;
39
+ completedAt: string | null;
40
+ location: string | null;
41
+ description: string | null;
42
+ createdAt: string;
43
+ updatedAt: string;
44
+ }, Error, {
45
+ id: string;
46
+ input: UpdateActivityInput;
47
+ }, unknown>;
48
+ remove: import("@tanstack/react-query").UseMutationResult<{
49
+ success: boolean;
50
+ }, Error, string, unknown>;
51
+ addLink: import("@tanstack/react-query").UseMutationResult<{
52
+ id: string;
53
+ activityId: string;
54
+ entityType: string;
55
+ entityId: string;
56
+ role: string;
57
+ createdAt: string;
58
+ }, Error, {
59
+ activityId: string;
60
+ input: CreateActivityLinkInput;
61
+ }, unknown>;
62
+ removeLink: import("@tanstack/react-query").UseMutationResult<{
63
+ success: boolean;
64
+ }, Error, {
65
+ activityId: string;
66
+ linkId: string;
67
+ }, unknown>;
68
+ };
69
+ //# sourceMappingURL=use-activity-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-activity-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-activity-mutation.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAE9D,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAID,wBAAgB,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;YAoBS,MAAM;eAAS,mBAAmB;;;;;;;;;;;;;oBAmC5D,MAAM;eACX,uBAAuB;;;;;oBAqBlB,MAAM;gBACV,MAAM;;EAgBnB"}
@@ -0,0 +1,60 @@
1
+ "use client";
2
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
3
+ import { z } from "zod";
4
+ import { fetchWithValidation } from "../client.js";
5
+ import { useVoyantContext } from "../provider.js";
6
+ import { crmQueryKeys } from "../query-keys.js";
7
+ import { activityLinkSingleResponse, activitySingleResponse } from "../schemas.js";
8
+ const deleteResponseSchema = z.object({ success: z.boolean() });
9
+ export function useActivityMutation() {
10
+ const { baseUrl, fetcher } = useVoyantContext();
11
+ const queryClient = useQueryClient();
12
+ const create = useMutation({
13
+ mutationFn: async (input) => {
14
+ const { data } = await fetchWithValidation("/v1/crm/activities", activitySingleResponse, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify(input) });
15
+ return data;
16
+ },
17
+ onSuccess: () => {
18
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activities() });
19
+ },
20
+ });
21
+ const update = useMutation({
22
+ mutationFn: async ({ id, input }) => {
23
+ const { data } = await fetchWithValidation(`/v1/crm/activities/${id}`, activitySingleResponse, { baseUrl, fetcher }, { method: "PATCH", body: JSON.stringify(input) });
24
+ return data;
25
+ },
26
+ onSuccess: (data) => {
27
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activities() });
28
+ queryClient.setQueryData(crmQueryKeys.activity(data.id), data);
29
+ },
30
+ });
31
+ const remove = useMutation({
32
+ mutationFn: async (id) => {
33
+ return fetchWithValidation(`/v1/crm/activities/${id}`, deleteResponseSchema, { baseUrl, fetcher }, { method: "DELETE" });
34
+ },
35
+ onSuccess: (_data, id) => {
36
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activities() });
37
+ queryClient.removeQueries({ queryKey: crmQueryKeys.activity(id) });
38
+ },
39
+ });
40
+ const addLink = useMutation({
41
+ mutationFn: async ({ activityId, input, }) => {
42
+ const { data } = await fetchWithValidation(`/v1/crm/activities/${activityId}/links`, activityLinkSingleResponse, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify(input) });
43
+ return data;
44
+ },
45
+ onSuccess: (_data, vars) => {
46
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activityLinks(vars.activityId) });
47
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activities() });
48
+ },
49
+ });
50
+ const removeLink = useMutation({
51
+ mutationFn: async ({ activityId: _activityId, linkId, }) => {
52
+ return fetchWithValidation(`/v1/crm/activity-links/${linkId}`, deleteResponseSchema, { baseUrl, fetcher }, { method: "DELETE" });
53
+ },
54
+ onSuccess: (_data, vars) => {
55
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activityLinks(vars.activityId) });
56
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.activities() });
57
+ },
58
+ });
59
+ return { create, update, remove, addLink, removeLink };
60
+ }
@@ -0,0 +1,25 @@
1
+ export interface UseActivityOptions {
2
+ enabled?: boolean;
3
+ }
4
+ export declare function useActivity(id: string | undefined, options?: UseActivityOptions): import("@tanstack/react-query").UseQueryResult<{
5
+ id: string;
6
+ subject: string;
7
+ type: string;
8
+ ownerId: string | null;
9
+ status: string;
10
+ dueAt: string | null;
11
+ completedAt: string | null;
12
+ location: string | null;
13
+ description: string | null;
14
+ createdAt: string;
15
+ updatedAt: string;
16
+ }, Error>;
17
+ export declare function useActivityLinks(activityId: string | undefined, options?: UseActivityOptions): import("@tanstack/react-query").UseQueryResult<{
18
+ id: string;
19
+ activityId: string;
20
+ entityType: string;
21
+ entityId: string;
22
+ role: string;
23
+ createdAt: string;
24
+ }[], Error>;
25
+ //# sourceMappingURL=use-activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-activity.d.ts","sourceRoot":"","sources":["../../src/hooks/use-activity.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,kBAAuB;;;;;;;;;;;;UAiBnF;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,kBAAuB;;;;;;;YAiBhG"}
@@ -0,0 +1,34 @@
1
+ "use client";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { fetchWithValidation } from "../client.js";
4
+ import { useVoyantContext } from "../provider.js";
5
+ import { crmQueryKeys } from "../query-keys.js";
6
+ import { activityLinkListResponse, activitySingleResponse } from "../schemas.js";
7
+ export function useActivity(id, options = {}) {
8
+ const { baseUrl, fetcher } = useVoyantContext();
9
+ const { enabled = true } = options;
10
+ return useQuery({
11
+ queryKey: crmQueryKeys.activity(id ?? ""),
12
+ queryFn: async () => {
13
+ if (!id)
14
+ throw new Error("useActivity requires an id");
15
+ const { data } = await fetchWithValidation(`/v1/crm/activities/${id}`, activitySingleResponse, { baseUrl, fetcher });
16
+ return data;
17
+ },
18
+ enabled: enabled && Boolean(id),
19
+ });
20
+ }
21
+ export function useActivityLinks(activityId, options = {}) {
22
+ const { baseUrl, fetcher } = useVoyantContext();
23
+ const { enabled = true } = options;
24
+ return useQuery({
25
+ queryKey: crmQueryKeys.activityLinks(activityId ?? ""),
26
+ queryFn: async () => {
27
+ if (!activityId)
28
+ throw new Error("useActivityLinks requires an activityId");
29
+ const { data } = await fetchWithValidation(`/v1/crm/activities/${activityId}/links`, activityLinkListResponse, { baseUrl, fetcher });
30
+ return data;
31
+ },
32
+ enabled: enabled && Boolean(activityId),
33
+ });
34
+ }
@@ -0,0 +1,35 @@
1
+ import { type OpportunitiesListFilters } from "../query-keys.js";
2
+ export interface UseOpportunitiesOptions extends OpportunitiesListFilters {
3
+ enabled?: boolean;
4
+ }
5
+ /**
6
+ * Lists opportunities with filters + pagination. Returns the raw
7
+ * `{ data, total, limit, offset }` envelope.
8
+ */
9
+ export declare function useOpportunities(options?: UseOpportunitiesOptions): import("@tanstack/react-query").UseQueryResult<{
10
+ data: {
11
+ id: string;
12
+ title: string;
13
+ personId: string | null;
14
+ organizationId: string | null;
15
+ pipelineId: string;
16
+ stageId: string;
17
+ ownerId: string | null;
18
+ status: string;
19
+ valueAmountCents: number | null;
20
+ valueCurrency: string | null;
21
+ expectedCloseDate: string | null;
22
+ source: string | null;
23
+ sourceRef: string | null;
24
+ lostReason: string | null;
25
+ tags: string[];
26
+ createdAt: string;
27
+ updatedAt: string;
28
+ stageChangedAt: string;
29
+ closedAt: string | null;
30
+ }[];
31
+ total: number;
32
+ limit: number;
33
+ offset: number;
34
+ }, Error>;
35
+ //# sourceMappingURL=use-opportunities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-opportunities.d.ts","sourceRoot":"","sources":["../../src/hooks/use-opportunities.ts"],"names":[],"mappings":"AAMA,OAAO,EAAgB,KAAK,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAG9E,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B;;;;;;;;;;;;;;;;;;;;;;;;;UA0BrE"}
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { fetchWithValidation } from "../client.js";
4
+ import { useVoyantContext } from "../provider.js";
5
+ import { crmQueryKeys } from "../query-keys.js";
6
+ import { opportunityListResponse } from "../schemas.js";
7
+ /**
8
+ * Lists opportunities with filters + pagination. Returns the raw
9
+ * `{ data, total, limit, offset }` envelope.
10
+ */
11
+ export function useOpportunities(options = {}) {
12
+ const { baseUrl, fetcher } = useVoyantContext();
13
+ const { enabled = true, ...filters } = options;
14
+ return useQuery({
15
+ queryKey: crmQueryKeys.opportunitiesList(filters),
16
+ queryFn: () => {
17
+ const params = new URLSearchParams();
18
+ if (filters.search)
19
+ params.set("search", filters.search);
20
+ if (filters.personId)
21
+ params.set("personId", filters.personId);
22
+ if (filters.organizationId)
23
+ params.set("organizationId", filters.organizationId);
24
+ if (filters.pipelineId)
25
+ params.set("pipelineId", filters.pipelineId);
26
+ if (filters.stageId)
27
+ params.set("stageId", filters.stageId);
28
+ if (filters.ownerId)
29
+ params.set("ownerId", filters.ownerId);
30
+ if (filters.status)
31
+ params.set("status", filters.status);
32
+ if (filters.limit !== undefined)
33
+ params.set("limit", String(filters.limit));
34
+ if (filters.offset !== undefined)
35
+ params.set("offset", String(filters.offset));
36
+ const qs = params.toString();
37
+ return fetchWithValidation(`/v1/crm/opportunities${qs ? `?${qs}` : ""}`, opportunityListResponse, { baseUrl, fetcher });
38
+ },
39
+ enabled,
40
+ });
41
+ }
@@ -0,0 +1,69 @@
1
+ export interface CreateOpportunityInput {
2
+ title: string;
3
+ pipelineId: string;
4
+ stageId: string;
5
+ personId?: string | null;
6
+ organizationId?: string | null;
7
+ ownerId?: string | null;
8
+ status?: string;
9
+ valueAmountCents?: number | null;
10
+ valueCurrency?: string | null;
11
+ expectedCloseDate?: string | null;
12
+ source?: string | null;
13
+ sourceRef?: string | null;
14
+ lostReason?: string | null;
15
+ tags?: string[];
16
+ [key: string]: unknown;
17
+ }
18
+ export type UpdateOpportunityInput = Partial<CreateOpportunityInput>;
19
+ export declare function useOpportunityMutation(): {
20
+ create: import("@tanstack/react-query").UseMutationResult<{
21
+ id: string;
22
+ title: string;
23
+ personId: string | null;
24
+ organizationId: string | null;
25
+ pipelineId: string;
26
+ stageId: string;
27
+ ownerId: string | null;
28
+ status: string;
29
+ valueAmountCents: number | null;
30
+ valueCurrency: string | null;
31
+ expectedCloseDate: string | null;
32
+ source: string | null;
33
+ sourceRef: string | null;
34
+ lostReason: string | null;
35
+ tags: string[];
36
+ createdAt: string;
37
+ updatedAt: string;
38
+ stageChangedAt: string;
39
+ closedAt: string | null;
40
+ }, Error, CreateOpportunityInput, unknown>;
41
+ update: import("@tanstack/react-query").UseMutationResult<{
42
+ id: string;
43
+ title: string;
44
+ personId: string | null;
45
+ organizationId: string | null;
46
+ pipelineId: string;
47
+ stageId: string;
48
+ ownerId: string | null;
49
+ status: string;
50
+ valueAmountCents: number | null;
51
+ valueCurrency: string | null;
52
+ expectedCloseDate: string | null;
53
+ source: string | null;
54
+ sourceRef: string | null;
55
+ lostReason: string | null;
56
+ tags: string[];
57
+ createdAt: string;
58
+ updatedAt: string;
59
+ stageChangedAt: string;
60
+ closedAt: string | null;
61
+ }, Error, {
62
+ id: string;
63
+ input: UpdateOpportunityInput;
64
+ }, unknown>;
65
+ remove: import("@tanstack/react-query").UseMutationResult<{
66
+ success: boolean;
67
+ }, Error, string, unknown>;
68
+ };
69
+ //# sourceMappingURL=use-opportunity-mutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-opportunity-mutation.d.ts","sourceRoot":"","sources":["../../src/hooks/use-opportunity-mutation.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAA;AAIpE,wBAAgB,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YAoBM,MAAM;eAAS,sBAAsB;;;;;EA+BhF"}
@@ -0,0 +1,41 @@
1
+ "use client";
2
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
3
+ import { z } from "zod";
4
+ import { fetchWithValidation } from "../client.js";
5
+ import { useVoyantContext } from "../provider.js";
6
+ import { crmQueryKeys } from "../query-keys.js";
7
+ import { opportunitySingleResponse } from "../schemas.js";
8
+ const deleteResponseSchema = z.object({ success: z.boolean() });
9
+ export function useOpportunityMutation() {
10
+ const { baseUrl, fetcher } = useVoyantContext();
11
+ const queryClient = useQueryClient();
12
+ const create = useMutation({
13
+ mutationFn: async (input) => {
14
+ const { data } = await fetchWithValidation("/v1/crm/opportunities", opportunitySingleResponse, { baseUrl, fetcher }, { method: "POST", body: JSON.stringify(input) });
15
+ return data;
16
+ },
17
+ onSuccess: () => {
18
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.opportunities() });
19
+ },
20
+ });
21
+ const update = useMutation({
22
+ mutationFn: async ({ id, input }) => {
23
+ const { data } = await fetchWithValidation(`/v1/crm/opportunities/${id}`, opportunitySingleResponse, { baseUrl, fetcher }, { method: "PATCH", body: JSON.stringify(input) });
24
+ return data;
25
+ },
26
+ onSuccess: (data) => {
27
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.opportunities() });
28
+ queryClient.setQueryData(crmQueryKeys.opportunity(data.id), data);
29
+ },
30
+ });
31
+ const remove = useMutation({
32
+ mutationFn: async (id) => {
33
+ return fetchWithValidation(`/v1/crm/opportunities/${id}`, deleteResponseSchema, { baseUrl, fetcher }, { method: "DELETE" });
34
+ },
35
+ onSuccess: (_data, id) => {
36
+ void queryClient.invalidateQueries({ queryKey: crmQueryKeys.opportunities() });
37
+ queryClient.removeQueries({ queryKey: crmQueryKeys.opportunity(id) });
38
+ },
39
+ });
40
+ return { create, update, remove };
41
+ }
@@ -0,0 +1,25 @@
1
+ export interface UseOpportunityOptions {
2
+ enabled?: boolean;
3
+ }
4
+ export declare function useOpportunity(id: string | undefined, options?: UseOpportunityOptions): import("@tanstack/react-query").UseQueryResult<{
5
+ id: string;
6
+ title: string;
7
+ personId: string | null;
8
+ organizationId: string | null;
9
+ pipelineId: string;
10
+ stageId: string;
11
+ ownerId: string | null;
12
+ status: string;
13
+ valueAmountCents: number | null;
14
+ valueCurrency: string | null;
15
+ expectedCloseDate: string | null;
16
+ source: string | null;
17
+ sourceRef: string | null;
18
+ lostReason: string | null;
19
+ tags: string[];
20
+ createdAt: string;
21
+ updatedAt: string;
22
+ stageChangedAt: string;
23
+ closedAt: string | null;
24
+ }, Error>;
25
+ //# sourceMappingURL=use-opportunity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-opportunity.d.ts","sourceRoot":"","sources":["../../src/hooks/use-opportunity.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,GAAE,qBAA0B;;;;;;;;;;;;;;;;;;;;UAiBzF"}