Skip to content

Winjolu #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 73 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
73 commits
Select commit Hold shift + click to select a range
1678e44
set dotenv variables
winjolu Jul 23, 2024
c416b2f
abstracted .env variables
winjolu Jul 24, 2024
e36c3ec
abstracted .env variables
winjolu Jul 24, 2024
0e7ccf7
added require('dotenv').config() to server js, added openAI endpoint …
austinbfraser Jul 24, 2024
9e06696
Add files via upload
davisdoescoding Jul 25, 2024
7c0944a
Delete client directory
davisdoescoding Jul 25, 2024
4cecd04
Delete .vscode directory
davisdoescoding Jul 25, 2024
b26dbf8
Delete components directory
davisdoescoding Jul 25, 2024
7e99fa3
Delete public directory
davisdoescoding Jul 25, 2024
8218252
Delete server directory
davisdoescoding Jul 25, 2024
cfd0b57
Delete Routes.js
davisdoescoding Jul 25, 2024
605403c
Delete index.js
davisdoescoding Jul 25, 2024
d0351b5
Delete index.css
davisdoescoding Jul 25, 2024
e974fc5
Delete package-lock.json
davisdoescoding Jul 25, 2024
1e0b52c
Delete Auth directory
davisdoescoding Jul 25, 2024
f7864e7
Delete Pages directory
davisdoescoding Jul 25, 2024
0e33d30
Delete Server/Controllers/userController.js
davisdoescoding Jul 25, 2024
5e3b146
Update package.json
davisdoescoding Jul 25, 2024
02f33e5
Added:
davisdoescoding Jul 25, 2024
f6337ae
Merge pull request #1 from BATFISH-XV/davisdoescoding-patch-1
davisdoescoding Jul 25, 2024
4fa7553
Co-authored-by: Austin Fraser <austinbfraser@users.noreply.github.com>
davisdoescoding Jul 25, 2024
f237fde
Merge pull request #2 from BATFISH-XV/davisdoescoding-patch-1
davisdoescoding Jul 25, 2024
7596791
fixed authentication
davisdoescoding Jul 25, 2024
7078f1f
Merge pull request #3 from BATFISH-XV/davisdoescoding-patch-1
davisdoescoding Jul 25, 2024
063134c
replace supabase signIn with .signInWithPassword
davisdoescoding Jul 25, 2024
0b5afc3
Merge pull request #4 from BATFISH-XV/davisdoescoding-patch-1
davisdoescoding Jul 25, 2024
3f9f44b
added 5th field to ImageGenerationForm, updated OpenAI prompt accordi…
austinbfraser Jul 25, 2024
02a1115
Merge pull request #5 from Stabb-it/austin-5thfield
austinbfraser Jul 25, 2024
9603a96
adding 'sign up button'
davisdoescoding Jul 26, 2024
3f65122
Update index.css
davisdoescoding Jul 26, 2024
4854f44
Update Routes.js
davisdoescoding Jul 26, 2024
285bfe7
Update Login.jsx
davisdoescoding Jul 26, 2024
849daac
Update ResponsiveAppBar.jsx
davisdoescoding Jul 26, 2024
f565180
Delete Client/Pages/HomePage.css
davisdoescoding Jul 26, 2024
d677c1f
Update HomePage.jsx
davisdoescoding Jul 26, 2024
32cce12
Create AuthForm.css
davisdoescoding Jul 26, 2024
58e52f9
Update index.js
davisdoescoding Jul 26, 2024
7eb0c7c
converted HomePage into parent container
davisdoescoding Jul 26, 2024
9f294a5
Merge branch 'davisdoescoding-patch-1' of https://github.com/BATFISH-…
davisdoescoding Jul 26, 2024
444a664
added speech recognition feature
austinbfraser Jul 26, 2024
6dcca48
Merge pull request #6 from Stabb-it/austin
austinbfraser Jul 26, 2024
b90d5ec
Updated auth triggers and pinwheel
davisdoescoding Jul 26, 2024
c5ba8cb
Additional file renaming structure to supoort scaleable features.
davisdoescoding Jul 26, 2024
00744d6
open-cli fro npm start
winjolu Jul 27, 2024
f9d9520
-Refactored auth context to get user metadata and session details
davisdoescoding Jul 27, 2024
831c2c4
Added back on personal comments
davisdoescoding Jul 27, 2024
22dd39e
Update package.json
davisdoescoding Jul 27, 2024
7fed5e0
Delete Client/components/ImageGenerationForm.jsx
davisdoescoding Jul 27, 2024
ea05921
Create AuthProviderDebugger.jsx
davisdoescoding Jul 27, 2024
e851877
Create MyAccount.jsx
davisdoescoding Jul 27, 2024
63b12d3
stage
winjolu Jul 27, 2024
f87c899
merge conflicts
winjolu Jul 27, 2024
d8c2fc4
merge conflicts
winjolu Jul 27, 2024
25a318c
'additional' added to opnAI generator
davisdoescoding Jul 27, 2024
9a90afe
Merge pull request #9 from Stabb-it/davisdoescoding-patch-1
davisdoescoding Jul 27, 2024
30edc44
Merge branch 'dev' of https://github.com/BATFISH-XV/fashion-selector …
davisdoescoding Jul 27, 2024
6c994bd
Merge branch 'dev' of https://github.com/Stabb-it/fashion-selector in…
austinbfraser Jul 27, 2024
786f22d
test message
austinbfraser Jul 27, 2024
640fe62
Merge branch 'dev' of https://github.com/Stabb-it/fashion-selector in…
austinbfraser Jul 27, 2024
1d546a1
REMOVE PACKAGE-LOCK
davisdoescoding Jul 27, 2024
88facb7
restoring after saturday git issues and added package-lock.json to gi…
austinbfraser Jul 27, 2024
6ad8b94
conflicts
winjolu Jul 27, 2024
c1d2e77
merge conflicts
winjolu Jul 27, 2024
ce931f7
commiting mystery changes while trying to pull dev
austinbfraser Jul 27, 2024
14b721c
merge conflicts
winjolu Jul 27, 2024
970a047
added components/generic folder and Button.style.jsx - reusable style…
austinbfraser Jul 27, 2024
54b96e7
Merge pull request #11 from Stabb-it/austin-search
austinbfraser Jul 27, 2024
a650a03
session mgmt
winjolu Jul 28, 2024
ae54512
merge
winjolu Jul 28, 2024
e41cc75
debugging session mgmt
winjolu Jul 28, 2024
7f4404d
production mode
winjolu Jul 30, 2024
f6f76af
optimize dist/budle.js
winjolu Jul 30, 2024
0c19e76
ketchup
winjolu Aug 2, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.env
node_modules
.env
node_modules/
package-lock.json
93 changes: 93 additions & 0 deletions Client/Auth/AuthContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import React, { createContext, useContext, useState, useEffect } from 'react';
import axios from 'axios';

