mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-24 16:26:32 +02:00
Some checks are pending
Build and Push Docker Images / tag_release (push) Waiting to run
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_backend, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64) (push) Blocked by required conditions
Build and Push Docker Images / build (./surfsense_web, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (backend, surfsense-backend) (push) Blocked by required conditions
Build and Push Docker Images / create_manifest (web, surfsense-web) (push) Blocked by required conditions
84 lines
2.2 KiB
TypeScript
84 lines
2.2 KiB
TypeScript
"use client";
|
|
|
|
import Link from "next/link";
|
|
import { createContext, type ReactNode, useCallback, useContext, useState } from "react";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogDescription,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
} from "@/components/ui/dialog";
|
|
import { useIsAnonymous } from "./anonymous-mode";
|
|
|
|
interface LoginGateContextValue {
|
|
gate: (feature: string) => void;
|
|
}
|
|
|
|
const LoginGateContext = createContext<LoginGateContextValue>({
|
|
gate: () => {},
|
|
});
|
|
|
|
export function LoginGateProvider({ children }: { children: ReactNode }) {
|
|
const isAnonymous = useIsAnonymous();
|
|
const [feature, setFeature] = useState<string | null>(null);
|
|
|
|
const gate = useCallback(
|
|
(feat: string) => {
|
|
if (isAnonymous) {
|
|
setFeature(feat);
|
|
}
|
|
},
|
|
[isAnonymous]
|
|
);
|
|
|
|
const close = () => setFeature(null);
|
|
|
|
return (
|
|
<LoginGateContext.Provider value={{ gate }}>
|
|
{children}
|
|
<Dialog open={feature !== null} onOpenChange={(open) => !open && close()}>
|
|
<DialogContent className="sm:max-w-md">
|
|
<DialogHeader>
|
|
<DialogTitle>Create a free account to {feature}</DialogTitle>
|
|
<DialogDescription>
|
|
Get 5 million tokens, save chat history, upload documents, use all AI tools, and
|
|
connect 30+ integrations.
|
|
</DialogDescription>
|
|
</DialogHeader>
|
|
<DialogFooter className="flex flex-col gap-2 sm:flex-row">
|
|
<Button asChild>
|
|
<Link href="/register">Create Free Account</Link>
|
|
</Button>
|
|
<Button variant="outline" asChild>
|
|
<Link href="/login">Log In</Link>
|
|
</Button>
|
|
</DialogFooter>
|
|
</DialogContent>
|
|
</Dialog>
|
|
</LoginGateContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useLoginGate(): LoginGateContextValue {
|
|
return useContext(LoginGateContext);
|
|
}
|
|
|
|
/**
|
|
* Returns a click handler that triggers the login gate when anonymous,
|
|
* or calls the original handler when authenticated.
|
|
*/
|
|
export function useGatedHandler(handler: (() => void) | undefined, feature: string): () => void {
|
|
const { gate } = useLoginGate();
|
|
const isAnonymous = useIsAnonymous();
|
|
|
|
return useCallback(() => {
|
|
if (isAnonymous) {
|
|
gate(feature);
|
|
} else {
|
|
handler?.();
|
|
}
|
|
}, [isAnonymous, gate, feature, handler]);
|
|
}
|