diff --git a/public/App.css b/public/App.css new file mode 100644 index 0000000..b9d355d --- /dev/null +++ b/public/App.css @@ -0,0 +1,42 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} diff --git a/public/App.jsx b/public/App.jsx new file mode 100644 index 0000000..1a51650 --- /dev/null +++ b/public/App.jsx @@ -0,0 +1,67 @@ +import { useState } from 'react' +import reactLogo from './assets/react.svg' +import viteLogo from '/vite.svg' +import './App.css' +import { SignInButton, SignUpButton, LogOutButton } from './components/auth/Button' +import { SignInForm, SignUpForm } from './components/auth/Input' +import { useAuth } from './context/AuthContext' +import { doSignOut } from './firebase/auth' + +function App() { + const [count, setCount] = useState(0) + const [isSignInOpen, setIsSignInOpen] = useState(false) + const [isSignUpOpen, setIsSignUpOpen] = useState(false) + const { userLoggedIn } = useAuth() + + const openSignIn = () => setIsSignInOpen(true) + const closeSignIn = () => setIsSignInOpen(false) + const openSignUp = () => setIsSignUpOpen(true) + const closeSignUp = () => setIsSignUpOpen(false) + + const handleLogout = async () => { + try { + await doSignOut() + } catch (error) { + console.error('Logout error:', error) + } + } + + return ( + <> +
+ + Vite logo + + + React logo + +
+

Vite + React

+
+ +

+ Edit src/App.jsx and save to test HMR +

+
+ + {!userLoggedIn ? ( + <> + + + + ) : ( + + )} + +

+ Click on the Vite and React logos to learn more +

+ + + + ) +} + +export default App diff --git a/public/assets/logo.svg b/public/assets/logo.svg new file mode 100644 index 0000000..d4f0846 --- /dev/null +++ b/public/assets/logo.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/public/assets/react.svg b/public/assets/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/public/assets/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/components/auth/Button.jsx b/public/components/auth/Button.jsx new file mode 100644 index 0000000..dd9c339 --- /dev/null +++ b/public/components/auth/Button.jsx @@ -0,0 +1,24 @@ +import { doSignOut } from '../../firebase/auth'; + +// Authentication buttons component - Sign in and sign up trigger buttons +// TODO: Implement button variants and styling + +function SignInButton({ onClick }) { + return ( + + ) + } + + function SignUpButton({ onClick }) { + return ( + + ) + } + + function LogOutButton({ onClick }) { + return ( + + ) + } + + export { SignInButton, SignUpButton, LogOutButton } \ No newline at end of file diff --git a/public/components/auth/Input.jsx b/public/components/auth/Input.jsx new file mode 100644 index 0000000..cf8a3e1 --- /dev/null +++ b/public/components/auth/Input.jsx @@ -0,0 +1,202 @@ +import { useState } from 'react'; +import styles from '/src/styles/forms.module.css'; +import { doSignInWithEmailAndPassword, doSignInWithGoogle, doCreateUserWithEmailAndPassword } from '../../firebase/auth'; +import { useAuth } from '../../context/AuthContext'; + +// Authentication forms component - Sign in and sign up popup forms +// TODO: Implement form validation and authentication logic + +function SignInForm({ isOpen, onClose }) { + if (!isOpen) return null; + const { userLoggedIn } = useAuth() + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [isSigningIn, setIsSigningIn] = useState(false) + const [errorMessage, setErrorMessage] = useState('') + + const onSubmit = async (e) => { + e.preventDefault() + if(!isSigningIn){ + setIsSigningIn(true) + setErrorMessage('') + try { + await doSignInWithEmailAndPassword(email, password) + onClose() + } catch (error) { + setErrorMessage(error.message) + } finally { + setIsSigningIn(false) + } + } + } + + const onGoogleSignIn = async (e) => { + e.preventDefault() + if(!isSigningIn){ + setIsSigningIn(true) + setErrorMessage('') + try { + await doSignInWithGoogle() + onClose() + } catch (error) { + setErrorMessage(error.message) + } finally { + setIsSigningIn(false) + } + } + } + + return ( +
+
e.stopPropagation()}> +

