diff --git a/.gitignore b/.gitignore index 3601c4b..33aac76 100644 --- a/.gitignore +++ b/.gitignore @@ -143,3 +143,5 @@ Thumbs.db # Prisma prisma/.env +# direnv +.direnv \ No newline at end of file diff --git a/flake.nix b/flake.nix index fdcca78..f3ddb9b 100644 --- a/flake.nix +++ b/flake.nix @@ -19,7 +19,6 @@ # Core dependencies nodejs_20 nodePackages.typescript - nodePackages.tsx podman podman-compose direnv @@ -53,4 +52,4 @@ }; }; }); -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index 05bbe49..3dc35d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "pgt-web-app", - "version": "0.1.1", + "version": "0.1.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "pgt-web-app", - "version": "0.1.1", + "version": "0.1.3", "dependencies": { "@prisma/client": "^5.22.0", "@radix-ui/react-accordion": "^1.2.1", diff --git a/package.json b/package.json index d6aa74f..11896b5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pgt-web-app", - "version": "0.1.6", + "version": "0.1.7", "private": true, "type": "module", "scripts": { diff --git a/prisma/migrations/20241126154717_add_submission_phase/migration.sql b/prisma/migrations/20241126154717_add_submission_phase/migration.sql new file mode 100644 index 0000000..e990124 --- /dev/null +++ b/prisma/migrations/20241126154717_add_submission_phase/migration.sql @@ -0,0 +1,20 @@ +-- CreateTable +CREATE TABLE "SubmissionPhase" ( + "id" UUID NOT NULL, + "fundingRoundId" UUID NOT NULL, + "startDate" TIMESTAMPTZ(6) NOT NULL, + "endDate" TIMESTAMPTZ(6) NOT NULL, + "createdAt" TIMESTAMPTZ(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMPTZ(6) NOT NULL, + + CONSTRAINT "SubmissionPhase_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "SubmissionPhase_fundingRoundId_key" ON "SubmissionPhase"("fundingRoundId"); + +-- CreateIndex +CREATE INDEX "SubmissionPhase_startDate_endDate_idx" ON "SubmissionPhase"("startDate", "endDate"); + +-- AddForeignKey +ALTER TABLE "SubmissionPhase" ADD CONSTRAINT "SubmissionPhase_fundingRoundId_fkey" FOREIGN KEY ("fundingRoundId") REFERENCES "FundingRound"("id") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 8eadf28..8905d80 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -153,6 +153,7 @@ model FundingRound { topic Topic @relation(fields: [topicId], references: [id]) proposals Proposal[] + submissionPhase SubmissionPhase? considerationPhase ConsiderationPhase? deliberationPhase DeliberationPhase? votingPhase VotingPhase? @@ -201,6 +202,19 @@ model VotingPhase { @@index([startDate, endDate]) } +model SubmissionPhase { + id String @id @default(uuid()) @db.Uuid + fundingRoundId String @unique @db.Uuid + startDate DateTime @db.Timestamptz(6) + endDate DateTime @db.Timestamptz(6) + createdAt DateTime @default(now()) @db.Timestamptz(6) + updatedAt DateTime @updatedAt @db.Timestamptz(6) + + fundingRound FundingRound @relation(fields: [fundingRoundId], references: [id], onDelete: Cascade) + + @@index([startDate, endDate]) +} + model AdminUser { id String @id @default(uuid()) @db.Uuid userId String @unique @db.Uuid diff --git a/src/app/api/admin/funding-rounds/[id]/route.ts b/src/app/api/admin/funding-rounds/[id]/route.ts index 599a068..f8aa136 100644 --- a/src/app/api/admin/funding-rounds/[id]/route.ts +++ b/src/app/api/admin/funding-rounds/[id]/route.ts @@ -6,6 +6,23 @@ import { validatePhaseDates } from "@/lib/validation"; const adminService = new AdminService(prisma); +interface DateRange { + from: string; + to: string; +} + +interface FundingRoundRequestData { + name: string; + description: string; + topicId: string; + totalBudget: number; + fundingRoundDates: DateRange; + submissionDates: DateRange; + considerationDates: DateRange; + deliberationDates: DateRange; + votingDates: DateRange; +} + interface RouteContext { params: Promise<{ id: string; @@ -58,26 +75,37 @@ export async function PUT(request: Request, context: RouteContext) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } - const data = await request.json(); + const data: FundingRoundRequestData = await request.json(); + + // Convert string dates to Date objects for validation + const fundingRoundDates = { + from: new Date(data.fundingRoundDates.from), + to: new Date(data.fundingRoundDates.to), + }; + const submissionDates = { + from: new Date(data.submissionDates.from), + to: new Date(data.submissionDates.to), + }; + const considerationDates = { + from: new Date(data.considerationDates.from), + to: new Date(data.considerationDates.to), + }; + const deliberationDates = { + from: new Date(data.deliberationDates.from), + to: new Date(data.deliberationDates.to), + }; + const votingDates = { + from: new Date(data.votingDates.from), + to: new Date(data.votingDates.to), + }; // Validate phase dates const datesValid = validatePhaseDates({ - fundingRound: { - from: new Date(data.fundingRoundDates.from), - to: new Date(data.fundingRoundDates.to), - }, - consideration: { - from: new Date(data.considerationDates.from), - to: new Date(data.considerationDates.to), - }, - deliberation: { - from: new Date(data.deliberationDates.from), - to: new Date(data.deliberationDates.to), - }, - voting: { - from: new Date(data.votingDates.from), - to: new Date(data.votingDates.to), - }, + fundingRound: fundingRoundDates, + submission: submissionDates, + consideration: considerationDates, + deliberation: deliberationDates, + voting: votingDates, }); if (!datesValid.valid) { @@ -85,10 +113,18 @@ export async function PUT(request: Request, context: RouteContext) { } const round = await adminService.updateFundingRound( - ( - await context.params - ).id, - data + (await context.params).id, + { + name: data.name, + description: data.description, + topicId: data.topicId, + totalBudget: data.totalBudget, + fundingRoundDates, + submissionDates, + considerationDates, + deliberationDates, + votingDates, + } ); return NextResponse.json(round); diff --git a/src/app/api/admin/funding-rounds/route.ts b/src/app/api/admin/funding-rounds/route.ts index 023dcd7..3661caf 100644 --- a/src/app/api/admin/funding-rounds/route.ts +++ b/src/app/api/admin/funding-rounds/route.ts @@ -4,6 +4,23 @@ import prisma from "@/lib/prisma"; import { getUserFromRequest } from "@/lib/auth"; import { validatePhaseDates } from "@/lib/validation"; +interface DateRange { + from: string; + to: string; +} + +interface FundingRoundRequestData { + name: string; + description: string; + topicId: string; + totalBudget: number; + fundingRoundDates: DateRange; + submissionDates: DateRange; + considerationDates: DateRange; + deliberationDates: DateRange; + votingDates: DateRange; +} + const adminService = new AdminService(prisma); export async function GET(req: Request) { @@ -41,26 +58,37 @@ export async function POST(req: Request) { return NextResponse.json({ error: "Forbidden" }, { status: 403 }); } - const data = await req.json(); + const data: FundingRoundRequestData = await req.json(); + + // Convert string dates to Date objects for validation + const fundingRoundDates = { + from: new Date(data.fundingRoundDates.from), + to: new Date(data.fundingRoundDates.to), + }; + const submissionDates = { + from: new Date(data.submissionDates.from), + to: new Date(data.submissionDates.to), + }; + const considerationDates = { + from: new Date(data.considerationDates.from), + to: new Date(data.considerationDates.to), + }; + const deliberationDates = { + from: new Date(data.deliberationDates.from), + to: new Date(data.deliberationDates.to), + }; + const votingDates = { + from: new Date(data.votingDates.from), + to: new Date(data.votingDates.to), + }; // Validate phase dates const datesValid = validatePhaseDates({ - fundingRound: { - from: new Date(data.fundingRoundDates.from), - to: new Date(data.fundingRoundDates.to), - }, - consideration: { - from: new Date(data.considerationDates.from), - to: new Date(data.considerationDates.to), - }, - deliberation: { - from: new Date(data.deliberationDates.from), - to: new Date(data.deliberationDates.to), - }, - voting: { - from: new Date(data.votingDates.from), - to: new Date(data.votingDates.to), - }, + fundingRound: fundingRoundDates, + submission: submissionDates, + consideration: considerationDates, + deliberation: deliberationDates, + voting: votingDates, }); if (!datesValid.valid) { @@ -68,8 +96,16 @@ export async function POST(req: Request) { } const round = await adminService.createFundingRound({ - ...data, + name: data.name, + description: data.description, + topicId: data.topicId, + totalBudget: data.totalBudget, createdById: user.id, + fundingRoundDates, + submissionDates, + considerationDates, + deliberationDates, + votingDates, }); return NextResponse.json(round); } catch (error) { diff --git a/src/components/CreateEditFundingRound.tsx b/src/components/CreateEditFundingRound.tsx index 29ade0b..3a21765 100644 --- a/src/components/CreateEditFundingRound.tsx +++ b/src/components/CreateEditFundingRound.tsx @@ -44,6 +44,10 @@ interface FundingRound { totalBudget: number; startDate: string; endDate: string; + submissionPhase: { + startDate: string; + endDate: string; + }; considerationPhase: { startDate: string; endDate: string; @@ -59,12 +63,13 @@ interface FundingRound { } type DatePhase = { - key: 'fundingRoundDates' | 'considerationDates' | 'deliberationDates' | 'votingDates'; + key: 'fundingRoundDates' | 'submissionDates' | 'considerationDates' | 'deliberationDates' | 'votingDates'; label: string; }; const DATE_PHASES: DatePhase[] = [ { key: 'fundingRoundDates', label: "Funding Round Period" }, + { key: 'submissionDates', label: "Submission Phase (UTC)" }, { key: 'considerationDates', label: "Consideration Phase (UTC)" }, { key: 'deliberationDates', label: "Deliberation Phase (UTC)" }, { key: 'votingDates', label: "Voting Phase (UTC)" } @@ -87,6 +92,7 @@ export function AddEditFundingRoundComponent({ totalBudget: "", selectedTopic: null as Topic | null, fundingRoundDates: { from: null as Date | null, to: null as Date | null }, + submissionDates: { from: null as Date | null, to: null as Date | null }, considerationDates: { from: null as Date | null, to: null as Date | null }, deliberationDates: { from: null as Date | null, to: null as Date | null }, votingDates: { from: null as Date | null, to: null as Date | null }, @@ -107,6 +113,21 @@ export function AddEditFundingRoundComponent({ const roundResponse = await fetch(`/api/admin/funding-rounds/${roundId}`); if (!roundResponse.ok) throw new Error('Failed to fetch funding round'); const round: FundingRound = await roundResponse.json(); + + // Check for missing phases and show warnings + const missingPhases = []; + if (!round.submissionPhase) missingPhases.push('Submission'); + if (!round.considerationPhase) missingPhases.push('Consideration'); + if (!round.deliberationPhase) missingPhases.push('Deliberation'); + if (!round.votingPhase) missingPhases.push('Voting'); + + if (missingPhases.length > 0) { + toast({ + title: "⚠️ Warning", + description: `Missing phase data for: ${missingPhases.join(', ')}. Please set the dates manually.`, + variant: "default", + }); + } setFormData({ name: round.name, @@ -117,18 +138,22 @@ export function AddEditFundingRoundComponent({ from: new Date(round.startDate), to: new Date(round.endDate), }, - considerationDates: { + submissionDates: round.submissionPhase ? { + from: new Date(round.submissionPhase.startDate), + to: new Date(round.submissionPhase.endDate), + } : { from: null, to: null }, + considerationDates: round.considerationPhase ? { from: new Date(round.considerationPhase.startDate), to: new Date(round.considerationPhase.endDate), - }, - deliberationDates: { + } : { from: null, to: null }, + deliberationDates: round.deliberationPhase ? { from: new Date(round.deliberationPhase.startDate), to: new Date(round.deliberationPhase.endDate), - }, - votingDates: { + } : { from: null, to: null }, + votingDates: round.votingPhase ? { from: new Date(round.votingPhase.startDate), to: new Date(round.votingPhase.endDate), - }, + } : { from: null, to: null }, }); } } catch (error) { @@ -201,6 +226,7 @@ export function AddEditFundingRoundComponent({ // Check if all dates are set const dateFields = [ 'fundingRoundDates', + 'submissionDates', 'considerationDates', 'deliberationDates', 'votingDates', @@ -221,6 +247,8 @@ export function AddEditFundingRoundComponent({ const allDatesPresent = formData.fundingRoundDates.from && formData.fundingRoundDates.to && + formData.submissionDates.from && + formData.submissionDates.to && formData.considerationDates.from && formData.considerationDates.to && formData.deliberationDates.from && @@ -243,6 +271,10 @@ export function AddEditFundingRoundComponent({ from: formData.fundingRoundDates.from as Date, to: formData.fundingRoundDates.to as Date, }, + submission: { + from: formData.submissionDates.from as Date, + to: formData.submissionDates.to as Date, + }, consideration: { from: formData.considerationDates.from as Date, to: formData.considerationDates.to as Date, @@ -293,6 +325,10 @@ export function AddEditFundingRoundComponent({ from: formData.fundingRoundDates.from!.toISOString(), to: formData.fundingRoundDates.to!.toISOString(), }, + submissionDates: { + from: formData.submissionDates.from!.toISOString(), + to: formData.submissionDates.to!.toISOString(), + }, considerationDates: { from: formData.considerationDates.from!.toISOString(), to: formData.considerationDates.to!.toISOString(), diff --git a/src/components/FundingRoundStatus.tsx b/src/components/FundingRoundStatus.tsx index 80c9350..f5120e8 100644 --- a/src/components/FundingRoundStatus.tsx +++ b/src/components/FundingRoundStatus.tsx @@ -24,6 +24,10 @@ interface FundingRound { endDate: string; totalBudget: string; proposals: Proposal[]; + submissionPhase: { + startDate: string; + endDate: string; + }; considerationPhase: { startDate: string; endDate: string; @@ -38,7 +42,7 @@ interface FundingRound { }; } -type Phase = 'submit' | 'consider' | 'deliberate' | 'vote'; +type Phase = 'submission' | 'consider' | 'deliberate' | 'vote'; interface Props { onRoundSelect?: (round: { id: string; name: string } | null) => void; @@ -97,7 +101,7 @@ export function FundingRoundStatus({ onRoundSelect }: Props) { now <= new Date(round.votingPhase.endDate)) { return 'vote'; } - return 'submit'; + return 'submission'; }; const getTimeRemainingWithEmoji = (date: Date): { text: string; emoji: string } => { @@ -166,8 +170,8 @@ export function FundingRoundStatus({ onRoundSelect }: Props) { ; } - const currentPhase = selectedRound ? getCurrentPhase(selectedRound) : 'submit' as Phase; - const phases: Phase[] = ['submit', 'consider', 'deliberate', 'vote']; + const currentPhase = selectedRound ? getCurrentPhase(selectedRound) : 'submission' as Phase; + const phases: Phase[] = ['submission', 'consider', 'deliberate', 'vote']; return (
@@ -268,7 +272,7 @@ export function FundingRoundStatus({ onRoundSelect }: Props) { !isActive && !isCompleted && "text-muted-foreground" )} > - {phase === 'submit' && "📝 "} + {phase === 'submission' && "📝 "} {phase === 'consider' && "🤔 "} {phase === 'deliberate' && "💭 "} {phase === 'vote' && "🗳️ "} @@ -280,18 +284,20 @@ export function FundingRoundStatus({ onRoundSelect }: Props) { {/* Content Area */}
+ {currentPhase === 'submission' && ( + {/* Handle click */}} + > + + 📝 Submit Proposal + Submit your proposal for this funding round + + + )} + {currentPhase === 'consider' && ( <> - {/* Handle click */}} - > - - 📊 Submissions (in progress) - Proposal submissions are in progress - - - {/* Handle click */}} diff --git a/src/components/Header.tsx b/src/components/Header.tsx index b7fb188..b04affa 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -22,7 +22,7 @@ export default function Header() { const navigation = [ { name: 'Home', href: '/', emoji: '🏠' }, { name: 'Start Here', href: '/start-here', emoji: '🚀' }, - { name: 'Proposals', href: '/proposals', emoji: '📝' }, + { name: 'My Proposals', href: '/proposals', emoji: '📝' }, ] useEffect(() => { diff --git a/src/lib/validation.ts b/src/lib/validation.ts index 2bffed3..ee8c637 100644 --- a/src/lib/validation.ts +++ b/src/lib/validation.ts @@ -5,6 +5,7 @@ interface PhaseDate { interface PhaseDates { fundingRound: PhaseDate; + submission: PhaseDate; consideration: PhaseDate; deliberation: PhaseDate; voting: PhaseDate; @@ -14,73 +15,49 @@ export function validatePhaseDates(dates: PhaseDates): { valid: boolean; error?: string; } { - // Convert all dates to UTC - const fr = { - from: new Date(dates.fundingRound.from.toISOString()), - to: new Date(dates.fundingRound.to.toISOString()), - }; - const cons = { - from: new Date(dates.consideration.from.toISOString()), - to: new Date(dates.consideration.to.toISOString()), - }; - const del = { - from: new Date(dates.deliberation.from.toISOString()), - to: new Date(dates.deliberation.to.toISOString()), - }; - const vote = { - from: new Date(dates.voting.from.toISOString()), - to: new Date(dates.voting.to.toISOString()), - }; - - // Check that all phases have valid from/to dates - if (fr.from >= fr.to) { - return { - valid: false, - error: "Funding round end date must be after start date", - }; - } - if (cons.from >= cons.to) { - return { - valid: false, - error: "Consideration phase end date must be after start date", - }; - } - if (del.from >= del.to) { - return { - valid: false, - error: "Deliberation phase end date must be after start date", - }; - } - if (vote.from >= vote.to) { - return { - valid: false, - error: "Voting phase end date must be after start date", - }; + // Check if each phase's end date is after its start date + const phases = ['fundingRound', 'submission', 'consideration', 'deliberation', 'voting'] as const; + for (const phase of phases) { + if (dates[phase].to <= dates[phase].from) { + return { + valid: false, + error: `${phase.charAt(0).toUpperCase() + phase.slice(1)} end date must be after start date`, + }; + } } - // Check phase order and containment within funding round - if (cons.from < fr.from) { - return { - valid: false, - error: "Consideration phase must start on or after funding round start", - }; + // Check if all phases are within funding round period + const fundingRoundStart = dates.fundingRound.from; + const fundingRoundEnd = dates.fundingRound.to; + + for (const phase of phases.slice(1)) { // Skip fundingRound itself + if (dates[phase].from < fundingRoundStart || dates[phase].to > fundingRoundEnd) { + return { + valid: false, + error: `${phase.charAt(0).toUpperCase() + phase.slice(1)} phase must be within funding round period`, + }; + } } - if (cons.to >= del.from) { + + // Check if phases are in correct sequence + if (dates.submission.to > dates.consideration.from) { return { valid: false, - error: "Consideration phase must end before deliberation phase starts", + error: 'Submission phase must end before consideration phase starts', }; } - if (del.to >= vote.from) { + + if (dates.consideration.to > dates.deliberation.from) { return { valid: false, - error: "Deliberation phase must end before voting phase starts", + error: 'Consideration phase must end before deliberation phase starts', }; } - if (vote.to > fr.to) { + + if (dates.deliberation.to > dates.voting.from) { return { valid: false, - error: "Voting phase must end before funding round ends", + error: 'Deliberation phase must end before voting phase starts', }; } diff --git a/src/services/AdminService.ts b/src/services/AdminService.ts index aec4e04..0fe676b 100644 --- a/src/services/AdminService.ts +++ b/src/services/AdminService.ts @@ -408,6 +408,7 @@ export class AdminService { }, }, }, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -434,6 +435,7 @@ export class AdminService { }, }, }, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -454,11 +456,11 @@ export class AdminService { totalBudget: number; createdById: string; fundingRoundDates: { from: Date; to: Date }; + submissionDates: { from: Date; to: Date }; considerationDates: { from: Date; to: Date }; deliberationDates: { from: Date; to: Date }; votingDates: { from: Date; to: Date }; }) { - // Use a transaction to ensure all phases are created atomically return this.prisma.$transaction(async (tx) => { // Create the funding round with proper createdById const fundingRound = await tx.fundingRound.create({ @@ -479,6 +481,14 @@ export class AdminService { }); // Create all phases + await tx.submissionPhase.create({ + data: { + fundingRound: { connect: { id: fundingRound.id } }, + startDate: data.submissionDates.from, + endDate: data.submissionDates.to, + }, + }); + await tx.considerationPhase.create({ data: { fundingRound: { connect: { id: fundingRound.id } }, @@ -516,6 +526,7 @@ export class AdminService { }, }, }, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -538,6 +549,7 @@ export class AdminService { topicId: string; totalBudget: number; fundingRoundDates: { from: Date; to: Date }; + submissionDates: { from: Date; to: Date }; considerationDates: { from: Date; to: Date }; deliberationDates: { from: Date; to: Date }; votingDates: { from: Date; to: Date }; @@ -561,31 +573,59 @@ export class AdminService { }); // Update all phases - await tx.considerationPhase.update({ + await tx.submissionPhase.upsert({ where: { fundingRoundId: id }, - data: { + create: { + fundingRound: { connect: { id: fundingRound.id } }, + startDate: data.submissionDates.from, + endDate: data.submissionDates.to, + }, + update: { + startDate: data.submissionDates.from, + endDate: data.submissionDates.to, + }, + }); + + await tx.considerationPhase.upsert({ + where: { fundingRoundId: id }, + create: { + fundingRound: { connect: { id: fundingRound.id } }, + startDate: data.considerationDates.from, + endDate: data.considerationDates.to, + }, + update: { startDate: data.considerationDates.from, endDate: data.considerationDates.to, }, }); - await tx.deliberationPhase.update({ + await tx.deliberationPhase.upsert({ where: { fundingRoundId: id }, - data: { + create: { + fundingRound: { connect: { id: fundingRound.id } }, + startDate: data.deliberationDates.from, + endDate: data.deliberationDates.to, + }, + update: { startDate: data.deliberationDates.from, endDate: data.deliberationDates.to, }, }); - await tx.votingPhase.update({ + await tx.votingPhase.upsert({ where: { fundingRoundId: id }, - data: { + create: { + fundingRound: { connect: { id: fundingRound.id } }, + startDate: data.votingDates.from, + endDate: data.votingDates.to, + }, + update: { startDate: data.votingDates.from, endDate: data.votingDates.to, }, }); - // Return the complete updated funding round + // Return the complete funding round with all relations return tx.fundingRound.findUnique({ where: { id: fundingRound.id }, include: { @@ -598,6 +638,7 @@ export class AdminService { }, }, }, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -616,6 +657,9 @@ export class AdminService { // Use a transaction to ensure all related data is deleted return this.prisma.$transaction(async (tx) => { // Delete all phases + await tx.submissionPhase.delete({ + where: { fundingRoundId: id }, + }); await tx.considerationPhase.delete({ where: { fundingRoundId: id }, }); diff --git a/src/services/FundingRoundService.ts b/src/services/FundingRoundService.ts index 83ed35c..92fe83b 100644 --- a/src/services/FundingRoundService.ts +++ b/src/services/FundingRoundService.ts @@ -1,6 +1,10 @@ import { PrismaClient, FundingRound as PrismaFundingRound, FundingRoundStatus } from "@prisma/client"; interface FundingRoundWithPhases extends PrismaFundingRound { + submissionPhase: { + startDate: Date; + endDate: Date; + }; considerationPhase: { startDate: Date; endDate: Date; @@ -26,6 +30,7 @@ export class FundingRoundService { return await this.prisma.fundingRound.findMany({ include: { proposals: true, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -44,6 +49,7 @@ export class FundingRoundService { }, include: { proposals: true, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -57,6 +63,7 @@ export class FundingRoundService { where: { id }, include: { proposals: true, + submissionPhase: true, considerationPhase: true, deliberationPhase: true, votingPhase: true, @@ -71,6 +78,11 @@ export class FundingRoundService { return 'upcoming'; } + if (now >= new Date(fundingRound.submissionPhase.startDate) && + now <= new Date(fundingRound.submissionPhase.endDate)) { + return 'submission'; + } + if (now >= new Date(fundingRound.considerationPhase.startDate) && now <= new Date(fundingRound.considerationPhase.endDate)) { return 'consideration';