Skip to content

Commit f38dbc7

Browse files
committed
feat: add feedback item overview grid
1 parent ad49b68 commit f38dbc7

File tree

1 file changed

+85
-31
lines changed

1 file changed

+85
-31
lines changed
Lines changed: 85 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
'use client'
2-
31
import { Feedback, Retrospective } from '@prisma/client'
2+
import { IconLayoutGrid, IconSlideshow } from '@tabler/icons-react'
3+
import React, { useState } from 'react'
44

55
import { Loader } from '@/app/components/loader/loader'
66
import { Badge } from '@/app/ui/badge/badge'
@@ -12,48 +12,102 @@ import {
1212
CarouselNext,
1313
CarouselPrevious,
1414
} from '@/app/ui/carousel/carousel'
15+
import { Tabs, TabsList, TabsTrigger } from '@/app/ui/tabs/tabs'
1516
import { api } from '@/trpc/react'
1617
import { getFeedbackType } from '@/utils/utils'
1718

1819
type DiscussPhaseProps = {
1920
selectedRetro: Retrospective
2021
}
2122

23+
type ViewType = 'carousel' | 'grid'
24+
2225
export function DiscussPhase({ selectedRetro }: DiscussPhaseProps) {
26+
const [view, setView] = useState<ViewType>('carousel')
27+
2328
const { data: feedback, isLoading } =
2429
api.feedback.getAllByRetroIdSorted.useQuery(selectedRetro.id)
2530

31+
const FeedbackCard = ({
32+
item,
33+
index,
34+
total,
35+
}: {
36+
item: Feedback
37+
index?: number
38+
total?: number
39+
}) => (
40+
<Card className='flex min-h-[18rem] w-full flex-col justify-between break-words p-5'>
41+
<CardTitle className='flex flex-row items-center justify-between'>
42+
Feedback <Badge variant='secondary'>{getFeedbackType(item.type)}</Badge>
43+
</CardTitle>
44+
<CardDescription className='prose text-lg'>
45+
{item.content}
46+
</CardDescription>
47+
<div className='flex flex-row items-center justify-between'>
48+
<Badge className='text-lg font-bold'>+{item.votes}</Badge>
49+
{index !== undefined && total !== undefined && (
50+
<CardDescription className='self-end justify-self-end px-5 text-lg'>
51+
{`${index + 1}/${total}`}
52+
</CardDescription>
53+
)}
54+
</div>
55+
</Card>
56+
)
57+
58+
const CarouselView = () => (
59+
<Carousel className='w-full'>
60+
<CarouselContent>
61+
{feedback?.map((item, index) => (
62+
<CarouselItem key={item.id}>
63+
<div className='px-4'>
64+
<FeedbackCard item={item} index={index} total={feedback.length} />
65+
</div>
66+
</CarouselItem>
67+
))}
68+
</CarouselContent>
69+
<CarouselPrevious />
70+
<CarouselNext />
71+
</Carousel>
72+
)
73+
74+
const GridView = () => (
75+
<div className='grid w-full grid-cols-1 gap-6 px-4 md:grid-cols-2 lg:grid-cols-3'>
76+
{feedback?.map((item) => (
77+
<div key={item.id}>
78+
<FeedbackCard item={item} />
79+
</div>
80+
))}
81+
</div>
82+
)
83+
2684
return (
27-
<div className='col-start-2 w-full lg:min-h-screen'>
85+
<div
86+
className={`${
87+
view === 'grid' ? 'col-span-full mx-auto w-full' : 'col-start-2 w-full'
88+
}`}
89+
>
90+
<div className='mb-6 flex items-center justify-between px-4'>
91+
<h2 className='text-2xl font-bold'>Discussion Items</h2>
92+
<Tabs defaultValue={view} onValueChange={(v) => setView(v as ViewType)}>
93+
<TabsList className='grid w-24 grid-cols-2'>
94+
<TabsTrigger value='carousel'>
95+
<IconSlideshow className='h-4 w-4' />
96+
</TabsTrigger>
97+
<TabsTrigger value='grid'>
98+
<IconLayoutGrid className='h-4 w-4' />
99+
</TabsTrigger>
100+
</TabsList>
101+
</Tabs>
102+
</div>
103+
28104
{isLoading && <Loader isLoading fullHeight />}
29-
<Carousel className='lg:mt-48'>
30-
<CarouselContent>
31-
{feedback &&
32-
feedback.map((item: Feedback, index: number) => (
33-
<CarouselItem key={item.id}>
34-
<Card className='mx-auto flex min-h-[18rem] w-11/12 flex-col justify-between break-words p-5'>
35-
<CardTitle className='flex flex-row items-center justify-between'>
36-
Feedback{' '}
37-
<Badge variant='secondary'>
38-
{getFeedbackType(item.type)}
39-
</Badge>
40-
</CardTitle>
41-
<CardDescription className='prose text-lg'>
42-
{item.content}
43-
</CardDescription>
44-
<div className='flex flex-row items-center justify-between'>
45-
<Badge className='text-lg font-bold'>+{item.votes}</Badge>
46-
<CardDescription className='self-end justify-self-end px-5 text-lg'>
47-
{`${index + 1}/${feedback.length}`}
48-
</CardDescription>
49-
</div>
50-
</Card>
51-
</CarouselItem>
52-
))}
53-
</CarouselContent>
54-
<CarouselPrevious />
55-
<CarouselNext />
56-
</Carousel>
105+
106+
<div className='mt-6'>
107+
{feedback && view === 'carousel' ? <CarouselView /> : <GridView />}
108+
</div>
57109
</div>
58110
)
59111
}
112+
113+
export default DiscussPhase

0 commit comments

Comments
 (0)