Sign In

+ {errorMessage &&
{errorMessage}
} +
+
+ setEmail(e.target.value)} + required + /> +
+
+ setPassword(e.target.value)} + required + /> +
+ +
+ +
+ or +
+ + +
+
+ ) + } + + function SignUpForm({ isOpen, onClose }) { + if (!isOpen) return null; + + const [email, setEmail] = useState('') + const [password, setPassword] = useState('') + const [confirmPassword, setConfirmPassword] = useState('') + const [isRegistering, setIsRegistering] = useState(false) + const [errorMessage, setErrorMessage] = useState('') + + const onSubmit = async (e) => { + e.preventDefault() + if (password !== confirmPassword) { + setErrorMessage('Passwords do not match') + return + } + if(!isRegistering){ + setIsRegistering(true) + setErrorMessage('') + try { + await doCreateUserWithEmailAndPassword(email, password) + onClose() + } catch (error) { + setErrorMessage(error.message) + } finally { + setIsRegistering(false) + } + } + } + + const onGoogleSignIn = async (e) => { + e.preventDefault() + if(!isRegistering){ + setIsRegistering(true) + setErrorMessage('') + try { + await doSignInWithGoogle() + onClose() + } catch (error) { + setErrorMessage(error.message) + } finally { + setIsRegistering(false) + } + } + } + + return ( +
+
e.stopPropagation()}> +

Sign Up

+ {errorMessage &&
{errorMessage}
} +
+
+ setEmail(e.target.value)} + required + /> +
+
+ setPassword(e.target.value)} + required + /> +
+
+ setConfirmPassword(e.target.value)} + required + /> +
+ +
+ +
+ or +
+ + +
+
+ ) + } + + export { SignInForm, SignUpForm } \ No newline at end of file diff --git a/public/components/board/AddTaskCard.jsx b/public/components/board/AddTaskCard.jsx new file mode 100644 index 0000000..8674020 --- /dev/null +++ b/public/components/board/AddTaskCard.jsx @@ -0,0 +1,2 @@ +// AddTaskCard component - A button/form for adding new tasks to a column +// TODO: Implement add task form or button \ No newline at end of file diff --git a/public/components/board/Board.jsx b/public/components/board/Board.jsx new file mode 100644 index 0000000..d138556 --- /dev/null +++ b/public/components/board/Board.jsx @@ -0,0 +1,2 @@ +// Board component - The main container for the entire board +// TODO: Implement main board container with drag and drop context \ No newline at end of file diff --git a/public/components/board/BoardColumn.jsx b/public/components/board/BoardColumn.jsx new file mode 100644 index 0000000..e7d1797 --- /dev/null +++ b/public/components/board/BoardColumn.jsx @@ -0,0 +1,2 @@ +// BoardColumn component - Represents a single column/list in the board +// TODO: Implement column component with Droppable logic \ No newline at end of file diff --git a/public/components/board/ColumnHeader.jsx b/public/components/board/ColumnHeader.jsx new file mode 100644 index 0000000..c2a96b7 --- /dev/null +++ b/public/components/board/ColumnHeader.jsx @@ -0,0 +1,2 @@ +// ColumnHeader component - Component for the column title, settings, and menu +// TODO: Implement column header with title and settings menu \ No newline at end of file diff --git a/public/components/board/TaskCard.jsx b/public/components/board/TaskCard.jsx new file mode 100644 index 0000000..ec02b84 --- /dev/null +++ b/public/components/board/TaskCard.jsx @@ -0,0 +1,2 @@ +// TaskCard component - A single task card component +// TODO: Implement task card with Draggable logic \ No newline at end of file diff --git a/public/components/layout/Header.jsx b/public/components/layout/Header.jsx new file mode 100644 index 0000000..3a6dc7e --- /dev/null +++ b/public/components/layout/Header.jsx @@ -0,0 +1,2 @@ +// Header component - Top navigation bar +// TODO: Implement header with navigation and user menu \ No newline at end of file diff --git a/public/components/layout/MainContent.jsx b/public/components/layout/MainContent.jsx new file mode 100644 index 0000000..99081d2 --- /dev/null +++ b/public/components/layout/MainContent.jsx @@ -0,0 +1,2 @@ +// MainContent component - The main container for the board area +// TODO: Implement main content container for board display \ No newline at end of file diff --git a/public/components/layout/Sidebar.jsx b/public/components/layout/Sidebar.jsx new file mode 100644 index 0000000..a83268d --- /dev/null +++ b/public/components/layout/Sidebar.jsx @@ -0,0 +1,2 @@ +// Sidebar component - Side navigation for project lists, filters, etc. +// TODO: Implement sidebar with project navigation and filters \ No newline at end of file diff --git a/public/components/ui/Avatar.jsx b/public/components/ui/Avatar.jsx new file mode 100644 index 0000000..12cd757 --- /dev/null +++ b/public/components/ui/Avatar.jsx @@ -0,0 +1,2 @@ +// Avatar component - User profile image component +// TODO: Implement avatar component with fallback images \ No newline at end of file diff --git a/public/components/ui/Button.jsx b/public/components/ui/Button.jsx new file mode 100644 index 0000000..e908902 --- /dev/null +++ b/public/components/ui/Button.jsx @@ -0,0 +1,16 @@ +// Button component - All button types (primary, secondary, danger) +// TODO: Implement button component with different variants + +function SignInButton({ onClick }) { + return ( + + ) + } + + function SignUpButton({ onClick }) { + return ( + + ) + } + + export { SignInButton, SignUpButton } \ No newline at end of file diff --git a/public/components/ui/Input.jsx b/public/components/ui/Input.jsx new file mode 100644 index 0000000..6d55501 --- /dev/null +++ b/public/components/ui/Input.jsx @@ -0,0 +1,109 @@ +import { useState } from 'react'; +import styles from '/src/styles/forms.module.css'; + +// Input component - Input fields for forms, search, etc. +// TODO: Implement input component with different types and validation + +function SignInForm({ isOpen, onClose }) { + if (!isOpen) return null; + + return ( +
+
e.stopPropagation()}> +

