Skip to content
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

Celine/expanding menu #20

Closed
wants to merge 11 commits into from
33 changes: 31 additions & 2 deletions api/supabase/queries/events.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,45 @@
import { UUID } from 'crypto';
import supabase from '../createClient';

export async function fetchAllEvents() {
const { data, error } = await supabase.from('events').select('*');

if (error) {
console.error('An error occurred trying to read events:', error);
return null;
throw error;
}

return data;
}

export async function fetchAcceptedEventsByVolunteer(volunteer_id: UUID) {
const { data, error } = await supabase
.from('event_signups')
.select('*')
.eq('volunteer_id', volunteer_id)
.eq('is_accepted', true);

if (error) {
throw error;
}
if (!data || data.length === 0) {
//No accepted events for volunteer found
return [];
}

const eventIDs = data.map(data => data.event_id);

const { data: events, error: eventsError } = await supabase
.from('events')
.select('*')
.in('event_id', eventIDs);

if (eventsError) {
throw eventsError;
}

return events;
}

// fetches all events that have event_status = 'ACTIVE'
export async function fetchAllActiveEvents() {
const { data, error } = await supabase
Expand Down
129 changes: 129 additions & 0 deletions app/(auth)/auth-styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import styled from 'styled-components';
import COLORS from '@/styles/colors';
import { Sans } from '@/styles/fonts';
import { H3, P } from '@/styles/text';

export const Container = styled.div`
font-family: ${Sans.style.fontFamily}, sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
background-color: ${COLORS.gray2};
padding: 1rem;
`;

export const Header = styled(H3)`
margin-bottom: 1rem;
text-align: center;
`;

export const Card = styled.div`
background-color: ${COLORS.bread1};
padding: 2rem;
border-radius: 12px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
max-width: 400px;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
`;

export const Form = styled.div`
display: flex;
flex-direction: column;
align-items: stretch;
width: 100%;
gap: 0.5rem;
`;

export const Label = styled(P)`
font-family: ${Sans.style.fontFamily};
font-weight: 500;
margin-bottom: -0.2rem;
`;

export const Input = styled.input`
font-family: ${Sans.style.fontFamily};
padding: 0.7rem;
border: 1px solid ${COLORS.gray4};
border-radius: 8px;
width: 100%;
margin-bottom: 0.6rem;
box-sizing: border-box;
`;

export const Button = styled.button`
font-family: ${Sans.style.fontFamily};
background-color: ${COLORS.gray12};
color: white;
font-size: 1rem;
padding: 0.75rem;
border: none;
border-radius: 8px;
cursor: pointer;
margin-top: 0.8rem;
width: 100%;
`;

export const GoogleButton = styled(Button)`
background-color: ${COLORS.bread1};
color: ${COLORS.gray12};
font-size: 1rem;
// TODO: Update to COLORS.black if that gets added
border: 1px solid #000000;
margin-top: 0rem;
`;

export const Separator = styled.div`
display: flex;
align-items: center;
text-align: center;
margin: 0.2rem;

&::before,
&::after {
content: '';
flex: 1;
border-bottom: 1px solid ${COLORS.gray5};
}

span {
margin: 0 0.5rem;
color: ${COLORS.gray7};
}
`;

export const Link = styled.a`
font-family: ${Sans.style.fontFamily};
// TODO: CHANGE COLOR TO BLUE ONCE COLORS.TS IS UPDATED
color: #3978ff;
text-decoration: none;

&:hover {
text-decoration: underline;
}
`;

export const SmallBuffer = styled.div`
height: 0.5rem;
`;

// TODO: Temporarily added to verify that supabase login functionality actually works
export const LoginMessage = styled(P)<{ isError: boolean }>`
font-family: ${Sans.style.fontFamily};
color: ${({ isError }) => (isError ? 'red' : 'green')};
text-align: center;
margin-top: 0.5rem;
`;

export const Footer = styled.div`
font-family: ${Sans.style.fontFamily};
text-align: center;
margin-top: 1rem;
width: 100%;
padding: 0.5rem;
`;
89 changes: 89 additions & 0 deletions app/(auth)/signin/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use client';

import { useState } from 'react';
import supabase from '@/api/supabase/createClient';
import { H5 } from '@/styles/text';
import {
Button,
Card,
Container,
Footer,
Form,
GoogleButton,
Header,
Input,
Label,
Link,
LoginMessage,
Separator,
SmallBuffer,
} from '../auth-styles';

export default function SignIn() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
const [isError, setIsError] = useState(false);

// handle sign in w/ supabase, borrowed from Immigration Justice PR
const handleSignIn = async () => {
setMessage('');
setIsError(false);
const { error } = await supabase.auth.signInWithPassword({
email,
password,
});

// Ik this wasn't part of the sprint but I added so I could verify that supabase functionality is working
if (error) {
setMessage(`Login failed: ${error.message}`);
setIsError(true);
} else {
setMessage('Login successful!');
setIsError(false);
}
};

// Front-end interface
return (
<Container>
<Header>Welcome Back!</Header>
<SmallBuffer />
<Card>
<Form>
<H5>Login</H5>
<SmallBuffer />
<Label>
Email <span style={{ color: 'red' }}>*</span>
</Label>
<Input
name="email"
placeholder="[email protected]"
onChange={e => setEmail(e.target.value)}
value={email}
/>
<Label>
Password <span style={{ color: 'red' }}>*</span>
</Label>
<Input
type="password"
name="password"
placeholder="Password"
onChange={e => setPassword(e.target.value)}
value={password}
/>
<Button onClick={handleSignIn}>Sign In</Button>
<Separator>
<span>or</span>
</Separator>
<GoogleButton>Continue with Google</GoogleButton>
{message && <LoginMessage isError={isError}>{message}</LoginMessage>}
</Form>
</Card>
<SmallBuffer />
<Footer>
Don’t have an account? <Link href="/signup">Sign up!</Link>
</Footer>
</Container>
);
}
106 changes: 106 additions & 0 deletions app/(auth)/signup/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use client';

