diff --git a/frontend/next-env.d.ts b/frontend/next-env.d.ts
new file mode 100644
index 0000000..4f11a03
--- /dev/null
+++ b/frontend/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index b7430c6..62baa47 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -8,6 +8,7 @@
"name": "vite-react-typescript-starter",
"version": "0.0.0",
"dependencies": {
+ "@auth0/auth0-react": "^2.3.0",
"@mediapipe/camera_utils": "^0.3.1675466862",
"@mediapipe/drawing_utils": "^0.3.1675466124",
"@mediapipe/hands": "^0.4.1675469240",
@@ -18,6 +19,7 @@
},
"devDependencies": {
"@eslint/js": "^9.9.1",
+ "@types/node": "^22.13.14",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
@@ -58,6 +60,23 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@auth0/auth0-react": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@auth0/auth0-react/-/auth0-react-2.3.0.tgz",
+ "integrity": "sha512-YYTc/DWWigKC9fURufR/79h3+3DAnIzbfEzJLZ8Z4Q0BXE0azru3pKUbU+vYzS4lMAJkclwLuAbUnLjK81vCpA==",
+ "dependencies": {
+ "@auth0/auth0-spa-js": "^2.1.3"
+ },
+ "peerDependencies": {
+ "react": "^16.11.0 || ^17 || ^18 || ^19",
+ "react-dom": "^16.11.0 || ^17 || ^18 || ^19"
+ }
+ },
+ "node_modules/@auth0/auth0-spa-js": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/@auth0/auth0-spa-js/-/auth0-spa-js-2.1.3.tgz",
+ "integrity": "sha512-NMTBNuuG4g3rame1aCnNS5qFYIzsTUV5qTFPRfTyYFS1feS6jsCBR+eTq9YkxCp1yuoM2UIcjunPaoPl77U9xQ=="
+ },
"node_modules/@babel/code-frame": {
"version": "7.26.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
@@ -1337,6 +1356,15 @@
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
+ "node_modules/@types/node": {
+ "version": "22.13.14",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz",
+ "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==",
+ "dev": true,
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
"node_modules/@types/prop-types": {
"version": "15.7.14",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.14.tgz",
@@ -3738,6 +3766,12 @@
"typescript": ">=4.8.4 <5.9.0"
}
},
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true
+ },
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index c74c417..186ac29 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
+ "@auth0/auth0-react": "^2.3.0",
"@mediapipe/camera_utils": "^0.3.1675466862",
"@mediapipe/drawing_utils": "^0.3.1675466124",
"@mediapipe/hands": "^0.4.1675469240",
@@ -20,6 +21,7 @@
},
"devDependencies": {
"@eslint/js": "^9.9.1",
+ "@types/node": "^22.13.14",
"@types/react": "^18.3.5",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
index ddca4a3..9fd0e58 100644
--- a/frontend/src/App.tsx
+++ b/frontend/src/App.tsx
@@ -1,12 +1,16 @@
-import React from 'react'
-import Canvas from './components/Canvas'
-import Toolbar from './components/Toolbar'
-import Header from './components/Header'
-import HandDrawing from './components/HandDrawing'
-import { DrawingProvider } from './context/DrawingContext'
-import { HandGestureProvider } from './context/HandGestureContext'
+import React from 'react';
+import { useAuth0 } from '@auth0/auth0-react';
+import { withAuthenticationRequired } from '@auth0/auth0-react';
+import Canvas from './components/Canvas';
+import Toolbar from './components/Toolbar';
+import Header from './components/Header';
+import HandDrawing from './components/HandDrawing';
+import LoginButton from './components/LoginButton';
+import { DrawingProvider } from './context/DrawingContext';
+import { HandGestureProvider } from './context/HandGestureContext';
-function App() {
+// Protected component that requires authentication
+const ProtectedApp = () => {
return (
@@ -21,7 +25,57 @@ function App() {
- )
+ );
+};
+
+// Wrap the protected component with authentication
+const ProtectedAppWithAuth = withAuthenticationRequired(ProtectedApp);
+
+function App() {
+ const { isAuthenticated } = useAuth0();
+
+ if (!isAuthenticated) {
+ return (
+
+
+ {/* Logo and Title */}
+
+
+ C
+
+
CoCo
+
Create, collaborate, and share your drawings
+
+
+ {/* Login Button */}
+
+
+
+
+ {/* Feature Grid */}
+
+
+
🎨
+
Draw Freely
+
Express your creativity with our intuitive drawing tools
+
+
+
🤝
+
Collaborate
+
Work together in real-time with others
+
+
+
✨
+
Hand Gestures
+
Draw naturally with hand tracking support
+
+
+
+
+ );
+ }
+
+ return ;
}
-export default App
+export default App;
\ No newline at end of file
diff --git a/frontend/src/components/Header.tsx b/frontend/src/components/Header.tsx
index 7cb2758..3a20da4 100644
--- a/frontend/src/components/Header.tsx
+++ b/frontend/src/components/Header.tsx
@@ -1,9 +1,13 @@
import React, { useState } from 'react'
import { useDrawing } from '../context/DrawingContext'
import { Download, Share2, Clock, User, ChevronDown } from 'lucide-react'
+import LoginButton from './LoginButton'
+import LogoutButton from './LogoutButton'
+import { useAuth0 } from "@auth0/auth0-react"
const Header: React.FC = () => {
const { state } = useDrawing()
+ const { isAuthenticated } = useAuth0()
const [documentName, setDocumentName] = useState('Untitled')
const handleExport = () => {
@@ -92,6 +96,11 @@ const Header: React.FC = () => {
+ {isAuthenticated ? (
+
+ ) : (
+
+ )}
diff --git a/frontend/src/components/LoginButton.tsx b/frontend/src/components/LoginButton.tsx
new file mode 100644
index 0000000..7f61d3e
--- /dev/null
+++ b/frontend/src/components/LoginButton.tsx
@@ -0,0 +1,17 @@
+import React from "react";
+import { useAuth0 } from "@auth0/auth0-react";
+
+const LoginButton = () => {
+ const { loginWithRedirect } = useAuth0();
+
+ return (
+
+ );
+};
+
+export default LoginButton;
\ No newline at end of file
diff --git a/frontend/src/components/LogoutButton.tsx b/frontend/src/components/LogoutButton.tsx
new file mode 100644
index 0000000..d16b8d1
--- /dev/null
+++ b/frontend/src/components/LogoutButton.tsx
@@ -0,0 +1,13 @@
+import { useAuth0 } from "@auth0/auth0-react";
+
+const LogoutButton = () => {
+ const { logout } = useAuth0();
+
+ return (
+
+ );
+};
+
+export default LogoutButton;
\ No newline at end of file
diff --git a/frontend/src/loginPage.tsx b/frontend/src/loginPage.tsx
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index 6f4ac9b..af69432 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -2,9 +2,22 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
+import {Auth0Provider} from "@auth0/auth0-react"
+
+const domain = import.meta.env.VITE_AUTH0_DOMAIN;
+const clientId = import.meta.env.VITE_AUTH0_CLIENT_ID;
createRoot(document.getElementById('root')!).render(
-
+
+
+
,
)
+