From 36cc4f1ef745a027540050ad668db3bcdc08d4b2 Mon Sep 17 00:00:00 2001 From: Brandon Eng Date: Tue, 16 Jan 2024 22:41:46 +0700 Subject: Ability to archive groups when they’re settled up (#45) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Settled up icon on group card * remove logs * archived groups * remove settled up * remove more settled up * recent-group-list-card * sortGroups * archiveGroup * unarchiveGroup * clean up * more clean up * Prettier, fix TS errors, add titles --------- Co-authored-by: Sebastien Castiel --- src/app/groups/recent-group-list.tsx | 263 +++++++++++++---------------------- 1 file changed, 97 insertions(+), 166 deletions(-) (limited to 'src/app/groups/recent-group-list.tsx') diff --git a/src/app/groups/recent-group-list.tsx b/src/app/groups/recent-group-list.tsx index 92a8067..5f41fdb 100644 --- a/src/app/groups/recent-group-list.tsx +++ b/src/app/groups/recent-group-list.tsx @@ -1,73 +1,80 @@ 'use client' import { getGroupsAction } from '@/app/groups/actions' import { - deleteRecentGroup, + RecentGroups, + getArchivedGroups, getRecentGroups, getStarredGroups, - saveRecentGroup, - starGroup, - unstarGroup, } from '@/app/groups/recent-groups-helpers' import { Button } from '@/components/ui/button' -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuTrigger, -} from '@/components/ui/dropdown-menu' -import { Skeleton } from '@/components/ui/skeleton' -import { ToastAction } from '@/components/ui/toast' -import { useToast } from '@/components/ui/use-toast' import { getGroups } from '@/lib/api' -import { StarFilledIcon } from '@radix-ui/react-icons' -import { Calendar, Loader2, MoreHorizontal, Star, Users } from 'lucide-react' +import { Loader2 } from 'lucide-react' import Link from 'next/link' -import { useRouter } from 'next/navigation' -import { useEffect, useState } from 'react' -import { z } from 'zod' - -const recentGroupsSchema = z.array( - z.object({ - id: z.string().min(1), - name: z.string(), - }), -) -type RecentGroups = z.infer +import { SetStateAction, useEffect, useState } from 'react' +import { RecentGroupListCard } from './recent-group-list-card' -type State = +export type RecentGroupsState = | { status: 'pending' } - | { status: 'partial'; groups: RecentGroups; starredGroups: string[] } + | { + status: 'partial' + groups: RecentGroups + starredGroups: string[] + archivedGroups: string[] + } | { status: 'complete' groups: RecentGroups groupsDetails: Awaited> starredGroups: string[] + archivedGroups: string[] } -type Props = { - getGroupsAction: (groupIds: string[]) => ReturnType +function sortGroups( + state: RecentGroupsState & { status: 'complete' | 'partial' }, +) { + const starredGroupInfo = [] + const groupInfo = [] + const archivedGroupInfo = [] + for (const group of state.groups) { + if (state.starredGroups.includes(group.id)) { + starredGroupInfo.push(group) + } else if (state.archivedGroups.includes(group.id)) { + archivedGroupInfo.push(group) + } else { + groupInfo.push(group) + } + } + return { + starredGroupInfo, + groupInfo, + archivedGroupInfo, + } } export function RecentGroupList() { - const [state, setState] = useState({ status: 'pending' }) + const [state, setState] = useState({ status: 'pending' }) useEffect(() => { const groupsInStorage = getRecentGroups() const starredGroups = getStarredGroups() - setState({ status: 'partial', groups: groupsInStorage, starredGroups }) + const archivedGroups = getArchivedGroups() + setState({ + status: 'partial', + groups: groupsInStorage, + starredGroups, + archivedGroups, + }) getGroupsAction(groupsInStorage.map((g) => g.id)).then((groupsDetails) => { setState({ status: 'complete', groups: groupsInStorage, groupsDetails, starredGroups, + archivedGroups, }) }) }, []) - const router = useRouter() - const toast = useToast() - if (state.status === 'pending') { return (

@@ -91,139 +98,63 @@ export function RecentGroupList() { ) } + const { starredGroupInfo, groupInfo, archivedGroupInfo } = sortGroups(state) + + return ( + <> + {starredGroupInfo.length > 0 && ( + <> +

Starred groups

+ + + )} + + {groupInfo.length > 0 && ( + <> +

Recent groups

+ + + )} + + {archivedGroupInfo.length > 0 && ( + <> +

Archived groups

+
+ +
+ + )} + + ) +} + +function GroupList({ + groups, + state, + setState, +}: { + groups: RecentGroups + state: RecentGroupsState + setState: (state: SetStateAction) => void +}) { return (
    - {state.groups - .toSorted( - (first, second) => - (state.starredGroups.includes(second.id) ? 2 : 0) - - (state.starredGroups.includes(first.id) ? 1 : 0), - ) - .map((group) => { - const details = - state.status === 'complete' - ? state.groupsDetails.find((d) => d.id === group.id) - : null - return ( -
  • - - - - - - - { - event.stopPropagation() - deleteRecentGroup(group) - setState({ - ...state, - groups: state.groups.filter( - (g) => g.id !== group.id, - ), - }) - toast.toast({ - title: 'Group has been removed', - description: - 'The group was removed from your recent groups list.', - action: ( - { - saveRecentGroup(group) - setState({ - ...state, - groups: state.groups, - }) - }} - > - Undo - - ), - }) - }} - > - Remove from recent groups - - - - - -
    - {details ? ( -
    -
    - - {details._count.participants} -
    -
    - - - {new Date(details.createdAt).toLocaleDateString( - 'en-US', - { - dateStyle: 'medium', - }, - )} - -
    -
    - ) : ( -
    - - -
    - )} -
    - - - -
  • - ) - })} + {groups.map((group) => ( + + ))}
) } -- cgit v1.3