import { useState } from 'react';
import supabase from '@/api/supabase/createClient';
import { H5 } from '@/styles/text';
import {
Button,
Card,
Container,
Footer,
Form,
GoogleButton,
Header,
Input,
Label,
Link,
LoginMessage,
Separator,
SmallBuffer,
} from '../auth-styles';

export default function SignUp() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmedPassword, setConfirmedPassword] = useState('');
const [message, setMessage] = useState('');
const [isError, setIsError] = useState(false);

const handleSignUp = async () => {
setMessage('');
setIsError(false);

if (password !== confirmedPassword) {
setMessage('Sign-up failed: Passwords do not match');
setIsError(true);
return;
}

const { error } = await supabase.auth.signUp({
email,
password,
});

// Ik this wasn't part of the sprint but I added so I could verify that supabase functionality is working
if (error) {
setMessage(`Sign-up failed: ${error.message}`);
setIsError(true);
} else {
setMessage('Sign-up successful!');
setIsError(false);
}
};

// Front-end interface
return (
<Container>
<Header>Welcome!</Header>
<SmallBuffer />
<Card>
<Form>
<H5>Sign Up</H5>
<SmallBuffer />
<Label>
Email <span style={{ color: 'red' }}>*</span>
</Label>
<Input
name="email"
placeholder="[email protected]"
onChange={e => setEmail(e.target.value)}
value={email}
/>
<Label>
Password <span style={{ color: 'red' }}>*</span>
</Label>
<Input
type="password"
name="password"
placeholder="Password"
onChange={e => setPassword(e.target.value)}
value={password}
/>
<Label>
Confirm Password <span style={{ color: 'red' }}>*</span>
</Label>
<Input
type="password"
name="confirm password"
placeholder="Confirm Password"
onChange={e => setConfirmedPassword(e.target.value)}
value={confirmedPassword}
/>
<Button onClick={handleSignUp}>Sign Up</Button>
<Separator>
<span>or</span>
</Separator>
<GoogleButton>Continue with Google</GoogleButton>
{message && <LoginMessage isError={isError}>{message}</LoginMessage>}
</Form>
</Card>
<SmallBuffer />
<Footer>
Already have an account? <Link href="/signin">Sign in!</Link>
</Footer>
</Container>
);
}
Loading
Loading