Update artifacts/fb-publisher/src/App.tsx
Browse files
artifacts/fb-publisher/src/App.tsx
CHANGED
|
@@ -1,121 +1,29 @@
|
|
| 1 |
import { useEffect, useRef, useState } from "react";
|
| 2 |
import { KindeProvider, useKindeAuth } from "@kinde-oss/kinde-auth-react";
|
| 3 |
-
import { setAuthTokenGetter } from "@workspace/api-client-react";
|
| 4 |
import {
|
| 5 |
Switch,
|
| 6 |
Route,
|
| 7 |
-
useLocation,
|
| 8 |
Router as WouterRouter,
|
| 9 |
Redirect,
|
| 10 |
} from "wouter";
|
| 11 |
-
import { QueryClientProvider
|
| 12 |
import { queryClient } from "./lib/queryClient";
|
| 13 |
-
import { Toaster } from "@/components/ui/toaster";
|
| 14 |
-
import { TooltipProvider } from "@/components/ui/tooltip";
|
| 15 |
import Landing from "@/pages/Landing";
|
| 16 |
import Publisher from "@/pages/Publisher";
|
| 17 |
-
import Subscription from "@/pages/Subscription";
|
| 18 |
-
import SubscriptionReturn from "@/pages/SubscriptionReturn";
|
| 19 |
-
import InstallExtension from "@/pages/InstallExtension";
|
| 20 |
-
import Admin from "@/pages/Admin";
|
| 21 |
-
import NotFound from "@/pages/not-found";
|
| 22 |
-
import UpdateBanner from "@/components/UpdateBanner";
|
| 23 |
|
| 24 |
const kindeDomain = import.meta.env.VITE_KINDE_DOMAIN as string;
|
| 25 |
const kindeClientId = import.meta.env.VITE_KINDE_CLIENT_ID as string;
|
| 26 |
-
const basePath = import.meta.env.BASE_URL.replace(/\/$/, "");
|
| 27 |
|
| 28 |
-
function
|
| 29 |
const { isAuthenticated, isLoading } = useKindeAuth();
|
| 30 |
|
| 31 |
-
if (isLoading) return <div className="min-h-screen flex items-center justify-center
|
| 32 |
-
if (
|
| 33 |
|
| 34 |
-
return <Publisher />;
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
function ProtectedSubscription() {
|
| 38 |
-
const { isAuthenticated } = useKindeAuth();
|
| 39 |
-
if (!isAuthenticated) return <Redirect to="/sign-in" />;
|
| 40 |
-
return <Subscription />;
|
| 41 |
-
}
|
| 42 |
-
|
| 43 |
-
function ProtectedExtension() {
|
| 44 |
-
const { isAuthenticated } = useKindeAuth();
|
| 45 |
-
if (!isAuthenticated) return <Redirect to="/sign-in" />;
|
| 46 |
-
return <InstallExtension />;
|
| 47 |
-
}
|
| 48 |
-
|
| 49 |
-
function HomePage() {
|
| 50 |
-
const { isAuthenticated } = useKindeAuth();
|
| 51 |
-
if (isAuthenticated) return <Redirect to="/app" />;
|
| 52 |
return <Landing />;
|
| 53 |
}
|
| 54 |
|
| 55 |
-
function
|
| 56 |
-
const [waking, setWaking] = useState(false);
|
| 57 |
-
|
| 58 |
-
useEffect(() => {
|
| 59 |
-
let wakingTimer: ReturnType<typeof setTimeout>;
|
| 60 |
-
const ping = () => {
|
| 61 |
-
wakingTimer = setTimeout(() => setWaking(true), 4000);
|
| 62 |
-
fetch("/api/healthz", { cache: "no-store" })
|
| 63 |
-
.then(() => { clearTimeout(wakingTimer); setWaking(false); })
|
| 64 |
-
.catch(() => { clearTimeout(wakingTimer); setWaking(false); });
|
| 65 |
-
};
|
| 66 |
-
ping();
|
| 67 |
-
const interval = setInterval(ping, 10 * 60 * 1000);
|
| 68 |
-
return () => { clearInterval(interval); clearTimeout(wakingTimer); };
|
| 69 |
-
}, []);
|
| 70 |
-
|
| 71 |
-
if (!waking) return null;
|
| 72 |
-
|
| 73 |
-
return (
|
| 74 |
-
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-[#16162a]/90 backdrop-blur-sm" dir="rtl">
|
| 75 |
-
<div className="bg-[#1f1f3a] border border-[#3a3a55] rounded-2xl p-8 text-center max-w-sm mx-4 shadow-2xl">
|
| 76 |
-
<div className="text-5xl mb-4">⚙️</div>
|
| 77 |
-
<h2 className="text-white text-xl font-bold mb-2">جاري تشغيل الخادم…</h2>
|
| 78 |
-
<p className="text-gray-400 text-sm leading-relaxed">الخادم كان في وضع السكون.<br />يستغرق الأمر بضع ثوانٍ، شكراً لصبرك.</p>
|
| 79 |
-
<div className="mt-5 flex justify-center gap-2">
|
| 80 |
-
{[0, 1, 2].map((i) => (
|
| 81 |
-
<div key={i} className="w-2.5 h-2.5 bg-[#bb86fc] rounded-full animate-bounce" style={{ animationDelay: `${i * 0.18}s` }} />
|
| 82 |
-
))}
|
| 83 |
-
</div>
|
| 84 |
-
</div>
|
| 85 |
-
</div>
|
| 86 |
-
);
|
| 87 |
-
}
|
| 88 |
-
|
| 89 |
-
function KindeAuthTokenSetter() {
|
| 90 |
-
const { getToken } = useKindeAuth();
|
| 91 |
-
|
| 92 |
-
useEffect(() => {
|
| 93 |
-
setAuthTokenGetter(async () => {
|
| 94 |
-
return await getToken() ?? null;
|
| 95 |
-
});
|
| 96 |
-
return () => setAuthTokenGetter(null);
|
| 97 |
-
}, [getToken]);
|
| 98 |
-
|
| 99 |
-
return null;
|
| 100 |
-
}
|
| 101 |
-
|
| 102 |
-
function KindeQueryClientCacheInvalidator() {
|
| 103 |
-
const { user, isAuthenticated } = useKindeAuth();
|
| 104 |
-
const qc = useQueryClient();
|
| 105 |
-
const prevUserIdRef = useRef<string | null | undefined>(undefined);
|
| 106 |
-
|
| 107 |
-
useEffect(() => {
|
| 108 |
-
const userId = user?.id ?? null;
|
| 109 |
-
if (prevUserIdRef.current !== undefined && prevUserIdRef.current !== userId) {
|
| 110 |
-
qc.clear();
|
| 111 |
-
}
|
| 112 |
-
prevUserIdRef.current = userId;
|
| 113 |
-
}, [user?.id, qc]);
|
| 114 |
-
|
| 115 |
-
return null;
|
| 116 |
-
}
|
| 117 |
-
|
| 118 |
-
function KindeProviderWithRoutes() {
|
| 119 |
return (
|
| 120 |
<KindeProvider
|
| 121 |
domain={kindeDomain}
|
|
@@ -124,31 +32,13 @@ function KindeProviderWithRoutes() {
|
|
| 124 |
logoutUri={`${window.location.origin}`}
|
| 125 |
>
|
| 126 |
<QueryClientProvider client={queryClient}>
|
| 127 |
-
<
|
| 128 |
-
<KindeAuthTokenSetter />
|
| 129 |
-
<KindeQueryClientCacheInvalidator />
|
| 130 |
-
<TooltipProvider>
|
| 131 |
<Switch>
|
| 132 |
<Route path="/" component={HomePage} />
|
| 133 |
-
<Route path="/app" component={
|
| 134 |
-
<Route path="/subscription" component={ProtectedSubscription} />
|
| 135 |
-
<Route path="/subscription/return" component={SubscriptionReturn} />
|
| 136 |
-
<Route path="/extension" component={ProtectedExtension} />
|
| 137 |
-
<Route path="/admin" component={Admin} />
|
| 138 |
-
<Route component={NotFound} />
|
| 139 |
</Switch>
|
| 140 |
-
|
| 141 |
-
<Toaster />
|
| 142 |
-
</TooltipProvider>
|
| 143 |
</QueryClientProvider>
|
| 144 |
</KindeProvider>
|
| 145 |
);
|
| 146 |
-
}
|
| 147 |
-
|
| 148 |
-
export default function App() {
|
| 149 |
-
return (
|
| 150 |
-
<WouterRouter base={basePath}>
|
| 151 |
-
<KindeProviderWithRoutes />
|
| 152 |
-
</WouterRouter>
|
| 153 |
-
);
|
| 154 |
}
|
|
|
|
| 1 |
import { useEffect, useRef, useState } from "react";
|
| 2 |
import { KindeProvider, useKindeAuth } from "@kinde-oss/kinde-auth-react";
|
|
|
|
| 3 |
import {
|
| 4 |
Switch,
|
| 5 |
Route,
|
|
|
|
| 6 |
Router as WouterRouter,
|
| 7 |
Redirect,
|
| 8 |
} from "wouter";
|
| 9 |
+
import { QueryClientProvider } from "@tanstack/react-query";
|
| 10 |
import { queryClient } from "./lib/queryClient";
|
|
|
|
|
|
|
| 11 |
import Landing from "@/pages/Landing";
|
| 12 |
import Publisher from "@/pages/Publisher";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
const kindeDomain = import.meta.env.VITE_KINDE_DOMAIN as string;
|
| 15 |
const kindeClientId = import.meta.env.VITE_KINDE_CLIENT_ID as string;
|
|
|
|
| 16 |
|
| 17 |
+
function HomePage() {
|
| 18 |
const { isAuthenticated, isLoading } = useKindeAuth();
|
| 19 |
|
| 20 |
+
if (isLoading) return <div className="min-h-screen flex items-center justify-center text-white">جاري التحميل...</div>;
|
| 21 |
+
if (isAuthenticated) return <Publisher />;
|
| 22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
return <Landing />;
|
| 24 |
}
|
| 25 |
|
| 26 |
+
export default function App() {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
return (
|
| 28 |
<KindeProvider
|
| 29 |
domain={kindeDomain}
|
|
|
|
| 32 |
logoutUri={`${window.location.origin}`}
|
| 33 |
>
|
| 34 |
<QueryClientProvider client={queryClient}>
|
| 35 |
+
<WouterRouter>
|
|
|
|
|
|
|
|
|
|
| 36 |
<Switch>
|
| 37 |
<Route path="/" component={HomePage} />
|
| 38 |
+
<Route path="/app" component={HomePage} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 39 |
</Switch>
|
| 40 |
+
</WouterRouter>
|
|
|
|
|
|
|
| 41 |
</QueryClientProvider>
|
| 42 |
</KindeProvider>
|
| 43 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
}
|