/**
* Context object created
*/
const AuthContext = createContext();

/**
* Functional component that will use the Provider functionality in the AuthContext to
* share the state and functions with child components.
* AuthContext : { ..., Provider: {the auth state}}
* @param {*} children deconstructed prop - refers to any nested components wrapped by AuthProvider
* in the virtual DOM (see client/index.js)
* @returns
*/
export const AuthProvider = ({ children }) => {

/**
* State variables and setters for holding top level authentication information
*/
const [user, setUser] = useState(null);
const [session, setSession] = useState(null);
const [avatarUrl, setAvatarUrl] = useState(null);
const [loading, setLoading] = useState(true);

/**
* sessionStorage does not persist beyond the current session,
* only accessible in the same window/tab and cleared when either closed.
* Stored in memory on web browser, not written to disk like cookies
*/
useEffect(() => {
const storedUser = JSON.parse(sessionStorage.getItem('user'));
const storedSession = JSON.parse(sessionStorage.getItem('session'));
const storedAvatarUrl = sessionStorage.getItem('avatarUrl');
if (storedUser) {
setUser(storedUser);
}
if (storedSession) {
setSession(storedSession);
}
if (storedAvatarUrl) {
setAvatarUrl(storedAvatarUrl);
}
setLoading(false); // Indicates that the data fetching has completed
}, []);

/**
* Async function that makes a request
* @param {*} user
* @param {*} session
*/
const login = async (user, session) => {
setUser(user);
setSession(session);
fetchAvatarUrl(user.id);
sessionStorage.setItem('user', JSON.stringify(user));
sessionStorage.setItem('session', JSON.stringify(session));
};

const fetchAvatarUrl = async (userId) => {
try {
const response = await axios.get(`/api/user-profile/${userId}`);
const avatarUrl = response.data.avatar_url;
setAvatarUrl(avatarUrl);
sessionStorage.setItem('avatarUrl', avatarUrl);
} catch (error) {
console.error('Error fetching avatar URL:', error);
}
};

const logout = () => {
setUser(null);
setSession(null);
setAvatarUrl(null);
sessionStorage.removeItem('user');
sessionStorage.removeItem('session');
sessionStorage.removeItem('avatarUrl');
};

/**
* Using React
*/
return (
<AuthContext.Provider value={{ user, session, avatarUrl, login, logout, loading }}>
{children}
</AuthContext.Provider>
);
};