Sign In

+
+
+ +
+
+ +
+ +
+ +
+ or +
+ + +
+
+ ) + } + + function SignUpForm({ isOpen, onClose }) { + if (!isOpen) return null; + + return ( +
+
e.stopPropagation()}> +

Sign Up

+
+
+ +
+
+ +
+
+ +
+ +
+ +
+ or +
+ + +
+
+ ) + } + + export { SignInForm, SignUpForm } \ No newline at end of file diff --git a/public/components/ui/Modal.jsx b/public/components/ui/Modal.jsx new file mode 100644 index 0000000..2b653d0 --- /dev/null +++ b/public/components/ui/Modal.jsx @@ -0,0 +1,2 @@ +// Modal component - Modal component for creating/editing tasks or projects +// TODO: Implement modal component with backdrop and content \ No newline at end of file diff --git a/public/components/ui/Tag.jsx b/public/components/ui/Tag.jsx new file mode 100644 index 0000000..0c943f6 --- /dev/null +++ b/public/components/ui/Tag.jsx @@ -0,0 +1,2 @@ +// Tag component - Visual component for task tags/categories +// TODO: Implement tag component with different colors and styles \ No newline at end of file diff --git a/public/context/AuthContext.jsx b/public/context/AuthContext.jsx new file mode 100644 index 0000000..5b8952b --- /dev/null +++ b/public/context/AuthContext.jsx @@ -0,0 +1,46 @@ +// AuthContext - Manages authentication state across the app +// TODO: Implement authentication context provider +import React, { useContext, useState, useEffect} from "react"; +import {auth} from "/src/firebase/firebase.js" +import { onAuthStateChanged } from "firebase/auth"; + +const AuthContext = React.createContext(); + +export function useAuth(){ + return useContext(AuthContext); +} + +export const AuthProvider = ({ children }) => { + const [currentUser, setCurrentUser] = useState(null); + const [userLoggedIn, setUserLoggedIn] = useState(false); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const unsubscribe = onAuthStateChanged(auth, initializeUser); + return unsubscribe; + }, []) + + async function initializeUser(user){ + if (user){ + setCurrentUser({...user}); + setUserLoggedIn(true); + } else { + setCurrentUser(null); + setUserLoggedIn(false); + } + setLoading(false); + } + + const value = { + currentUser, + userLoggedIn, + setUserLoggedIn, + loading + } + + return ( + + {!loading && children} + + ) +} \ No newline at end of file diff --git a/public/context/BoardContext.jsx b/public/context/BoardContext.jsx new file mode 100644 index 0000000..c299d53 --- /dev/null +++ b/public/context/BoardContext.jsx @@ -0,0 +1,2 @@ +// BoardContext - Manages the state for the current board (tasks, columns, etc.) +// TODO: Implement board context provider with state management \ No newline at end of file diff --git a/public/context/ThemeContext.jsx b/public/context/ThemeContext.jsx new file mode 100644 index 0000000..b236fa8 --- /dev/null +++ b/public/context/ThemeContext.jsx @@ -0,0 +1,2 @@ +// ThemeContext - Manages the light/dark mode theme +// TODO: Implement theme context provider \ No newline at end of file diff --git a/public/firebase/auth.js b/public/firebase/auth.js new file mode 100644 index 0000000..966011f --- /dev/null +++ b/public/firebase/auth.js @@ -0,0 +1,35 @@ +import {auth} from "./firebase.js" +import { createUserWithEmailAndPassword, GoogleAuthProvider, signInWithPopup, sendEmailVerification, sendPasswordResetEmail, signInWithEmailAndPassword, updatePassword} from "firebase/auth" + +export const doCreateUserWithEmailAndPassword = async (email, password) => { + return createUserWithEmailAndPassword(auth, email, password); +}; + +export const doSignInWithEmailAndPassword = (email, password) => { + return signInWithEmailAndPassword(auth, email, password); +}; + +export const doSignInWithGoogle = async () => { + const provider = new GoogleAuthProvider(); + const result = await signInWithPopup(auth, provider); + //result.user + return result +}; + +export const doSignOut = () => { + return auth.signOut(); +}; + +// export const doPasswordReset = (email) => { +// return sendPasswordResetEmail(auth, email); +// }; + +// export const doPasswordChange = (password) => { +// return updatePassword(auth.currentUser, password); +// }; + +// export const doSendEmailVerification = () => { +// return sendEmailVerification(auth.currentUser, { +// url: `${window.location.origin}/home`, +// }); +// }; diff --git a/public/firebase/firebase.js b/public/firebase/firebase.js new file mode 100644 index 0000000..c5a145d --- /dev/null +++ b/public/firebase/firebase.js @@ -0,0 +1,25 @@ +// Import the functions you need from the SDKs you need +import { initializeApp } from "firebase/app"; +import { getAnalytics } from "firebase/analytics"; +import { getAuth } from "firebase/auth"; +// TODO: Add SDKs for Firebase products that you want to use +// https://firebase.google.com/docs/web/setup#available-libraries + +// Your web app's Firebase configuration +// For Firebase JS SDK v7.20.0 and later, measurementId is optional +const firebaseConfig = { + apiKey: "AIzaSyCalE6UBEP6X3ZX7R19tC5VoKO03wgAoTo", + authDomain: "dragme-mini.firebaseapp.com", + projectId: "dragme-mini", + storageBucket: "dragme-mini.firebasestorage.app", + messagingSenderId: "188367279980", + appId: "1:188367279980:web:a554ae85ce559846fac549", + measurementId: "G-2XEQ97DMV8" +}; + +// Initialize Firebase +const app = initializeApp(firebaseConfig); +const analytics = getAnalytics(app); +const auth = getAuth(app); + +export { app, analytics, auth }; \ No newline at end of file diff --git a/public/hooks/useAuth.js b/public/hooks/useAuth.js new file mode 100644 index 0000000..7296141 --- /dev/null +++ b/public/hooks/useAuth.js @@ -0,0 +1,2 @@ +// useAuth hook - Handles user authentication state and logic +// TODO: Implement authentication hook with login/logout functionality \ No newline at end of file diff --git a/public/hooks/useDarkMode.js b/public/hooks/useDarkMode.js new file mode 100644 index 0000000..2f992e2 --- /dev/null +++ b/public/hooks/useDarkMode.js @@ -0,0 +1,2 @@ +// useDarkMode hook - Manages dark mode state and local storage +// TODO: Implement dark mode hook with theme switching \ No newline at end of file diff --git a/public/index.css b/public/index.css new file mode 100644 index 0000000..08a3ac9 --- /dev/null +++ b/public/index.css @@ -0,0 +1,68 @@ +:root { + font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 243288c..0000000 --- a/public/index.html +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - Welcome to Firebase Hosting - - - - - - - - - - - - - - - - - - - -
-

