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

refactor: service display #28

Merged
merged 1 commit into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 2 additions & 5 deletions interapp-frontend/src/api/api_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,8 @@ export class APIClient {
: `http://${process.env.BACKEND_HOST}:${process.env.BACKEND_PORT}/api`,
});
this.instance.interceptors.request.use((req) => {

if (this.config.useMultiPart)
req.headers['Content-Type'] = 'multipart/form-data';
else
req.headers['Content-Type'] = 'application/json';
if (this.config.useMultiPart) req.headers['Content-Type'] = 'multipart/form-data';
else req.headers['Content-Type'] = 'application/json';
return req;
});
if (this.config.useClient) {
Expand Down
55 changes: 23 additions & 32 deletions interapp-frontend/src/app/announcements/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,52 @@ import { useState, useEffect } from 'react';

const handleFetch = async () => {
const apiClient = new APIClient().instance;
const res = await apiClient.get('/announcement/all', {params: {page: 1, page_size: 100}});
const res = await apiClient.get('/announcement/all', { params: { page: 1, page_size: 100 } });
return res.data;
}


};

export default function AnnouncementsPage() {

const [A, setA] = useState<FileList | null>(null);
const [B, setB] = useState<any>(null);


const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
const apiClient = new APIClient({useMultiPart: true}).instance;
const apiClient = new APIClient({ useMultiPart: true }).instance;
event.preventDefault();
const formData = new FormData();
if (A) for (let i = 0; i < A.length; i++) {
formData.append('docs', A[i]);
}
if (A)
for (let i = 0; i < A.length; i++) {
formData.append('docs', A[i]);
}
const body = {
'creation_date': new Date().toISOString(),
'title': 'test5',
'description': 'test',
'username': 'sebas'
}
creation_date: new Date().toISOString(),
title: 'test5',
description: 'test',
username: 'sebas',
};
for (const [key, value] of Object.entries(body)) {
formData.append(key, value);
}
apiClient.post('/announcement', formData).then((res) => {
console.log(res);
}).catch((err) => {
console.log(err);
});
}
apiClient
.post('/announcement', formData)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
};

useEffect(() => {
handleFetch().then((res) => setB(res));
}, []);




return (
<>
<form onSubmit={handleSubmit}>
<input type='file' accept='*' multiple onChange={(e) => setA(e.currentTarget.files)}/>
<input type='file' accept='*' multiple onChange={(e) => setA(e.currentTarget.files)} />
<button type='submit'>Submit</button>
</form>
<div>
{
JSON.stringify(B)
}

</div>
<div>{JSON.stringify(B)}</div>
</>

);
}
28 changes: 18 additions & 10 deletions interapp-frontend/src/app/services/AddService/AddService.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import { Group, NumberInput, TextInput, Textarea, Button } from '@mantine/core';
import { Group, NumberInput, TextInput, Textarea, Button, TagsInput } from '@mantine/core';
import { TimeInput } from '@mantine/dates';
import { IconPlus } from '@tabler/icons-react';
import { useForm } from '@mantine/form';
Expand All @@ -15,15 +15,16 @@ import UploadImage, { convertToBase64, allowedFormats } from '@components/Upload
import './styles.css';
import { Permissions } from '@/app/route_permissions';
import { getAllUsernames } from '@api/utils';
import PillsInputWithSearch from '@components/PillsInputWithSearch/PillsInputWithSearch';
import { useRouter } from 'next/navigation';
import { CreateServiceWithUsers } from '../types';

const AddService = ({ alreadyServiceICUsernames }: { alreadyServiceICUsernames: string[] }) => {
const { user } = useContext(AuthContext);
const [opened, setOpened] = useState(false);

const [allUsernames, setAllUsernames] = useState<string[]>([]);
const [allValidServiceICUsernames, setAllValidServiceICUsernames] = useState<string[]>([]);

const [loading, setLoading] = useState(false);
const apiClient = new APIClient().instance;
const router = useRouter();
Expand Down Expand Up @@ -58,15 +59,19 @@ const AddService = ({ alreadyServiceICUsernames }: { alreadyServiceICUsernames:
if (!value) return false;
return value.toString().length !== 8 && 'Invalid phone number';
},
website: (value) => {
if (!value) return false;
return !value.includes('http') && 'Invalid website';
},

end_time: (value, values) =>
value <= values.start_time && 'End time must be after start time',
},
});

useEffect(() => {
if (!form.values.service_ic_username) return;
if (!form.values.usernames.includes(form.values.service_ic_username)) {
form.setFieldValue('usernames', [...form.values.usernames, form.values.service_ic_username]);
}
}, [form.values.service_ic_username]);

