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

[feat] create simple interest form component #25

Merged
merged 11 commits into from
Nov 7, 2023
1 change: 0 additions & 1 deletion src/api/supabase/queries/interest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export async function getAllInterests() {
/** Insert a new interest object into supabase interest table. */
export async function insertInterest(interest: Interest) {
const { error } = await supabase.from('interests').insert(interest).select();

if (error) {
throw new Error(`An error occurred trying to insert an interest: ${error}`);
}
Expand Down
24 changes: 11 additions & 13 deletions src/app/cases/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@
import { useEffect, useState } from 'react';
import { UUID } from 'crypto';
import { CaseListing } from '@/types/schema';
import FilterDropdown from '@/components/FilterDropdown';
import { getNCases } from '@/api/supabase/queries/cases';
import ListingCard from '@/components/ListingCard';
import { H1, H2 } from '@/styles/text';
import FilterDropdown from '@/components/FilterDropdown';
import CaseDetailDisplay from '@/components/CaseDetails';
import { H1 } from '@/styles/text';
import {
CardColumn,
CaseDetailDisplay,
CaseDetails,
FiltersContainer,
MainDisplay,
PageContainer,
FiltersContainer,
} from './styles';

type FilterType = {
Expand All @@ -27,6 +26,7 @@ type FilterType = {
export default function Page() {
const [caseData, setCaseData] = useState<CaseListing[]>([]);
const [selectedCard, setSelectedCard] = useState<UUID>();
const [caseInfo, setCaseInfo] = useState<CaseListing>();
const [caseFilters, setCaseFilters] = useState<FilterType>({
remote: 'Remote/In Person',
role: 'Attorney/Interpreter',
Expand All @@ -39,10 +39,10 @@ export default function Page() {
useEffect(() => {
getNCases(20).then(casesData => {
setCaseData(casesData);
setCaseInfo(casesData[0]);
});
}, []);

// page structure
return (
<PageContainer>
<H1>Browse Available Cases</H1>
Expand Down Expand Up @@ -126,16 +126,14 @@ export default function Page() {
key={c.id}
caseData={c}
isSelected={c.id === selectedCard}
onClick={() => setSelectedCard(c.id)}
onClick={() => {
setSelectedCard(c.id);
setCaseInfo(c);
}}
/>
))}
</CardColumn>
<CaseDetailDisplay>
{/* proof of concept -- to turn into component later */}
<CaseDetails>
<H2>Case details.</H2>
</CaseDetails>
</CaseDetailDisplay>
{caseInfo && <CaseDetailDisplay caseData={caseInfo} />}
jinkang-0 marked this conversation as resolved.
Show resolved Hide resolved
</MainDisplay>
</PageContainer>
);
Expand Down
13 changes: 0 additions & 13 deletions src/app/cases/styles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,3 @@ export const CaseDetailDisplay = styled.aside`
position: relative;
width: 100%;
`;

export const CaseDetails = styled.div`
position: sticky;
top: 4rem;
background: white;
width: 90%;
height: 80vh;
border-radius: 20px;
margin: 0 auto;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.25);
padding: 2rem;
border: 1px solid lightgray;
`;
48 changes: 0 additions & 48 deletions src/app/interest/page.tsx

This file was deleted.

45 changes: 45 additions & 0 deletions src/components/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import styled from 'styled-components';

/*
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AMAZING documentation!! thank you for this alvaro :)))

FOR PRIMARY BUTTON USAGE:

Props:
primaryColor (Required) - This color will determine the default background color of the button
secondaryColor (Required) - This color will determine the border color and background color on hover

Example:
<Button primaryColor={COLORS.primaryBlue} secondaryColor={COLORS.primaryBlueClicked} onClick={...}>
[Button text here]
</Button>

FOR SECONDARY BUTTON USAGE:

Props:
primaryColor (Omit) - IMPORTANT: DO NOT PASS IN A primaryColor PROP!!! The background color will be white by default
secondaryColor (Required) - This color will determine the border color and background color on hover

Example:
<Button secondaryColor={COLORS.primaryBlue} onClick={...}>
[Button text here]
</Button>
*/
const Button = styled.button<{
primaryColor?: string;
secondaryColor: string;
}>`
appearance: none;
color: ${props => (props.primaryColor ? 'white' : 'black')};
background: ${props => (props.primaryColor ? props.primaryColor : 'white')};
align-self: flex-end;
padding: 0.625rem 1.25rem;
border-radius: 0.313rem; // 5px
border: 2px solid
${props => (props.primaryColor ? props.primaryColor : props.secondaryColor)};
&:hover {
background: ${props => props.secondaryColor};
color: white;
border-color: ${props => props.secondaryColor};
}
`;

export default Button;
36 changes: 36 additions & 0 deletions src/components/CaseDetails/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* eslint-disable react/jsx-no-comment-textnodes */
import React from 'react';
import { timestampStringToDate, parseDate } from '@/utils/helpers';
import { H1 } from '@/styles/text';
import { CaseListing } from '@/types/schema';
import InterestForm from '../InterestForm';
import {
CaseInterestContainer,
CaseDisplay,
InfoContainer,
Line,
} from './styles';

export default function CaseDetails({ caseData }: { caseData: CaseListing }) {
return (
<CaseDisplay>
<CaseInterestContainer>
<InfoContainer>
<H1>Guatemalan mother and two children seeking protection</H1>
<p>
<strong>Languages: </strong>
{caseData.languages}
</p>
<p>
<strong>Next Court/Filing Date: </strong>
{parseDate(timestampStringToDate(caseData.upcoming_date))}
</p>

<p>{caseData.summary}</p>
</InfoContainer>
<Line />
<InterestForm caseData={caseData} />
</CaseInterestContainer>
</CaseDisplay>
);
}
42 changes: 42 additions & 0 deletions src/components/CaseDetails/styles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styled from 'styled-components';
import { H1 } from '@/styles/text';
import COLORS from '../../styles/colors';

// case detail
export const CaseDisplay = styled.aside`
position: relative;
width: 100%;
`;

export const CaseTitle = styled(H1)`
margin: 0.4rem 4rem;
`;

export const CaseInterestContainer = styled.div`
position: sticky;
top: 4rem;
width: 95%;
border-radius: 10px;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we use rem here?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved this in slack DMs with sauhard! this is what he said:

i would rec using px
reason is rem depends on root font size and border widths have no relation to font size
and the variance is border width across screen size is pretty limited

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so let's keep this as is

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for border-radius we will still use rem, only px for border-width

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pragyakallanagoudar are you fine with going along with this change? I think it makes sense to change border-radius to rem

margin: 0 auto;
padding: 2rem;
border: 2px solid ${COLORS.blueMid};
justify-content: space-between;
flex-direction: column;
gap: 1.4rem;
display: block;
overflow: scroll;
`;

export const InfoContainer = styled.div`
display: flex;
flex-direction: column;
width: 100%;
min-height: 50%;
gap: 0.5rem;
margin-bottom: 1rem;
padding: 0.2rem;
`;

export const Line = styled.hr`
color: 'black';
`;
115 changes: 115 additions & 0 deletions src/components/InterestForm/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
'use client';

import { useState, useEffect } from 'react';
import { UUID } from 'crypto';
import { insertInterest } from '@/api/supabase/queries/interest';
import { Interest, CaseListing } from '@/types/schema';
import { H4 } from '@/styles/text';
import COLORS from '@/styles/colors';
import Button from '../Button';
import {
FormContainer,
FormTextArea,
FormInput,
RadioGroup,
RadioLabel,
RadioInput,
FormFooter,
FormWarning,
FormTitle,
} from './styles';

const radioOptions = [
'Attorney',
'Interpreter',
'Either Attorney or Interpreter',
];

export default function InterestForm({ caseData }: { caseData: CaseListing }) {
const [reason, setReason] = useState<string>('');
const [rolesInterested, setRolesInterested] = useState<string>('');
const [startDate, setStartDate] = useState<string>('');

useEffect(() => {
// Reset form fields when caseData changes
setReason('');
setStartDate('');
setRolesInterested('');
}, [caseData]);

const handleInsert = async () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why this function seems to force a re-render of the whole page? Are we explicitly doing this somewhere?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a rough idea of why it might be re-rendering, but I'll also look more into this during the next sprint! I think once I reconnect the form to the backend it'll be easier to debug.

// will improve this in the next sprint
if (reason !== '' && startDate !== '' && rolesInterested !== '') {
const newInterest: Interest = {
// hardcoded values for now
id: crypto.randomUUID() as UUID,
listing_id: caseData.id,
listing_type: 1,
user_id: '36b8f84d-df4e-4d49-b662-bcde71a8764f',
form_response: {
interestType: rolesInterested,
interestReason: reason,
start_date: startDate,
},
};

await insertInterest(newInterest);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is just on my end, but for me this doesn't seem to be writing an interest to the table? All of this seems fine though, so I'm not sure why this might be 🤔

But also since this sprint is entirely frontend-focused, we can look deeper into this in your next sprint!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, there's a 409 error rn... I'll look more into it during the next sprint to not delay merging the frontend changes in!

setReason('');
setStartDate('');
setRolesInterested('');
}
};

return (
<FormContainer>
<FormTitle>Submit Interest</FormTitle>
<H4>What role(s) are you applying for?</H4>
<RadioGroup>
varortz marked this conversation as resolved.
Show resolved Hide resolved
{radioOptions.map(option => (
<RadioLabel key={option}>
<RadioInput
id="radio"
type="radio"
name="radioOptions"
value={option}
checked={rolesInterested === option}
varortz marked this conversation as resolved.
Show resolved Hide resolved
onChange={event => setRolesInterested(event.target.value)}
/>
{option}
</RadioLabel>
))}
</RadioGroup>

<H4>What is the earliest date you can contact the client?</H4>
<FormInput
id="startDate"
required
placeholder="MM/DD/YYYY"
value={startDate}
onChange={event => setStartDate(event.target.value)}
/>

<H4>Why are you interested in this case?</H4>
<FormTextArea
id="reason"
required
value={reason}
onChange={event => setReason(event.target.value)}
/>
varortz marked this conversation as resolved.
Show resolved Hide resolved
<FormFooter>
<FormWarning>
Your interest form is not saved!
<br />
Please submit before leaving this page.
</FormWarning>
<Button
primaryColor={COLORS.blueMid}
secondaryColor={COLORS.blueDark}
onClick={handleInsert}
>
Submit Interest
</Button>
</FormFooter>
</FormContainer>
);
}
Loading