Welcome

-

Firebase Hosting Setup Complete

-

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

- Open Hosting Documentation -
-

Firebase SDK Loading…

- - - - diff --git a/public/lib/api.js b/public/lib/api.js new file mode 100644 index 0000000..41bb501 --- /dev/null +++ b/public/lib/api.js @@ -0,0 +1,2 @@ +// API utilities - Functions for making API calls to the backend +// TODO: Implement API functions for CRUD operations \ No newline at end of file diff --git a/public/lib/dndHelpers.js b/public/lib/dndHelpers.js new file mode 100644 index 0000000..232c138 --- /dev/null +++ b/public/lib/dndHelpers.js @@ -0,0 +1,2 @@ +// DnD Helpers - Helper functions for the drag-and-drop logic +// TODO: Implement drag and drop utility functions \ No newline at end of file diff --git a/public/main.jsx b/public/main.jsx new file mode 100644 index 0000000..ec394e1 --- /dev/null +++ b/public/main.jsx @@ -0,0 +1,13 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import './index.css' +import App from './App.jsx' +import { AuthProvider } from './context/AuthContext' + +createRoot(document.getElementById('root')).render( + + + + + , +) diff --git a/public/pages/Dashboard.jsx b/public/pages/Dashboard.jsx new file mode 100644 index 0000000..fc12591 --- /dev/null +++ b/public/pages/Dashboard.jsx @@ -0,0 +1,2 @@ +// Dashboard page - The main landing page after login +// TODO: Implement dashboard with project overview and quick actions \ No newline at end of file diff --git a/public/pages/Login.jsx b/public/pages/Login.jsx new file mode 100644 index 0000000..5dbc04f --- /dev/null +++ b/public/pages/Login.jsx @@ -0,0 +1,2 @@ +// Login page - The user login page +// TODO: Implement login form with authentication \ No newline at end of file diff --git a/public/pages/ProjectView.jsx b/public/pages/ProjectView.jsx new file mode 100644 index 0000000..99d71b0 --- /dev/null +++ b/public/pages/ProjectView.jsx @@ -0,0 +1,2 @@ +// ProjectView page - The primary component for a single project board +// TODO: Implement project view with board and project settings \ No newline at end of file diff --git a/public/pages/Register.jsx b/public/pages/Register.jsx new file mode 100644 index 0000000..8be63cf --- /dev/null +++ b/public/pages/Register.jsx @@ -0,0 +1,2 @@ +// Register page - The user registration page +// TODO: Implement registration form with validation \ No newline at end of file diff --git a/public/styles/buttons.module.css b/public/styles/buttons.module.css new file mode 100644 index 0000000..6d5fa16 --- /dev/null +++ b/public/styles/buttons.module.css @@ -0,0 +1,2 @@ +/* Button component styles */ +/* TODO: Add button variant styles */ \ No newline at end of file diff --git a/public/styles/cards.module.css b/public/styles/cards.module.css new file mode 100644 index 0000000..645a05c --- /dev/null +++ b/public/styles/cards.module.css @@ -0,0 +1,2 @@ +/* Card component styles */ +/* TODO: Add card layout and styling */ \ No newline at end of file diff --git a/public/styles/forms.module.css b/public/styles/forms.module.css new file mode 100644 index 0000000..460610c --- /dev/null +++ b/public/styles/forms.module.css @@ -0,0 +1,156 @@ +/* Form component styles */ +/* TODO: Add form layout and input styling */ + +/* Popup Overlay */ +.popupOverlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + backdrop-filter: blur(4px); +} + +/* Popup Card */ +.popupCard { + background: white; + border-radius: 12px; + padding: 2rem; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04); + width: 100%; + max-width: 400px; + margin: 1rem; +} + +/* Popup Title */ +.popupTitle { + font-size: 1.5rem; + font-weight: 600; + color: #1f2937; + margin-bottom: 1.5rem; + text-align: center; +} + +/* Popup Form */ +.popupForm { + display: flex; + flex-direction: column; + gap: 1rem; +} + +/* Input Group */ +.inputGroup { + display: flex; + flex-direction: column; +} + +/* Popup Input */ +.popupInput { + padding: 0.75rem 1rem; + border: 2px solid #e5e7eb; + border-radius: 8px; + font-size: 1rem; + transition: all 0.2s ease; + background-color: #f9fafb; +} + +.popupInput:focus { + outline: none; + border-color: #3b82f6; + background-color: white; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); +} + +.popupInput::placeholder { + color: #9ca3af; +} + +/* Popup Button */ +.popupButton { + background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); + color: white; + border: none; + padding: 0.75rem 1.5rem; + border-radius: 8px; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; + margin-top: 0.5rem; +} + +.popupButton:hover { + transform: translateY(-1px); + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2); +} + +.popupButton:active { + transform: translateY(0); +} + +.popupButton:focus { + outline: none; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.3); +} + +/* Divider */ +.divider { + display: flex; + align-items: center; + margin: 1.5rem 0; + text-align: center; +} + +.divider::before, +.divider::after { + content: ''; + flex: 1; + border-bottom: 1px solid #e5e7eb; +} + +.divider span { + padding: 0 1rem; + color: #6b7280; + font-size: 0.875rem; + background: white; +} + +/* Google Button */ +.googleButton { + display: flex; + align-items: center; + justify-content: center; + gap: 0.75rem; + width: 100%; + padding: 0.75rem 1rem; + border: 2px solid #e5e7eb; + border-radius: 8px; + background-color: white; + color: #374151; + font-size: 1rem; + font-weight: 500; + cursor: pointer; + transition: all 0.2s ease; +} + +.googleButton:hover { + border-color: #d1d5db; + background-color: #f9fafb; + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); +} + +.googleButton:focus { + outline: none; + border-color: #3b82f6; + box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1); +} + +/* Google Icon */ +.googleIcon { + width: 18px; + height: 18px; +} \ No newline at end of file diff --git a/public/styles/layout.module.css b/public/styles/layout.module.css new file mode 100644 index 0000000..3592ef8 --- /dev/null +++ b/public/styles/layout.module.css @@ -0,0 +1,2 @@ +/* Layout component styles */ +/* TODO: Add layout and grid styling */ \ No newline at end of file diff --git a/public/styles/tags.module.css b/public/styles/tags.module.css new file mode 100644 index 0000000..466981e --- /dev/null +++ b/public/styles/tags.module.css @@ -0,0 +1,2 @@ +/* Tag component styles */ +/* TODO: Add tag styling and color variants */ \ No newline at end of file diff --git a/public/tailwind.config.js b/public/tailwind.config.js new file mode 100644 index 0000000..f9376f7 --- /dev/null +++ b/public/tailwind.config.js @@ -0,0 +1,2 @@ +// Tailwind CSS configuration +// TODO: Configure Tailwind with custom theme and plugins \ No newline at end of file