const handleSubmit = async (data: CreateServiceWithUsers) => {
setLoading(true);
const serviceUsers = data.usernames;
Expand Down Expand Up @@ -185,18 +190,21 @@ const AddService = ({ alreadyServiceICUsernames }: { alreadyServiceICUsernames:
</div>

<SearchableSelect
defaultValue={''}
defaultValue={form.values.service_ic_username}
allValues={allValidServiceICUsernames}
onChange={(newServiceIc) => form.setFieldValue('service_ic_username', newServiceIc)}
label='Service IC'
required
/>
<PillsInputWithSearch

<TagsInput
label='Service Users'
allValues={allUsernames}
onChange={(newServiceUsers) => form.setFieldValue('usernames', newServiceUsers)}
placeholder='Users that participate in this service regularly'
required
data={allUsernames}
{...form.getInputProps('usernames')}
/>

<Group gap={3} justify='center'>
<Button onClick={() => setOpened(false)} variant='outline' color='red'>
Cancel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,6 @@ const EditService = ({
if (!value) return false;
return value.toString().length !== 8 && 'Invalid phone number';
},
website: (value) => {
if (!value) return false;
return !value.includes('http') && 'Invalid website';
},
end_time: (value, values) =>
value <= values.start_time && 'End time must be after start time',
},
Expand Down
65 changes: 24 additions & 41 deletions interapp-frontend/src/app/services/ServiceBox/ServiceBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import dynamic from 'next/dynamic';
import { Service } from '../types';
import { Suspense, memo } from 'react';
import { Text, Title, Skeleton } from '@mantine/core';
import { IconMail, IconPhoneCall, IconNetwork, IconCalendar, IconClock } from '@tabler/icons-react';
import { Text, Title, Skeleton, Card, Image } from '@mantine/core';
import { IconMail, IconPhoneCall, IconNetwork, IconClock } from '@tabler/icons-react';
import APIClient from '@api/api_client';

const ServiceBoxUsers = dynamic(() => import('../ServiceBoxUsers/ServiceBoxUsers'));
Expand Down Expand Up @@ -59,10 +59,6 @@ const ServiceBox = (service: Service & { alreadyServiceICUsernames: string[] })
const added_users = service_users.filter((user) => !old_service_users.includes(user));
const removed_users = old_service_users.filter((user) => !service_users.includes(user));

// sigh... this endpoint was originally not implemented at all, and i just thought to send multiple requests at once
// then i have to remind myself that this is not a hackathon and i can't just rush silly things like this
// i'm so tired

const actions = [
...added_users.map((user) => {
return { action: 'add', username: user };
Expand Down Expand Up @@ -95,10 +91,10 @@ const ServiceBox = (service: Service & { alreadyServiceICUsernames: string[] })
};

return (
<div className='service-box'>
<Card shadow='sm' padding='md' radius='md' className='service-box'>
<div className='service-box-image-container'>
<Suspense fallback={<Skeleton className='service-box-image-skeleton' />}>
<img
<Image
src={service.promotional_image ?? '/placeholder-image.jpg'}
alt={service.name}
className='service-box-image'
Expand Down Expand Up @@ -133,39 +129,26 @@ const ServiceBox = (service: Service & { alreadyServiceICUsernames: string[] })
</div>

<div className='service-box-info-content'>
<div>
<Text className='service-box-info-title'>Contact Info:</Text>
<div className='service-box-info-content-inner'>
<IconMail size={20} />
<Text>{service.contact_email}</Text>
<IconClock className='service-box-icon' />
<Text>
{daysOfWeek[service.day_of_week]}{' '}
{roundTimeToMinutes(service.start_time) + ' - ' + roundTimeToMinutes(service.end_time)}
</Text>
<IconMail className='service-box-icon' />
<Text>{service.contact_email}</Text>

{service.contact_number && (
<>
<IconPhoneCall size={20} />
<Text>{service.contact_number}</Text>
</>
)}
{service.website && (
<>
<IconNetwork size={20} />
<Text>{service.website}</Text>
</>
)}
</div>
</div>
<div>
<Text className='service-box-info-title'>Service Info:</Text>
<div className='service-box-info-content-inner'>
<IconCalendar size={20} />
<Text>{daysOfWeek[service.day_of_week]}</Text>
<IconClock size={20} />
<Text>
{roundTimeToMinutes(service.start_time) +
' - ' +
roundTimeToMinutes(service.end_time)}
</Text>
</div>
</div>
{service.contact_number && (
<>
<IconPhoneCall className='service-box-icon' />
<Text>{service.contact_number}</Text>
</>
)}
{service.website && (
<>
<IconNetwork className='service-box-icon' />
<Text>{service.website}</Text>
</>
)}
</div>
<ServiceBoxUsers
service_id={service.service_id}
Expand All @@ -175,7 +158,7 @@ const ServiceBox = (service: Service & { alreadyServiceICUsernames: string[] })
handleChangeServiceUsers={handleChangeServiceUsers}
/>
</div>
</div>
</Card>
);
};

Expand Down
29 changes: 19 additions & 10 deletions interapp-frontend/src/app/services/ServiceBox/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
flex-direction: column;
align-items: center;
width: 100%;
border-radius: 7px;
border: 1px solid var(--mantine-color-dark-6);
}

.service-box-image {
Expand All @@ -14,8 +12,6 @@
}

.service-box-image-container {
border-radius: 7px 7px 0 0;
border-bottom: 1px solid var(--mantine-color-dark-6);
width: 100%;
height: 15rem;
position: relative;
Expand All @@ -42,24 +38,37 @@
flex-direction: column;
align-items: center;
margin-bottom: 0.5rem;
overflow: hidden;
}

.service-box-info-title {
font-weight: bold;
margin-bottom: 0.2rem;
white-space: nowrap;
text-overflow: ellipsis;
width: 100%;
display: block;
overflow: hidden;
}

.service-box-info-content {
display: flex;
justify-content: space-around;
gap: 0.5rem;
}

.service-box-info-content-inner {
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
column-gap: 0.5rem;
margin: 0.5rem 0;
}

.service-box-info-content > p {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}

.service-box-icon {
width: 1rem;
height: 1rem;
color: var(--mantine-color-teal-6);
}

.service-box-info-content-inner > svg {
Expand Down
Loading
Loading