Skip to content

Commit e626902

Browse files
committed
fix: donation tags / componentized the urgent supplies section
1 parent 49fd66c commit e626902

File tree

11 files changed

+195
-121
lines changed

11 files changed

+195
-121
lines changed

src/components/ShelterListItem/ShelterListItem.tsx

Lines changed: 0 additions & 118 deletions
This file was deleted.

src/components/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { LoadingScreen } from './LoadingScreen';
22
import { Header } from './Header';
33
import { Alert } from './Alert';
44
import { CardAboutShelter } from './CardAboutShelter';
5-
import { ShelterListItem } from './ShelterListItem';
5+
import { ShelterListItem } from '../pages/Home/components/ShelterListItem';
66
import { NoFoundSearch } from './NoFoundSearch';
77
import { CircleStatus } from './CircleStatus';
88
import { DialogSelector } from './DialogSelector';

src/hooks/useShelters/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { ShelterTagType } from '@/pages/Home/components/ShelterListItem/types';
2+
13
export interface IUseSheltersData {
24
id: string;
35
name: string;
@@ -17,8 +19,12 @@ export interface IUseSheltersData {
1719
}
1820

1921
export interface IUseSheltersDataSupplyData {
20-
supply: { name: string, supplyCategory: { name: string}};
22+
supply: {
23+
name: string;
24+
supplyCategory: { name: string };
25+
};
2126
priority: number;
27+
tags: ShelterTagType[];
2228
}
2329

2430
export interface IUseShelterOptions {

src/lib/utils.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import { IUseSheltersDataSupplyData } from '@/hooks/useShelters/types';
2+
import {
3+
ShelterTagInfo,
4+
ShelterTagType,
5+
} from '@/pages/Home/components/ShelterListItem/types';
16
import { SupplyPriority } from '@/service/supply/types';
27
import { type ClassValue, clsx } from 'clsx';
38
import { twMerge } from 'tailwind-merge';
@@ -114,6 +119,31 @@ function group<T extends Record<string, any>>(
114119
return data;
115120
}
116121

122+
function groupShelterSuppliesByTag(data: IUseSheltersDataSupplyData[]) {
123+
const initialGroup: ShelterTagInfo<IUseSheltersDataSupplyData[]> = {
124+
NeedDonations: [],
125+
NeedVolunteers: [],
126+
RemainingSupplies: [],
127+
};
128+
const grouped: ShelterTagInfo<IUseSheltersDataSupplyData[]> = initialGroup;
129+
130+
data.forEach((shelterSupply) => {
131+
Object.keys(grouped).forEach((key: string) => {
132+
console.log(shelterSupply.supply);
133+
if (shelterSupply.tags.includes(key as ShelterTagType)) {
134+
grouped[key as ShelterTagType].push(shelterSupply);
135+
}
136+
});
137+
});
138+
139+
return Object.entries(grouped).reduce((prev, [category, values]) => {
140+
return {
141+
...prev,
142+
[category]: values.sort((a, b) => a.priority - b.priority),
143+
};
144+
}, initialGroup);
145+
}
146+
117147
export {
118148
cn,
119149
getAvailabilityProps,
@@ -123,4 +153,5 @@ export {
123153
colorStatusPriority,
124154
nameStatusPriority,
125155
priorityOptions,
156+
groupShelterSuppliesByTag,
126157
};
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { useMemo } from 'react';
2+
import { format } from 'date-fns';
3+
import { useNavigate } from 'react-router-dom';
4+
import { ChevronRight } from 'lucide-react';
5+
6+
import {
7+
IShelterListItemProps,
8+
IShelterAvailabilityProps,
9+
ShelterTagInfo,
10+
} from './types';
11+
import {
12+
cn,
13+
getAvailabilityProps,
14+
getSupplyPriorityProps,
15+
groupShelterSuppliesByTag,
16+
} from '@/lib/utils';
17+
import { Button } from '../../../../components/ui/button';
18+
import { VerifiedBadge } from '@/components/VerifiedBadge/VerifiedBadge.tsx';
19+
import { IUseSheltersDataSupplyData } from '@/hooks/useShelters/types';
20+
import { ShelterSupplyCategoryRow } from '../ShelterSupplyCategoryRow';
21+
22+
const ShelterListItem = (props: IShelterListItemProps) => {
23+
const { data, onClick } = props;
24+
const { capacity, shelteredPeople } = data;
25+
const navigate = useNavigate();
26+
const { availability, className: availabilityClassName } =
27+
useMemo<IShelterAvailabilityProps>(
28+
() => getAvailabilityProps(capacity, shelteredPeople),
29+
[capacity, shelteredPeople]
30+
);
31+
32+
const tags: ShelterTagInfo<IUseSheltersDataSupplyData[]> = useMemo(() => {
33+
return groupShelterSuppliesByTag(data.shelterSupplies);
34+
}, [data.shelterSupplies]);
35+
36+
return (
37+
<div className="flex flex-col p-4 w-full border-2 border-border rounded-md gap-1 relative">
38+
<Button size="sm" variant="ghost" className="absolute top-4 right-4">
39+
<ChevronRight className="h-5 w-5" />
40+
</Button>
41+
<div
42+
className="flex items-center gap-1"
43+
onClick={() => navigate(`/abrigo/${data.id}`)}
44+
>
45+
<h3
46+
className="font-semibold text-lg hover:cursor-pointer hover:text-slate-500"
47+
onClick={onClick}
48+
>
49+
{data.name}
50+
</h3>
51+
{data.verified && <VerifiedBadge />}
52+
</div>
53+
<h6 className={cn('font-semibold text-md', availabilityClassName)}>
54+
{availability}
55+
</h6>
56+
<h6 className="text-muted-foreground text-sm md:text-lg font-medium">
57+
{data.address}
58+
</h6>
59+
{data.shelterSupplies.length > 0 && (
60+
<>
61+
<ShelterSupplyCategoryRow
62+
title="Necessita volunários:"
63+
tags={tags.NeedVolunteers.map((t) => {
64+
const { className } = getSupplyPriorityProps(t.priority);
65+
return {
66+
...t,
67+
label: t.supply.name,
68+
className,
69+
};
70+
})}
71+
/>
72+
<ShelterSupplyCategoryRow
73+
title="Necessita urgente doações de:"
74+
tags={tags.NeedDonations.map((t) => {
75+
const { className } = getSupplyPriorityProps(t.priority);
76+
return {
77+
...t,
78+
label: t.supply.name,
79+
className,
80+
};
81+
})}
82+
/>
83+
<ShelterSupplyCategoryRow
84+
title="Sobrando para doações:"
85+
tags={tags.RemainingSupplies.map((t) => {
86+
const { className } = getSupplyPriorityProps(t.priority);
87+
return {
88+
...t,
89+
label: t.supply.name,
90+
className,
91+
};
92+
})}
93+
/>
94+
</>
95+
)}
96+
{data.updatedAt && (
97+
<small className="text-sm md:text-md font-light text-muted-foreground mt-2">
98+
Atualizado em {format(data.updatedAt, 'dd/MM/yyyy HH:mm')}
99+
</small>
100+
)}
101+
</div>
102+
);
103+
};
104+
105+
export { ShelterListItem };
File renamed without changes.

src/components/ShelterListItem/types.ts renamed to src/pages/Home/components/ShelterListItem/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ export interface IShelterAvailabilityProps {
55
className: string;
66
}
77

8+
export type ShelterTagType =
9+
| 'NeedVolunteers'
10+
| 'NeedDonations'
11+
| 'RemainingSupplies';
12+
13+
export type ShelterTagInfo<T = any> = {
14+
[key in ShelterTagType]: T;
15+
};
16+
817
export interface IShelterListItemProps {
918
data: IUseSheltersData;
1019
onClick?: () => void;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
3+
import { Separator } from '@/components/ui/separator';
4+
import { IShelterSupplyCategoryRowProps } from './types';
5+
import { Chip } from '@/components';
6+
import { cn } from '@/lib/utils';
7+
8+
const ShelterSupplyCategoryRow = React.forwardRef<
9+
HTMLDivElement,
10+
IShelterSupplyCategoryRowProps
11+
>((props, ref) => {
12+
const { description, tags, title, className = '', ...rest } = props;
13+
14+
return (
15+
<div className={cn('flex flex-col gap-3', className)} ref={ref} {...rest}>
16+
<Separator className="mt-2" />
17+
<p className="text-muted-foreground text-sm md:text-lg font-medium">
18+
{title}
19+
</p>
20+
{description && <p>{description}</p>}
21+
<div className="flex gap-2 flex-wrap">
22+
{tags.map((s, idx) => (
23+
<Chip key={idx} {...s} />
24+
))}
25+
</div>
26+
</div>
27+
);
28+
});
29+
30+
export { ShelterSupplyCategoryRow };
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { ShelterSupplyCategoryRow } from './ShelterSupplyCategoryRow';
2+
3+
export { ShelterSupplyCategoryRow };
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { IChipProps } from '@/components/Chip/types';
2+
3+
export interface IShelterSupplyCategoryRowProps
4+
extends React.ComponentPropsWithoutRef<'div'> {
5+
title: string;
6+
description?: string;
7+
tags: IChipProps[];
8+
}

0 commit comments

Comments
 (0)