diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
new file mode 100644
index 0000000..3247f89
--- /dev/null
+++ b/frontend/src/App.tsx
@@ -0,0 +1,76 @@
+import { ColorModeProvider } from '@/components/ui/color-mode'
+import { ChakraProvider } from '@chakra-ui/react'
+import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'
+import { RouterProvider, createRouter } from '@tanstack/react-router'
+import { PostHogProvider } from 'posthog-js/react'
+import { useState } from 'react'
+import { OpenAPI } from './client'
+import { ApiError } from './client'
+import { AuthProvider } from './hooks/useAuthContext'
+import { routeTree } from './routeTree.gen'
+import { system } from './theme'
+import CookieConsent from './components/commonUI/CookieConsentBanner'
+
+OpenAPI.BASE = import.meta.env.VITE_API_URL
+OpenAPI.TOKEN = async () => {
+ return localStorage.getItem('access_token') || ''
+}
+
+
+const posthogApiKey = import.meta.env.VITE_POSTHOG_API_KEY
+const posthogConfig = {
+ enabled: import.meta.env.PROD && !!posthogApiKey,
+ options: import.meta.env.VITE_POSTHOG_HOST ? { api_host: import.meta.env.VITE_POSTHOG_HOST } : {},
+}
+
+const handleApiError = (error: Error) => {
+ if (error instanceof ApiError && [401, 403].includes(error.status)) {
+ localStorage.removeItem('access_token')
+ window.location.href = '/login'
+ }
+ }
+
+
+const queryClient = new QueryClient({
+ queryCache: new QueryCache({
+ onError: handleApiError,
+ }),
+ mutationCache: new MutationCache({
+ onError: handleApiError,
+ }),
+})
+
+const router = createRouter({ routeTree })
+
+declare module '@tanstack/react-router' {
+ interface Register {
+ router: typeof router
+ }
+}
+
+const App = () => {
+ const [isPosthogEnabled, setIsPosthogEnabled] = useState(false);
+ const onConsent=(status:boolean)=>{
+ setIsPosthogEnabled(status)
+ }
+ return (
+
+
+
+
+
+ {isPosthogEnabled && posthogConfig.enabled ? (
+
+
+
+ ) : (
+
+ )}
+
+
+
+
+ );
+};
+
+export default App;
\ No newline at end of file
diff --git a/frontend/src/components/commonUI/CookieConsentBanner.tsx b/frontend/src/components/commonUI/CookieConsentBanner.tsx
new file mode 100644
index 0000000..5697c34
--- /dev/null
+++ b/frontend/src/components/commonUI/CookieConsentBanner.tsx
@@ -0,0 +1,129 @@
+import React, { useState, useEffect } from "react";
+import {
+ Box,
+ Button,
+ Flex,
+ Text,
+ Link,
+ VStack,
+ IconButton,
+} from "@chakra-ui/react";
+
+import { FaTimes as CloseIcon } from "react-icons/fa";
+
+interface CookieConsentProps{
+ consented:boolean
+ onConsent:(status:boolean)=>void
+}
+
+const CookieConsent:React.FC = ({consented,onConsent}) => {
+ const [isVisible, setIsVisible] = useState(false);
+ useEffect(() => {
+ const consent = localStorage.getItem("cookie-consent");
+ if (consent==="all") {
+ onConsent(true);
+ } else {
+ const timer = setTimeout(() => {
+ onConsent(false)
+ setIsVisible(true);
+ }, 300);
+ return () => clearTimeout(timer);
+ }
+ }, []);
+
+ const handleAcceptAll = () => {
+ localStorage.setItem("cookie-consent", "all");
+ setIsVisible(false);
+ setTimeout(() => onConsent(true), 300);
+ };
+
+ const handleAcceptNecessary = () => {
+ localStorage.setItem("cookie-consent", "deny");
+ setIsVisible(false);
+ setTimeout(() => onConsent(false), 300);
+ };
+
+ const handleClose = () => {
+ setIsVisible(false);
+ };
+
+ if (consented) return null;
+ return (
+
+
+
+ We use cookies 🍪
+
+ To enhance your experience on FlashNotes. By continuing, you agree to our use of cookies as outlined in our
+
+ Privacy Policy
+ .
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default CookieConsent;
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index 8e60b5f..e8d1c0c 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -1,69 +1,14 @@
import './i18n'
-import { ColorModeProvider } from '@/components/ui/color-mode'
-import { ChakraProvider } from '@chakra-ui/react'
-import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query'
-import { RouterProvider, createRouter } from '@tanstack/react-router'
-import { PostHogProvider } from 'posthog-js/react'
import { StrictMode } from 'react'
import ReactDOM from 'react-dom/client'
-import { ApiError, OpenAPI } from './client'
-import { AuthProvider } from './hooks/useAuthContext'
-import { routeTree } from './routeTree.gen'
-import { system } from './theme'
-
-OpenAPI.BASE = import.meta.env.VITE_API_URL
-OpenAPI.TOKEN = async () => {
- return localStorage.getItem('access_token') || ''
-}
-
-const handleApiError = (error: Error) => {
- if (error instanceof ApiError && [401, 403].includes(error.status)) {
- localStorage.removeItem('access_token')
- window.location.href = '/login'
- }
-}
-const queryClient = new QueryClient({
- queryCache: new QueryCache({
- onError: handleApiError,
- }),
- mutationCache: new MutationCache({
- onError: handleApiError,
- }),
-})
-
-const router = createRouter({ routeTree })
-declare module '@tanstack/react-router' {
- interface Register {
- router: typeof router
- }
-}
-
-const posthogApiKey = import.meta.env.VITE_POSTHOG_API_KEY
-const posthogConfig = {
- enabled: import.meta.env.PROD && !!posthogApiKey,
- options: import.meta.env.VITE_POSTHOG_HOST ? { api_host: import.meta.env.VITE_POSTHOG_HOST } : {},
-}
+import App from './App'
const rootElement = document.getElementById('root')
if (rootElement && !rootElement.innerHTML) {
const root = ReactDOM.createRoot(rootElement)
root.render(
-
-
-
-
- {posthogConfig.enabled ? (
-
-
-
- ) : (
-
- )}
-
-
-
-
+
,
)
}