diff --git a/package-lock.json b/package-lock.json index ed55cd0..41622ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "habit-tracker-fullstack", "version": "1.0.0", "dependencies": { + "framer-motion": "^11.11.17", "lucide-react": "^0.344.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -2952,6 +2953,31 @@ "url": "https://github.com/sponsors/rawify" } }, + "node_modules/framer-motion": { + "version": "11.11.17", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-11.11.17.tgz", + "integrity": "sha512-O8QzvoKiuzI5HSAHbcYuL6xU+ZLXbrH7C8Akaato4JzQbX2ULNeniqC2Vo5eiCtFktX9XsJ+7nUhxcl2E2IjpA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@emotion/is-prop-valid": "*", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "peerDependenciesMeta": { + "@emotion/is-prop-valid": { + "optional": true + }, + "react": { + "optional": true + }, + "react-dom": { + "optional": true + } + } + }, "node_modules/fs-extra": { "version": "11.2.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", @@ -4618,8 +4644,7 @@ "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, "node_modules/type-check": { "version": "0.4.0", diff --git a/package.json b/package.json index 6a10245..c9e972f 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "framer-motion": "^11.11.17", "lucide-react": "^0.344.0", "react": "^18.3.1", "react-dom": "^18.3.1", diff --git a/src/components/Login.tsx b/src/components/Login.tsx index 62eeda2..ffbe172 100644 --- a/src/components/Login.tsx +++ b/src/components/Login.tsx @@ -1,6 +1,8 @@ import { useState } from 'react'; import { useAuth } from '../contexts/AuthContext'; import { useThemeContext } from '../contexts/ThemeContext'; +import { motion } from 'framer-motion'; +import { Circle } from 'lucide-react'; export function Login({ onSwitchToSignUp }: { onSwitchToSignUp: () => void }) { const [email, setEmail] = useState(''); @@ -14,53 +16,138 @@ export function Login({ onSwitchToSignUp }: { onSwitchToSignUp: () => void }) { try { setError(''); await signIn(email, password); - } catch (error) { + } catch { setError('Failed to sign in'); } }; return ( -
-
-

Log In

- {error &&
{error}
} -
-
- setEmail(e.target.value)} - placeholder="Email" - className={`w-full px-4 py-2 rounded-lg ${theme.input}`} - required - /> -
-
- setPassword(e.target.value)} - placeholder="Password" - className={`w-full px-4 py-2 rounded-lg ${theme.input}`} - required - /> -
- -
-

- Don't have an account?{' '} -

+ + {/* Content */} +
+

+ welcome
back. +

+

+ Continue your journey to better habits. +

+
+
+ + {/* Right Panel - Form */} +
+ {/* Mobile Header - Added */} +
+

welcome back.

+

+ Continue your journey to better habits. +

+
+ + {/* Mobile Background Decoration - Updated */} +
+ - Sign Up - -

+ +
+ + + +
+ + {/* Form Container - Updated */} +
+
+

Log In

+ {error && ( +
+ {error} +
+ )} +
+
+ setEmail(e.target.value)} + placeholder="Email" + className={`w-full px-4 py-3 rounded-xl ${theme.input} transition-all duration-200 + focus:ring-2 focus:ring-black dark:focus:ring-white border-gray-200 dark:border-gray-700`} + required + /> +
+
+ setPassword(e.target.value)} + placeholder="Password" + className={`w-full px-4 py-3 rounded-xl ${theme.input} transition-all duration-200 + focus:ring-2 focus:ring-black dark:focus:ring-white border-gray-200 dark:border-gray-700`} + required + /> +
+ +
+

+ Don't have an account?{' '} + +

+
+
); diff --git a/src/components/SignUp.tsx b/src/components/SignUp.tsx index 8dbb7ef..1e271f0 100644 --- a/src/components/SignUp.tsx +++ b/src/components/SignUp.tsx @@ -1,6 +1,8 @@ import { useState } from 'react'; import { useAuth } from '../contexts/AuthContext'; import { useThemeContext } from '../contexts/ThemeContext'; +import { motion } from 'framer-motion'; +import { Circle } from 'lucide-react'; export function SignUp({ onSwitchToLogin }: { onSwitchToLogin: () => void }) { const [email, setEmail] = useState(''); @@ -14,53 +16,131 @@ export function SignUp({ onSwitchToLogin }: { onSwitchToLogin: () => void }) { try { setError(''); await signUp(email, password); - } catch (error) { + } catch { setError('Failed to create an account'); } }; return ( -
-
-

Sign Up

- {error &&
{error}
} -
-
- setEmail(e.target.value)} - placeholder="Email" - className={`w-full px-4 py-2 rounded-lg ${theme.input}`} - required - /> -
-
- setPassword(e.target.value)} - placeholder="Password" - className={`w-full px-4 py-2 rounded-lg ${theme.input}`} - required - /> -
- -
-

- Already have an account?{' '} -

+ +
+

+ track
your habit. +

+

+ Build better habits, one day at a time. +

+
+
+ +
+
+

track your habit.

+

+ Build better habits, one day at a time. +

+
+ +
+ - Log In - -

+ +
+ + + +
+ +
+
+

Sign Up

+ {error && ( +
+ {error} +
+ )} +
+
+ setEmail(e.target.value)} + placeholder="Email" + className={`w-full px-4 py-3 rounded-xl ${theme.input} transition-all duration-200 + focus:ring-2 focus:ring-black dark:focus:ring-white border-gray-200 dark:border-gray-700`} + required + /> +
+
+ setPassword(e.target.value)} + placeholder="Password" + className={`w-full px-4 py-3 rounded-xl ${theme.input} transition-all duration-200 + focus:ring-2 focus:ring-black dark:focus:ring-white border-gray-200 dark:border-gray-700`} + required + /> +
+ +
+

+ Already have an account?{' '} + +

+
+
);