export const useAuth = () => {
return useContext(AuthContext);
};
35 changes: 35 additions & 0 deletions Client/Auth/AuthProviderDebugger.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import { useAuth } from './AuthContext'; // Adjust the path as needed

const style = {
position: 'fixed',
bottom: '10px',
right: '10px',
width: 300,
bgcolor: 'background.paper',
border: '2px solid #000',
boxShadow: 24,
p: 2,
zIndex: 1000,
overflow: 'auto',
maxHeight: '50vh',
};

const AuthProviderDebugger = () => {
const { user, session, avatarUrl } = useAuth();

return (
<Box sx={style}>
<Typography variant="h6" component="h2">
AuthContext Debug Info
</Typography>
<Box sx={{ mt: 2 }}>
<pre>{JSON.stringify({ user, session, avatarUrl }, null, 2)}</pre>
</Box>
</Box>
);
};

export default AuthProviderDebugger;
79 changes: 79 additions & 0 deletions Client/Auth/Login.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useState } from 'react';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
import { Typography, CircularProgress, Snackbar, Alert } from '@mui/material';
import { useAuth } from './AuthContext';
import AuthNavigationButton from '../components/AuthNavigationButton';
import '../styles/AuthForm.css';

/**
* User-side functionality for existing user at login and route path
* @returns
*/
const Login = () => {
/**
* local state for email, password, loading
*/
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [snackbar, setSnackbar] = useState({ open: false, message: '', severity: '' });
const history = useHistory();
const { login } = useAuth();

const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
const response = await axios.post('/api/login', { email, password });
const { user, session } = response.data;
login(user, session);
setSnackbar({ open: true, message: 'Login successful', severity: 'success' });
setTimeout(() => {
history.push('/search');
}, 1200);
} catch (error) {
setSnackbar({ open: true, message: 'Login failed', severity: 'error' });
console.error('AxiosError:', error);
} finally {
setLoading(false);
}
};

const handleCloseSnackbar = () => {
setSnackbar({ ...snackbar, open: false });
};

return (
<div className="auth-container">
<div className="auth-form">
<Typography variant="h4" style={{ marginBottom: '1rem' }}>Login</Typography>
<form onSubmit={handleSubmit}>
<label>Email:</label>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
<label>Password:</label>
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
<button type="submit" disabled={loading}>Login</button>
</form>
{loading && (
<div className="center-loading">
<CircularProgress />
</div>
)}
</div>
<AuthNavigationButton navigateTo="/signup" label="Don't have an account? Sign-Up" />
<Snackbar
open={snackbar.open}
autoHideDuration={6000}
onClose={handleCloseSnackbar}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }} // Center the Snackbar at the top
>
<Alert onClose={handleCloseSnackbar} severity={snackbar.severity} sx={{ width: '100%' }}>
{snackbar.message}
</Alert>
</Snackbar>
</div>
);
};

