diff --git a/app/src/App.tsx b/app/src/App.tsx index f513933..dfbce01 100644 --- a/app/src/App.tsx +++ b/app/src/App.tsx @@ -1,5 +1,5 @@ -import React, { ComponentProps, useEffect, useMemo } from "react"; -import { useLocation } from "react-router-dom"; +import React, {ComponentProps, useMemo} from "react"; +import {useLocation} from "react-router-dom"; import Providers from "@/components/Providers"; import { isAddress } from "viem"; import { ConnectButton } from "@rainbow-me/rainbowkit"; @@ -8,12 +8,16 @@ import SwapWidget from "@ensofinance/shortcuts-widget"; import logoUrl from "./logo_black_white.png"; import "@rainbow-me/rainbowkit/styles.css"; +import useProjectInfo from "@/hooks/useProjectInfo"; // import "./App.css"; const EnsoApiKey = import.meta.env.VITE_ENSO_API_KEY; function App() { const location = useLocation(); + + const projectInfo = useProjectInfo() + const props = useMemo(() => { const searchParams = new URLSearchParams(window.location.search); const tokenInParam = searchParams.get("tokenIn"); @@ -33,21 +37,6 @@ function App() { return props; }, [location]); - useEffect(() => { - // Set the title of the page from the environment variable - if (import.meta.env.VITE_APP_TITLE) { - document.title = `ENSO | ${import.meta.env.VITE_APP_TITLE}`; - } - - // Set the favicon of the page from the environment variable - if (import.meta.env.VITE_APP_LOGO_URL) { - const favicon = document.querySelector("link[rel='icon']"); - if (favicon instanceof HTMLLinkElement) { - favicon.href = import.meta.env.VITE_APP_LOGO_URL; - } - } - }, []); - return (
- {"Enso"} + {"Enso"}
-
{ + if (title) { + document.title = `ENSO | ${title}`; + } + if (logo) { + let favicon = document.querySelector("link[rel='icon']"); + + // If favicon does not exist, create a new one + if (!favicon) { + favicon = document.createElement("link"); + favicon.rel = "icon"; + document.head.appendChild(favicon); + } + favicon.href = logo; + } +}; + +/** + * Fetches project data from Firebase using the project name extracted from the URL. + * @param slug - The project name derived from the current hostname. + */ +const getProjectData = async (slug: string): Promise => { + try { + const resp = await fetch(`https://us-central1-enso-95b84.cloudfunctions.net/getProject`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ subdomain: slug }), + }); + + // Check if the response is valid + if (!resp.ok) { + throw new Error(`Failed to fetch project data: ${resp.status} ${resp.statusText}`); + } + + return await resp.json(); + + } catch (error) { + console.error("Error fetching project data:", error); + throw error; + } +}; + +const useProjectInfo = () => { + const hostname = window.location.hostname; // e.g., "sub.widget.denys-heraymov.website" + const parts = hostname.split('.'); + const subdomain = parts[0] + "." + parts[1]; // "sub.widget" + const storageKey = `projectInfo_${subdomain}`; + + const [projectInfo, setProjectInfo] = useState(null); + + useEffect(() => { + if (subdomain) { + // Try to retrieve cached project info from localStorage + const cachedData = localStorage.getItem(storageKey); + if (cachedData) { + try { + const parsedData: FirebaseProjectI = JSON.parse(cachedData); + setProjectInfo(parsedData); + applyProjectInfoInDOM(parsedData.name, parsedData.logo); + return; // Data found, skip fetching + } catch (error) { + console.error("Error parsing project info from localStorage:", error); + // If error occurs during parsing, clear the corrupted data + localStorage.removeItem(storageKey); + } + } + + // If not in localStorage, fetch data from the API + getProjectData(subdomain).then((data: FirebaseProjectI) => { + if (data?.name || data?.logo) { + setProjectInfo(data); + applyProjectInfoInDOM(data.name, data.logo); + // Save fetched data to localStorage for later use + localStorage.setItem(storageKey, JSON.stringify(data)); + } + }).catch((error) => { + console.error("Error in fetching project data:", error); + }); + } + }, [subdomain]); // Re-run if subdomain changes + + return projectInfo; // Return project info to be used in components +}; + +export default useProjectInfo; diff --git a/app/src/main.tsx b/app/src/main.tsx index dd54fc0..0812dbb 100644 --- a/app/src/main.tsx +++ b/app/src/main.tsx @@ -1,13 +1,26 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import { BrowserRouter } from "react-router-dom"; +import {BrowserRouter, Route, Routes} from "react-router-dom"; import "./index.css"; import App from "./App"; createRoot(document.getElementById("root")!).render( - + + } + /> + } + /> + Empty page
} + /> + , ); diff --git a/app/src/types/project.ts b/app/src/types/project.ts new file mode 100644 index 0000000..f3c6f6d --- /dev/null +++ b/app/src/types/project.ts @@ -0,0 +1,12 @@ +export interface FirebaseProjectI { + id: string + name: string + projectName: string + subdomain: string + userId: string + category: string + variant: string + twitter?: string + logo?: string + banner?: string +} \ No newline at end of file diff --git a/app/vercel.json b/app/vercel.json index dd8ce5d..d513e0d 100644 --- a/app/vercel.json +++ b/app/vercel.json @@ -2,8 +2,8 @@ "trailingSlash": false, "rewrites": [ { - "source": "/widget/:path*", - "destination": "/:path*" + "source": "/(.*)", + "destination": "/index.html" } ] -} +} \ No newline at end of file diff --git a/app/vite.config.ts b/app/vite.config.ts index 2e4bf4a..1b59264 100644 --- a/app/vite.config.ts +++ b/app/vite.config.ts @@ -2,18 +2,24 @@ import { defineConfig, loadEnv } from "vite"; import react from "@vitejs/plugin-react"; import tsconfigPaths from "vite-tsconfig-paths"; -// https://vite.dev/config/ export default defineConfig(({ mode }) => { - // @ts-expect-error env is accessible - const env = loadEnv(mode, process.cwd(), ""); return { - base: env.VITE_BASE_PATH, + base: "/", plugins: [react(), tsconfigPaths()], resolve: { alias: { "@": "/src", }, }, + server: { + fs: { + strict: false, + }, + }, + build: { + outDir: "dist", + assetsDir: "assets", + }, }; }); diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..d513e0d --- /dev/null +++ b/vercel.json @@ -0,0 +1,9 @@ +{ + "trailingSlash": false, + "rewrites": [ + { + "source": "/(.*)", + "destination": "/index.html" + } + ] +} \ No newline at end of file