Skip to content

Commit

Permalink
Merge pull request #205 from MinaFoundation/feat/summary_phase_summar…
Browse files Browse the repository at this point in the history
…y_card

phase summary card loading [WIP]
  • Loading branch information
leomanza authored Mar 10, 2025
2 parents 3c1e973 + 11e3035 commit 61d23d4
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 89 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pgt-web-app",
"version": "0.1.106",
"version": "0.1.107",
"private": true,
"type": "module",
"scripts": {
Expand Down
88 changes: 2 additions & 86 deletions src/app/funding-rounds/[id]/(summaries)/summaries/page.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
import { type FC } from 'react'
import { notFound } from 'next/navigation'
import Link from 'next/link'
import { format } from 'date-fns'
import { prisma } from '@/lib/prisma'
import {
Card,
CardHeader,
CardTitle,
CardDescription,
CardContent,
} from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
import {
CalendarIcon,
FileTextIcon,
UsersIcon,
VoteIcon,
CoinsIcon,
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { FileTextIcon, UsersIcon, VoteIcon, CoinsIcon } from 'lucide-react'
import { getPhaseStatus } from '@/lib/phase-utils'
import { type PhaseStatus } from '@/types/phase-summary'
import { type Metadata } from 'next'
import { PhaseSummaryCard } from '@/components/funding-rounds/PhaseSummaryCard'

type MetadataProps = {
params: Promise<{
Expand Down Expand Up @@ -55,73 +38,6 @@ interface PhaseInfo {
href: string
}

const PhaseSummaryCard: FC<PhaseInfo> = ({
title,
description,
icon,
status,
startDate,
endDate,
href,
}) => {
const isAccessible = status !== 'not-started'
const CardWrapper = isAccessible ? Link : 'div'

return (
<CardWrapper
href={href}
className={cn(
'block transition-all duration-200',
isAccessible && 'hover:shadow-md',
)}
>
<Card className={cn('relative', !isAccessible && 'opacity-75')}>
<CardHeader>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
{icon}
<CardTitle className="text-lg">{title}</CardTitle>
</div>
<Badge
variant={
status === 'ended'
? 'default'
: status === 'ongoing'
? 'secondary'
: 'outline'
}
className={cn(
status === 'not-started' && 'bg-muted text-muted-foreground',
)}
>
{status === 'ended'
? 'Completed'
: status === 'ongoing'
? 'In Progress'
: 'Not Started'}
</Badge>
</div>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<CalendarIcon className="h-4 w-4" />
<span>
{format(startDate, 'MMM dd, yyyy')} -{' '}
{format(endDate, 'MMM dd, yyyy')}
</span>
</div>
{!isAccessible && (
<div className="mt-4 text-sm text-muted-foreground">
Summary will be available when the phase starts
</div>
)}
</CardContent>
</Card>
</CardWrapper>
)
}

const getPhaseInfoWithFallback = (
phase: {
startDate: Date
Expand Down
100 changes: 100 additions & 0 deletions src/components/funding-rounds/PhaseSummaryCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
'use client'
import { type PhaseStatus } from '@/types/phase-summary'
import { Suspense, useState, type FC } from 'react'
import Link from 'next/link'
import { cn } from '@/lib/utils'
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from '../ui/card'
import { Badge } from '@/components/ui/badge'
import { CalendarIcon } from 'lucide-react'
import { format } from 'date-fns'
import { Icons } from '../icons'

interface PhaseInfo {
title: string
description: string
icon: React.ReactNode
status: PhaseStatus
startDate: Date
endDate: Date
href: string
}

export const PhaseSummaryCard: FC<PhaseInfo> = ({
title,
description,
icon,
status,
startDate,
endDate,
href,
}) => {
const isAccessible = status !== 'not-started'
const CardWrapper = isAccessible ? Link : 'div'
const [isLoading, setIsLoading] = useState(false)

const handleClick = (e: React.MouseEvent<HTMLElement>) => {
setIsLoading(true)
}

return (
<CardWrapper
href={href}
onClick={handleClick}
className={cn(
'block transition-all duration-200',
isAccessible && 'hover:shadow-md',
)}
>
<Card className={cn('relative', !isAccessible && 'opacity-75')}>
<CardHeader>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2">
{icon}
<CardTitle className="text-lg">{title}</CardTitle>
</div>
{isLoading && <Icons.spinner className="h-4 w-4 animate-spin" />}
<Badge
variant={
status === 'ended'
? 'default'
: status === 'ongoing'
? 'secondary'
: 'outline'
}
className={cn(
status === 'not-started' && 'bg-muted text-muted-foreground',
)}
>
{status === 'ended'
? 'Completed'
: status === 'ongoing'
? 'In Progress'
: 'Not Started'}
</Badge>
</div>
<CardDescription>{description}</CardDescription>
</CardHeader>
<CardContent>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<CalendarIcon className="h-4 w-4" />
<span>
{format(startDate, 'MMM dd, yyyy')} -{' '}
{format(endDate, 'MMM dd, yyyy')}
</span>
</div>
{!isAccessible && (
<div className="mt-4 text-sm text-muted-foreground">
Summary will be available when the phase starts
</div>
)}
</CardContent>
</Card>
</CardWrapper>
)
}

0 comments on commit 61d23d4

Please sign in to comment.