export default Login;
13 changes: 13 additions & 0 deletions Client/Auth/LoginStatus.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import { useAuth } from './AuthContext';

const LoginStatus = () => {
const { user } = useAuth();
return (
<div className="login-status">
{user ? `Logged in as: ${user.user_metadata.first_name}` : 'Not logged in'}
</div>
);
};

export default LoginStatus;
84 changes: 84 additions & 0 deletions Client/Auth/Signup.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React, { useState } from 'react';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
import { Typography, CircularProgress, Snackbar, Alert } from '@mui/material';
import { useAuth } from './AuthContext';
import AuthNavigationButton from '../components/AuthNavigationButton';
import '../styles/AuthForm.css';

const Signup = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
const [loading, setLoading] = useState(false);
const [snackbar, setSnackbar] = useState({ open: false, message: '', severity: '' });
const history = useHistory();
const { login } = useAuth();

const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
const response = await axios.post('/api/signup', { email, password, firstName, lastName });
const { user, session } = response.data;
login(user, session);
setTimeout(() => {
setSnackbar({ open: true, message: 'Signup successful', severity: 'success' });
setTimeout(() => {
history.push('/search');
}, 2000); // Redirect after 2 seconds to ensure the user sees the Snackbar
}, 1000); // Ensure spinner shows for at least 1 second
} catch (error) {
setTimeout(() => {
setSnackbar({ open: true, message: 'Signup failed', severity: 'error' });
}, 1000); // Ensure spinner shows for at least 1 second
console.error('AxiosError:', error);
} finally {
setTimeout(() => {
setLoading(false);
}, 1000); // Ensure spinner shows for at least 1 second
}
};

const handleCloseSnackbar = () => {
setSnackbar({ ...snackbar, open: false });
};

return (
<div className="auth-container">
<div className="auth-form">
<Typography variant="h4" style={{ marginBottom: '1rem' }}>Signup</Typography>
<form onSubmit={handleSubmit}>
<label>Email:</label>
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} required />
<label>Password:</label>
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} required />
<label>First Name:</label>
<input type="text" value={firstName} onChange={(e) => setFirstName(e.target.value)} required />
<label>Last Name:</label>
<input type="text" value={lastName} onChange={(e) => setLastName(e.target.value)} required />
<button type="submit" disabled={loading}>Signup</button>
</form>
{loading && (
<div className="center-loading">
<CircularProgress />
</div>
)}
</div>
<AuthNavigationButton navigateTo="/login" label="Already Have an Account? Login" />
<Snackbar
open={snackbar.open}
autoHideDuration={6000}
onClose={handleCloseSnackbar}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }} // Center the Snackbar at the top
>
<Alert onClose={handleCloseSnackbar} severity={snackbar.severity} sx={{ width: '100%' }}>
{snackbar.message}
</Alert>
</Snackbar>
</div>
);
};

export default Signup;
25 changes: 25 additions & 0 deletions Client/Pages/About.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { Container, Typography, Paper } from '@mui/material';

const About = () => {
return (
<Container maxWidth="md" style={{ marginTop: '100px' }}> {/* Adjust marginTop as needed */}
<Paper elevation={3} style={{ padding: '20px', backgroundColor: 'rgba(255, 255, 255, 0.8)' }}>
<Typography variant="h2" gutterBottom>
About Fashion Selector
</Typography>
<Typography variant="body1" paragraph>
Fashion Selector is your AI-powered fashion assistant, designed to help you discover and refine your personal style.
</Typography>
<Typography variant="body1" paragraph>
Our mission is to make fashion accessible and enjoyable for everyone. Whether you're looking for outfit inspiration or trying to build a wardrobe that truly reflects your personality, Fashion Selector is here to guide you.
</Typography>
<Typography variant="body1">
Explore, experiment, and express yourself through fashion with us!
</Typography>
</Paper>
</Container>
);
};

export default About;
10 changes: 10 additions & 0 deletions Client/Pages/HomePage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import Login from '../Auth/Login'; // Adjust the path as needed

const HomePage = () => {
return (
<Login />
);
};

export default HomePage;
Loading