Skip to content

Commit 5d6fae1

Browse files
authored
Merge pull request #31 from cherryontech/feat/profile
Feat/profile
2 parents 8009816 + 3dc3ba2 commit 5d6fae1

10 files changed

Lines changed: 316 additions & 102 deletions

File tree

src/App.css

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
button:not(.toggle-btn):focus-visible {
1+
button:not(.toggle-btn):not(.delete-btn):focus-visible {
22
outline: solid 4px var(--color-persianblue);
33
outline-offset: 8px;
44
}
5-
button:not(.toggle-btn):hover {
5+
button:not(.toggle-btn):not(.delete-btn):hover {
66
background-color: var(--color-zinc);
77
color: white;
88
cursor: pointer;
99
}
10-
button:not(.toggle-btn):active {
10+
button:not(.toggle-btn):not(.delete-btn):active {
1111
background-color: var(--color-persianblue);
1212
color: white;
1313
}
@@ -17,4 +17,4 @@ button.active {
1717
}
1818
button.active:hover {
1919
background-color: var(--color-persianblue);
20-
}
20+
}

src/components/Baseinput.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function Baseinput({
3333
block w-full h-11 px-4 py-2
3434
bg-white text-black
3535
${inputClassName}
36-
disabled:bg-gray-100 disabled:text-gray-500`}
36+
disabled:bg-white disabled:text-eerie`}
3737
aria-invalid={ariaInvalid}
3838
aria-describedby={ariaDescribedBy}
3939
disabled={disabled}

src/components/Button.jsx

Lines changed: 58 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,68 @@ import { useNavigate } from 'react-router-dom';
22
import { tv } from 'tailwind-variants/lite';
33

44
const buttonVariants = tv({
5-
// base styles for all buttons
6-
base: 'font-poppins flex items-center justify-center drop-shadow-[0_4px_4px_rgba(0,0,0,0.25)]',
7-
// all button variants
8-
variants: {
9-
size: {
10-
sm: 'h-12 w-[162px] text-base font-semibold rounded-lg lg:h-14 lg:w-[220px] lg:text-xl',
11-
md: 'h-11 w-[218px] text-base font-semibold rounded-lg lg:h-14 lg:w-[286px] lg:text-xl xl:h-16 xl:w-[327px] xl:text-2xl',
12-
lg: 'h-11 w-[345px] text-base font-medium rounded-md lg:w-[501px]',
13-
circ: 'h-11 w-11 text-2xl rounded-full'
14-
},
15-
color: {
16-
primary: 'bg-eerie text-white border-1 border-eerie',
17-
secondary: 'bg-white text-eerie border-1 border-eerie',
18-
gradient: 'bg-gradient-to-b from-electricgreen to-persianblue text-white'
19-
}
5+
// base styles for all buttons
6+
base: 'font-poppins flex items-center justify-center drop-shadow-[0_4px_4px_rgba(0,0,0,0.25)]',
7+
// all button variants
8+
variants: {
9+
size: {
10+
sm: 'h-12 w-[162px] text-base font-semibold rounded-lg lg:h-14 lg:w-[220px] lg:text-xl',
11+
md: 'h-11 w-[218px] text-base font-semibold rounded-lg lg:h-14 lg:w-[286px] lg:text-xl xl:h-16 xl:w-[327px] xl:text-2xl',
12+
lg: 'h-11 w-[345px] text-base font-medium rounded-md lg:w-[501px]',
13+
circ: 'h-11 w-11 text-2xl rounded-full',
2014
},
21-
// default button styles if no specified props
22-
defaultVariants: {
23-
size: 'sm',
24-
color: 'primary'
15+
color: {
16+
primary: 'bg-eerie text-white border-1 border-eerie',
17+
secondary: 'bg-white text-eerie border-1 border-eerie',
18+
gradient: 'bg-gradient-to-b from-electricgreen to-persianblue text-white',
2519
},
26-
// conditional style cases for specific prop combinations
27-
compoundVariants: [
28-
// remove drop shadow and lower font weight for user selection button
29-
{
30-
color: 'secondary',
31-
size: 'md',
32-
className: 'drop-shadow-none !font-normal'
33-
}
34-
]
20+
},
21+
// default button styles if no specified props
22+
defaultVariants: {
23+
size: 'sm',
24+
color: 'primary',
25+
},
26+
// conditional style cases for specific prop combinations
27+
compoundVariants: [
28+
// remove drop shadow and lower font weight for user selection button
29+
{
30+
color: 'secondary',
31+
size: 'md',
32+
className: 'drop-shadow-none !font-normal',
33+
},
34+
],
3535
});
3636

37-
export default function Button({ size, color, label, onClick, isActive, to, ...props }) {
38-
let navigate = useNavigate();
37+
export default function Button({
38+
size,
39+
color,
40+
label,
41+
onClick,
42+
isActive,
43+
to,
44+
...props
45+
}) {
46+
let navigate = useNavigate();
3947

40-
function handleClick(){
41-
if (to){
42-
navigate(to);
43-
} else {
44-
onClick();
45-
}
48+
function handleClick() {
49+
if (to) {
50+
navigate(to);
51+
} else {
52+
onClick();
4653
}
54+
}
4755

48-
return (
49-
<button onClick={handleClick} className={isActive ? `${buttonVariants({ size, color })} active` : buttonVariants({ size, color })}
50-
{...props}
51-
>{label}
52-
</button>
53-
);
54-
}
56+
return (
57+
<button
58+
onClick={handleClick}
59+
className={
60+
isActive
61+
? `${buttonVariants({ size, color })} active`
62+
: buttonVariants({ size, color })
63+
}
64+
{...props}
65+
>
66+
{label}
67+
</button>
68+
);
69+
}

src/components/Navbar.jsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { HiMenu } from 'react-icons/hi';
99
//components
1010
import MobileMenu from './MobileMenu';
1111

12+
//firebase
13+
import { auth } from '../firebase';
14+
import { signOut } from 'firebase/auth';
15+
1216
function Navbar() {
1317
const [isMenuOpen, setIsMenuOpen] = useState(false); // mobile menu state
1418
const [isAuthenticated, setIsAuthenticated] = useState(false); // user authentication state
@@ -27,10 +31,15 @@ function Navbar() {
2731

2832
const toggleMenu = () => setIsMenuOpen(!isMenuOpen);
2933

30-
const handleLogout = () => {
31-
localStorage.removeItem('authToken');
32-
setIsAuthenticated(false);
33-
navigate('/logout');
34+
const handleLogout = async () => {
35+
try {
36+
await signOut(auth);
37+
localStorage.removeItem('authToken');
38+
setIsAuthenticated(false);
39+
navigate('/logout');
40+
} catch (error) {
41+
console.error('Logout failed:', error);
42+
}
3443
};
3544

3645
// navbar for NON-authenticated user
@@ -123,15 +132,15 @@ function Navbar() {
123132
Detox Challenge
124133
</Link>
125134
</li>
126-
<li>
135+
<li>
127136
<Link
128137
to="community"
129138
className="text-stone-900 text-base font-normal font-playfair hover:font-bold focus:outline-none focus-visible:ring-2 focus-visible:ring-persianblue focus-visible:p-2 rounded-[5px]"
130139
>
131140
Community Forum
132141
</Link>
133142
</li>
134-
143+
135144
<li>
136145
<Link
137146
to="/profile"

src/firebase.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Import the functions you need from the SDKs you need
2-
import { initializeApp } from "firebase/app";
3-
import { getFirestore } from "firebase/firestore";
2+
import { initializeApp } from 'firebase/app';
3+
import { getFirestore } from 'firebase/firestore';
4+
import { getAuth } from 'firebase/auth';
45

56
// TODO: Add SDKs for Firebase products that you want to use
67
// https://firebase.google.com/docs/web/setup#available-libraries
@@ -12,12 +13,12 @@ const firebaseConfig = {
1213
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
1314
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
1415
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
15-
appId: import.meta.env.VITE_FIREBASE_APP_ID
16+
appId: import.meta.env.VITE_FIREBASE_APP_ID,
1617
};
1718

1819
// Initialize Firebase
1920
const app = initializeApp(firebaseConfig);
20-
21+
const auth = getAuth(app);
2122
// Initialize Cloud Firestore and get a reference to the service
2223
const db = getFirestore(app);
23-
export { db };
24+
export { db, auth };

src/main.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Signup from './pages/Signup';
1313
import Journal from './pages/journal';
1414
import Logout from './pages/Logout';
1515
import Challenges from './pages/Challenges';
16+
import Profile from './pages/Profile';
1617
import App from './App';
1718

1819
const router = createBrowserRouter([
@@ -29,9 +30,10 @@ const router = createBrowserRouter([
2930
{ path: 'achievements', element: <Achievements /> },
3031
{ path: 'journal', element: <Journal /> },
3132
{ path: 'logout', element: <Logout /> },
33+
{ path: 'profile', element: <Profile /> },
3234
{ path: 'error', element: <Error /> },
3335
{ path: 'challenges', element: <Challenges /> },
34-
],
36+
],
3537
},
3638
{
3739
path: '*',
@@ -42,4 +44,4 @@ createRoot(document.getElementById('root')).render(
4244
<StrictMode>
4345
<RouterProvider router={router} />
4446
</StrictMode>
45-
);
47+
);

src/pages/Login.jsx

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,49 @@ import Passwordinput from '../components/PasswordInput';
33
import Button from '../components/Button';
44
import { useState } from 'react';
55
import { Link, useNavigate } from 'react-router-dom';
6+
import { signInWithEmailAndPassword } from 'firebase/auth';
7+
import { auth } from '../firebase';
68

79
function Login() {
810
const navigate = useNavigate();
911
const [formValues, setFormValues] = useState({});
1012
const [isValidEmail, setisValidEmail] = useState(false);
1113
const [isValidPassword, setisValidPassword] = useState(false);
1214
const [formSubmitMessage, setFormSubmitMessage] = useState('');
15+
const buttonStyles =
16+
'h-11 w-[345px] text-base font-medium rounded-md lg:w-[501px] bg-eerie text-white border-1 border-eerie';
1317
const setFormValue = (fieldName, value) => {
1418
setFormValues((prevValue) => ({ ...prevValue, [fieldName]: value }));
1519
};
16-
const handleSubmit = (e) => {
20+
const handleSubmit = async (e) => {
1721
e.preventDefault();
1822
if (!isValidEmail || !isValidPassword) {
1923
setFormSubmitMessage('Fill form properly');
2024
} else {
21-
localStorage.setItem('authToken', 'my-auth-token');
25+
//localStorage.setItem('authToken', 'my-auth-token');
2226
const loginFormData = new FormData();
2327
for (const key in formValues) {
2428
loginFormData.append(key, formValues[key]);
2529
}
26-
navigate('/dashboard');
30+
try {
31+
const { user } = await signInWithEmailAndPassword(
32+
auth,
33+
formValues.loginEmail,
34+
formValues.loginPassword
35+
);
36+
console.log('Logged in user is: ', user.uid);
37+
localStorage.setItem('authToken', user.uid);
38+
navigate('/dashboard');
39+
} catch (error) {
40+
if (error.code === 'auth/user-not-found') {
41+
setFormSubmitMessage('No user found with this email');
42+
} else if (error.code === 'auth/wrong-password') {
43+
setFormSubmitMessage('No usr found with this email');
44+
} else {
45+
setFormSubmitMessage('Login failed. Try again.');
46+
}
47+
}
48+
2749
console.log('Login Submission Data:', loginFormData);
2850
}
2951
};
@@ -84,7 +106,9 @@ function Login() {
84106
</p>
85107
)}
86108
<div className="flex justify-center">
87-
<Button size="lg" color="primary" label="Sign in" />
109+
<button type="submit" className={buttonStyles}>
110+
Sign in
111+
</button>
88112
</div>
89113
<div className="mt-[12px]">
90114
New user?{' '}
@@ -100,4 +124,4 @@ function Login() {
100124
);
101125
}
102126

103-
export default Login;
127+
export default Login;

0 commit comments

Comments
 (0)