Add trust center v2

Signed-off-by: Jonathan <contact@grafikart.fr>
This commit is contained in:
Jonathan
2025-09-26 16:42:52 +02:00
committed by Sacha Al Himdani
parent 44898be9d3
commit 55e85e5f67
182 changed files with 4609 additions and 425 deletions

View File

@@ -0,0 +1,19 @@
import { useEffect, useRef } from "react";
/**
* Hook to handle cleanup after a delay
*
* Used for disposing the graphQL query when the component unmounts
*/
export function useCleanup(callback: () => void, delay: number) {
const timer = useRef<ReturnType<typeof setTimeout>>(null);
useEffect(() => {
if (timer.current) {
clearTimeout(timer.current);
}
return () => {
timer.current = setTimeout(callback, delay);
};
}, [callback, delay]);
}

View File

@@ -0,0 +1,13 @@
import { useForm } from "react-hook-form";
import type { z, ZodTypeAny } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
export function useFormWithSchema<T extends ZodTypeAny>(
schema: T,
options: Parameters<typeof useForm<z.infer<T>>>[0],
) {
return useForm<z.infer<T>>({
...options,
resolver: zodResolver(schema),
});
}

View File

@@ -0,0 +1,6 @@
import { useContext } from "react";
import { AuthContext } from "/providers/AuthProvider";
export function useIsAuthenticated(): boolean {
return useContext(AuthContext).isAuthenticated;
}

View File

@@ -0,0 +1,63 @@
import { useCallback } from "react";
import { useMutation, type UseMutationConfig } from "react-relay";
import { useToast } from "@probo/ui";
import { useTranslate } from "@probo/i18n";
import type { MutationParameters, GraphQLTaggedNode } from "relay-runtime";
/**
* A decorated useMutation hook that emits toast notifications on success or error.
*/
export function useMutationWithToasts<T extends MutationParameters>(
query: GraphQLTaggedNode,
baseOptions?: {
onSuccess?: (response: T["response"]) => void;
errorMessage?: string;
}
) {
const [mutate, isLoading] = useMutation<T>(query);
const { toast } = useToast();
const { __ } = useTranslate();
const mutateWithToast = useCallback(
(
queryOptions: UseMutationConfig<T> & {
onSuccess?: (response: T["response"]) => void;
errorMessage?: string;
}
) => {
const options = { ...baseOptions, ...queryOptions };
return new Promise<void>((resolve, reject) =>
mutate({
...queryOptions,
onCompleted: (response, error) => {
options.onCompleted?.(response, error);
if (error) {
toast({
title: __("Error"),
description:
options.errorMessage ??
__("Failed to commit this operation."),
variant: "error",
});
reject(error);
return;
}
options.onSuccess?.(response);
resolve();
},
onError: (error) => {
toast({
title: __("Error"),
description:
options.errorMessage ?? __("Failed to commit this operation."),
variant: "error",
});
reject(error);
},
})
);
},
[mutate]
);
return [mutateWithToast, isLoading] as const;
}

View File

@@ -0,0 +1,13 @@
import { TrustCenterContext } from "/providers/TrustCenterProvider";
import { useContext } from "react";
export function useTrustCenter(): {
id: string;
organization: { name: string };
} {
const context = useContext(TrustCenterContext);
if (!context) {
throw new Error("useTrustCenter must be used within a TrustCenterProvider");
}
return context;
}