diff --git a/app/api/bounties/[id]/submit/route.ts b/app/api/bounties/[id]/submit/route.ts
index 2ef4cf7..1394af1 100644
--- a/app/api/bounties/[id]/submit/route.ts
+++ b/app/api/bounties/[id]/submit/route.ts
@@ -1,55 +1,89 @@
-import { NextResponse } from 'next/server';
-import { BountyStore } from '@/lib/store';
-import { Submission } from '@/types/participation';
+import { NextResponse } from "next/server";
+import { BountyStore } from "@/lib/store";
+import { Submission } from "@/types/participation";
+import { submissionFormSchema } from "@/components/bounty/forms/schemas";
const generateId = () => crypto.randomUUID();
export async function POST(
- request: Request,
- { params }: { params: Promise<{ id: string }> }
+ request: Request,
+ { params }: { params: Promise<{ id: string }> },
) {
- const { id: bountyId } = await params;
+ const { id: bountyId } = await params;
- try {
- const body = await request.json();
- const { contributorId, content } = body;
+ try {
+ const body = await request.json();
+ const { contributorId, ...formData } = body;
- if (!contributorId || !content) {
- return NextResponse.json({ error: 'Missing required fields' }, { status: 400 });
- }
+ if (!contributorId) {
+ return NextResponse.json(
+ { error: "Missing contributor ID" },
+ { status: 400 },
+ );
+ }
- const bounty = BountyStore.getBountyById(bountyId);
- if (!bounty) {
- return NextResponse.json({ error: 'Bounty not found' }, { status: 404 });
- }
+ const parsed = submissionFormSchema.safeParse(formData);
+ if (!parsed.success) {
+ const fieldErrors = parsed.error.flatten().fieldErrors;
+ return NextResponse.json(
+ { error: "Validation failed", fieldErrors },
+ { status: 400 },
+ );
+ }
- const allowedModels = ['single-claim', 'competition', 'multi-winner', 'application'];
- if (!allowedModels.includes(bounty.claimingModel)) {
- return NextResponse.json({ error: 'Submission not allowed for this bounty type' }, { status: 400 });
- }
+ const bounty = BountyStore.getBountyById(bountyId);
+ if (!bounty) {
+ return NextResponse.json({ error: "Bounty not found" }, { status: 404 });
+ }
- const existingSubmission = BountyStore.getSubmissionsByBounty(bountyId).find(
- s => s.contributorId === contributorId
- );
+ const allowedModels = [
+ "single-claim",
+ "competition",
+ "multi-winner",
+ "application",
+ ];
+ if (!allowedModels.includes(bounty.claimingModel)) {
+ return NextResponse.json(
+ { error: "Submission not allowed for this bounty type" },
+ { status: 400 },
+ );
+ }
- if (existingSubmission) {
- return NextResponse.json({ error: 'Duplicate submission' }, { status: 409 });
- }
+ const existingSubmission = BountyStore.getSubmissionsByBounty(
+ bountyId,
+ ).find((s) => s.contributorId === contributorId);
- const submission: Submission = {
- id: generateId(),
- bountyId,
- contributorId,
- content,
- status: 'pending',
- submittedAt: new Date().toISOString(),
- };
+ if (existingSubmission) {
+ return NextResponse.json(
+ { error: "Duplicate submission" },
+ { status: 409 },
+ );
+ }
- BountyStore.addSubmission(submission);
+ const { explanation, walletAddress, githubUrl, demoUrl, attachments } =
+ parsed.data;
- return NextResponse.json({ success: true, data: submission });
+ const submission: Submission = {
+ id: generateId(),
+ bountyId,
+ contributorId,
+ content: explanation,
+ explanation,
+ walletAddress,
+ githubUrl: githubUrl || undefined,
+ demoUrl: demoUrl || undefined,
+ attachments: attachments?.length ? attachments : undefined,
+ status: "pending",
+ submittedAt: new Date().toISOString(),
+ };
- } catch {
- return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
- }
+ BountyStore.addSubmission(submission);
+
+ return NextResponse.json({ success: true, data: submission });
+ } catch {
+ return NextResponse.json(
+ { error: "Internal Server Error" },
+ { status: 500 },
+ );
+ }
}
diff --git a/components/bounty-detail/bounty-detail-sidebar-cta.tsx b/components/bounty-detail/bounty-detail-sidebar-cta.tsx
index a468597..730f5a4 100644
--- a/components/bounty-detail/bounty-detail-sidebar-cta.tsx
+++ b/components/bounty-detail/bounty-detail-sidebar-cta.tsx
@@ -1,205 +1,215 @@
-"use client";
-
-import { useState } from "react";
-import { Github, Copy, Check, AlertCircle, Clock } from "lucide-react";
-import { Button } from "@/components/ui/button";
-import { Separator } from "@/components/ui/separator";
-
-import type { Bounty } from "@/lib/api";
-import { DifficultyBadge, StatusBadge } from "./bounty-badges";
-import { CLAIMING_MODEL_CONFIG } from "@/lib/bounty-config";
-
-export function SidebarCTA({ bounty }: { bounty: Bounty }) {
- const [copied, setCopied] = useState(false);
- const canAct = bounty.status === "open";
- const claimCfg = CLAIMING_MODEL_CONFIG[bounty.claimingModel];
- const ClaimIcon = claimCfg.icon;
-
- const handleCopy = async () => {
- try {
- await navigator.clipboard.writeText(window.location.href);
- setCopied(true);
- setTimeout(() => setCopied(false), 2000);
- } catch {
- // clipboard write failed (e.g. non-HTTPS, permission denied)
- }
- };
-
- const ctaLabel = () => {
- if (!canAct)
- return bounty.status === "claimed" ? "Already Claimed" : "Bounty Closed";
- switch (bounty.claimingModel) {
- case "single-claim":
- return "Claim Bounty";
- case "application":
- return "Apply Now";
- case "competition":
- return "Submit Entry";
- case "multi-winner":
- return "Submit Work";
- }
- };
-
- return (
-
- {/* Reward */}
-
-
- Reward
-
-
-
- {bounty.rewardAmount != null
- ? `$${bounty.rewardAmount.toLocaleString()}`
- : "TBD"}
-
-
- {bounty.rewardCurrency}
-
-
-
-
-
-
- {/* Meta */}
-
-
- Status
-
-
-
- Model
-
-
- {claimCfg.label}
-
-
- {bounty.difficulty && (
-
- Difficulty
-
-
- )}
- {bounty.submissionsEndDate && (
-
- Deadline
-
-
- {new Date(bounty.submissionsEndDate).toLocaleDateString("en-US", {
- month: "short",
- day: "numeric",
- year: "numeric",
- })}
-
-
- )}
-
-
-
-
- {/* CTA */}
-
-
- {!canAct && (
-
-
- {bounty.status === "claimed"
- ? "A contributor has already claimed this bounty."
- : "This bounty is no longer accepting submissions."}
-
- )}
-
- {/* GitHub */}
-
-
- View on GitHub
-
-
- {/* Copy link */}
-
-
- );
-}
-
-export function ClaimModelInfo({
- claimingModel,
-}: {
- claimingModel: Bounty["claimingModel"];
-}) {
- return (
-
-
- Claim Model
-
-
- {CLAIMING_MODEL_CONFIG[claimingModel].description}
-
-
- );
-}
-
-export function MobileCTA({ bounty }: { bounty: Bounty }) {
- const canAct = bounty.status === "open";
- // const claimCfg = CLAIMING_MODEL_CONFIG[bounty.claimingModel];
-
- const label = () => {
- if (!canAct)
- return bounty.status === "claimed" ? "Already Claimed" : "Bounty Closed";
- switch (bounty.claimingModel) {
- case "single-claim":
- return "Claim Bounty";
- case "application":
- return "Apply Now";
- case "competition":
- return "Submit Entry";
- case "multi-winner":
- return "Submit Work";
- }
- };
-
- return (
-
-
-
- );
-}
+"use client";
+
+import { useState } from "react";
+import { Github, Copy, Check, AlertCircle, Clock } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Separator } from "@/components/ui/separator";
+
+import type { Bounty } from "@/lib/api";
+import { DifficultyBadge, StatusBadge } from "./bounty-badges";
+import { CLAIMING_MODEL_CONFIG } from "@/lib/bounty-config";
+import { SubmissionDialog } from "./submission-dialog";
+
+export function SidebarCTA({ bounty }: { bounty: Bounty }) {
+ const [copied, setCopied] = useState(false);
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const canAct = bounty.status === "open";
+ const claimCfg = CLAIMING_MODEL_CONFIG[bounty.claimingModel];
+ const ClaimIcon = claimCfg.icon;
+
+ const handleCopy = async () => {
+ try {
+ await navigator.clipboard.writeText(window.location.href);
+ setCopied(true);
+ setTimeout(() => setCopied(false), 2000);
+ } catch {
+ // clipboard write failed (e.g. non-HTTPS, permission denied)
+ }
+ };
+
+ const ctaLabel = () => {
+ if (!canAct)
+ return bounty.status === "claimed" ? "Already Claimed" : "Bounty Closed";
+ switch (bounty.claimingModel) {
+ case "single-claim":
+ return "Claim Bounty";
+ case "application":
+ return "Apply Now";
+ case "competition":
+ return "Submit Entry";
+ case "multi-winner":
+ return "Submit Work";
+ }
+ };
+
+ return (
+
+ {/* Reward */}
+
+
+ Reward
+
+
+
+ {bounty.rewardAmount != null
+ ? `$${bounty.rewardAmount.toLocaleString()}`
+ : "TBD"}
+
+
+ {bounty.rewardCurrency}
+
+
+
+
+
+
+ {/* Meta */}
+
+
+ Status
+
+
+
+ Model
+
+
+ {claimCfg.label}
+
+
+ {bounty.difficulty && (
+
+ Difficulty
+
+
+ )}
+ {bounty.submissionsEndDate && (
+
+ Deadline
+
+
+ {new Date(bounty.submissionsEndDate).toLocaleDateString("en-US", {
+ month: "short",
+ day: "numeric",
+ year: "numeric",
+ })}
+
+
+ )}
+
+
+
+
+ {/* CTA */}
+
+
+
+
+ {!canAct && (
+
+
+ {bounty.status === "claimed"
+ ? "A contributor has already claimed this bounty."
+ : "This bounty is no longer accepting submissions."}
+
+ )}
+
+ {/* GitHub */}
+
+
+ View on GitHub
+
+
+ {/* Copy link */}
+
+
+ );
+}
+
+export function ClaimModelInfo({
+ claimingModel,
+}: {
+ claimingModel: Bounty["claimingModel"];
+}) {
+ return (
+
+
+ Claim Model
+
+
+ {CLAIMING_MODEL_CONFIG[claimingModel].description}
+
+
+ );
+}
+
+export function MobileCTA({ bounty }: { bounty: Bounty }) {
+ const [dialogOpen, setDialogOpen] = useState(false);
+ const canAct = bounty.status === "open";
+
+ const label = () => {
+ if (!canAct)
+ return bounty.status === "claimed" ? "Already Claimed" : "Bounty Closed";
+ switch (bounty.claimingModel) {
+ case "single-claim":
+ return "Claim Bounty";
+ case "application":
+ return "Apply Now";
+ case "competition":
+ return "Submit Entry";
+ case "multi-winner":
+ return "Submit Work";
+ }
+ };
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/components/bounty-detail/submission-dialog.tsx b/components/bounty-detail/submission-dialog.tsx
new file mode 100644
index 0000000..aac7698
--- /dev/null
+++ b/components/bounty-detail/submission-dialog.tsx
@@ -0,0 +1,321 @@
+"use client";
+
+import { useCallback, useEffect, useState } from "react";
+import { useForm, useFieldArray } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { toast } from "sonner";
+import { Plus, Trash2, Save, Send, Loader2 } from "lucide-react";
+
+import {
+ Dialog,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog";
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+import { Textarea } from "@/components/ui/textarea";
+import {
+ Form,
+ FormControl,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+ FormDescription,
+} from "@/components/ui/form";
+import {
+ submissionFormSchema,
+ type SubmissionFormValue,
+} from "@/components/bounty/forms/schemas";
+import { useLocalStorage } from "@/hooks/use-local-storage";
+import { bountiesApi } from "@/lib/api/bounties";
+
+interface SubmissionDialogProps {
+ bountyId: string;
+ bountyTitle: string;
+ open: boolean;
+ onOpenChange: (open: boolean) => void;
+}
+
+const DRAFT_DEFAULTS: SubmissionFormValue = {
+ githubUrl: "",
+ demoUrl: "",
+ explanation: "",
+ attachments: [],
+ walletAddress: "",
+};
+
+export function SubmissionDialog({
+ bountyId,
+ bountyTitle,
+ open,
+ onOpenChange,
+}: SubmissionDialogProps) {
+ const [submitting, setSubmitting] = useState(false);
+ const [submitted, setSubmitted] = useState(false);
+ const storageKey = `submission-draft-${bountyId}`;
+ const [draft, setDraft] = useLocalStorage(
+ storageKey,
+ null,
+ );
+
+ const form = useForm({
+ resolver: zodResolver(submissionFormSchema),
+ defaultValues: draft ?? DRAFT_DEFAULTS,
+ });
+
+ const { fields, append, remove } = useFieldArray({
+ control: form.control,
+ name: "attachments" as never,
+ });
+
+ useEffect(() => {
+ if (open && draft) {
+ form.reset(draft);
+ }
+ if (open) {
+ setSubmitted(false);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [open]);
+
+ const saveDraft = useCallback(() => {
+ const values = form.getValues();
+ setDraft(values);
+ toast.success("Draft saved");
+ onOpenChange(false);
+ }, [form, setDraft, onOpenChange]);
+
+ const clearDraft = useCallback(() => {
+ setDraft(null);
+ }, [setDraft]);
+
+ const onSubmit = async (data: SubmissionFormValue) => {
+ setSubmitting(true);
+ try {
+ const payload = {
+ ...data,
+ githubUrl: data.githubUrl || undefined,
+ demoUrl: data.demoUrl || undefined,
+ attachments: data.attachments?.filter(Boolean),
+ contributorId: "current-user",
+ };
+
+ await bountiesApi.submit(bountyId, payload);
+
+ clearDraft();
+ form.reset(DRAFT_DEFAULTS);
+ setSubmitted(true);
+ toast.success("Submission sent successfully!");
+
+ setTimeout(() => {
+ onOpenChange(false);
+ setSubmitted(false);
+ }, 2000);
+ } catch (err) {
+ const message =
+ err instanceof Error
+ ? err.message
+ : "Failed to submit. Please try again.";
+ toast.error(message);
+ } finally {
+ setSubmitting(false);
+ }
+ };
+
+ if (submitted) {
+ return (
+
+ );
+ }
+
+ return (
+
+ );
+}
diff --git a/components/bounty/forms/schemas.ts b/components/bounty/forms/schemas.ts
index 9658b2e..623d9cf 100644
--- a/components/bounty/forms/schemas.ts
+++ b/components/bounty/forms/schemas.ts
@@ -1,4 +1,4 @@
-import { z } from 'zod'
+import { z } from "zod";
// Schema para BudgetInput
export const budgetSchema = z.object({
@@ -6,65 +6,76 @@ export const budgetSchema = z.object({
.number({
error: (issue) =>
issue.input === undefined
- ? 'Amount is required'
- : 'Amount must be a number',
+ ? "Amount is required"
+ : "Amount must be a number",
})
- .positive('Amount must be greater than 0')
- .max(1_000_000_000, 'Amount exceeds maximum'),
- asset: z.enum(['XLM', 'USDC', 'AQUA'], {
- error: 'Please select an asset',
+ .positive("Amount must be greater than 0")
+ .max(1_000_000_000, "Amount exceeds maximum"),
+ asset: z.enum(["XLM", "USDC", "AQUA"], {
+ error: "Please select an asset",
}),
-})
+});
-export type BudgetValue = z.infer
+export type BudgetValue = z.infer;
// Schema para DeadlineInput
export const deadlineSchema = z
.date({
error: (issue) =>
- issue.input === undefined
- ? 'Please select a deadline'
- : 'Invalid date',
+ issue.input === undefined ? "Please select a deadline" : "Invalid date",
})
- .refine((date) => date > new Date(), 'Deadline must be in the future')
+ .refine((date) => date > new Date(), "Deadline must be in the future");
-export type DeadlineValue = z.infer
+export type DeadlineValue = z.infer;
// Schema para Milestone individual
export const milestoneSchema = z.object({
- title: z.string().min(1, 'Title is required').max(100, 'Title is too long'),
- description: z.string().max(500, 'Description is too long').optional(),
+ title: z.string().min(1, "Title is required").max(100, "Title is too long"),
+ description: z.string().max(500, "Description is too long").optional(),
percentage: z
.number({
error: (issue) =>
issue.input === undefined
- ? 'Percentage is required'
- : 'Percentage must be a number',
+ ? "Percentage is required"
+ : "Percentage must be a number",
})
- .min(1, 'Percentage must be at least 1%')
- .max(100, 'Percentage cannot exceed 100%'),
-})
+ .min(1, "Percentage must be at least 1%")
+ .max(100, "Percentage cannot exceed 100%"),
+});
-export type MilestoneValue = z.infer
+export type MilestoneValue = z.infer;
// Schema para array de Milestones
export const milestonesSchema = z
.array(milestoneSchema)
- .min(1, 'At least one milestone is required')
+ .min(1, "At least one milestone is required")
.refine(
(milestones) => {
- const total = milestones.reduce((sum, m) => sum + m.percentage, 0)
- return total === 100
+ const total = milestones.reduce((sum, m) => sum + m.percentage, 0);
+ return total === 100;
},
- { message: 'Milestone percentages must total 100%' }
- )
+ { message: "Milestone percentages must total 100%" },
+ );
-export type MilestonesValue = z.infer
+export type MilestonesValue = z.infer;
// Schema para descripción markdown
export const markdownContentSchema = z
.string()
- .min(10, 'Content must be at least 10 characters')
- .max(10000, 'Content must not exceed 10,000 characters')
+ .min(10, "Content must be at least 10 characters")
+ .max(10000, "Content must not exceed 10,000 characters");
-export type MarkdownContentValue = z.infer
+export type MarkdownContentValue = z.infer;
+
+export const submissionFormSchema = z.object({
+ githubUrl: z.string().url("Must be a valid URL").optional().or(z.literal("")),
+ demoUrl: z.string().url("Must be a valid URL").optional().or(z.literal("")),
+ explanation: z
+ .string()
+ .min(20, "Explanation must be at least 20 characters")
+ .max(5000, "Explanation must not exceed 5,000 characters"),
+ attachments: z.array(z.string().url("Must be a valid URL")).optional(),
+ walletAddress: z.string().min(1, "Wallet address is required"),
+});
+
+export type SubmissionFormValue = z.infer;
diff --git a/lib/api/bounties.ts b/lib/api/bounties.ts
index 0f9f801..45db3cc 100644
--- a/lib/api/bounties.ts
+++ b/lib/api/bounties.ts
@@ -1,40 +1,53 @@
-import { z } from 'zod';
-import { get, post, put, del } from './client';
-import type { PaginatedResponse, PaginationParams, SortParams } from './types';
+import { z } from "zod";
+import { get, post, put, del } from "./client";
+import type { PaginatedResponse, PaginationParams, SortParams } from "./types";
+import type { SubmissionFormValue } from "@/components/bounty/forms/schemas";
+import type { Submission } from "@/types/participation";
// Bounty schemas
-const bountyTypeSchema = z.enum(['feature', 'bug', 'documentation', 'refactor', 'other']);
-const bountyStatusSchema = z.enum(['open', 'claimed', 'closed']);
-const difficultySchema = z.enum(['beginner', 'intermediate', 'advanced']);
-const claimingModelSchema = z.enum(['single-claim', 'application', 'competition', 'multi-winner']);
+const bountyTypeSchema = z.enum([
+ "feature",
+ "bug",
+ "documentation",
+ "refactor",
+ "other",
+]);
+const bountyStatusSchema = z.enum(["open", "claimed", "closed"]);
+const difficultySchema = z.enum(["beginner", "intermediate", "advanced"]);
+const claimingModelSchema = z.enum([
+ "single-claim",
+ "application",
+ "competition",
+ "multi-winner",
+]);
export const bountySchema = z.object({
- id: z.string(),
- type: bountyTypeSchema,
- projectId: z.string(),
- projectName: z.string(),
- projectLogoUrl: z.string().nullable(),
- issueTitle: z.string(),
- issueNumber: z.number(),
- githubRepo: z.string(),
- githubIssueUrl: z.string().url(),
- description: z.string(),
- rewardAmount: z.number().nullable(),
- rewardCurrency: z.string(),
- claimingModel: claimingModelSchema,
- difficulty: difficultySchema.nullable(),
- tags: z.array(z.string()),
- status: bountyStatusSchema,
- createdAt: z.string(),
- updatedAt: z.string(),
- claimedAt: z.string().optional(),
- claimedBy: z.string().optional(),
- lastActivityAt: z.string().optional(),
- claimExpiresAt: z.string().optional(),
- submissionsEndDate: z.string().optional(),
-
- requirements: z.array(z.string()).optional(),
- scope: z.string().optional(),
+ id: z.string(),
+ type: bountyTypeSchema,
+ projectId: z.string(),
+ projectName: z.string(),
+ projectLogoUrl: z.string().nullable(),
+ issueTitle: z.string(),
+ issueNumber: z.number(),
+ githubRepo: z.string(),
+ githubIssueUrl: z.string().url(),
+ description: z.string(),
+ rewardAmount: z.number().nullable(),
+ rewardCurrency: z.string(),
+ claimingModel: claimingModelSchema,
+ difficulty: difficultySchema.nullable(),
+ tags: z.array(z.string()),
+ status: bountyStatusSchema,
+ createdAt: z.string(),
+ updatedAt: z.string(),
+ claimedAt: z.string().optional(),
+ claimedBy: z.string().optional(),
+ lastActivityAt: z.string().optional(),
+ claimExpiresAt: z.string().optional(),
+ submissionsEndDate: z.string().optional(),
+
+ requirements: z.array(z.string()).optional(),
+ scope: z.string().optional(),
});
export type Bounty = z.infer;
@@ -45,20 +58,20 @@ export type ClaimingModel = z.infer;
// Query params
export interface BountyListParams extends PaginationParams, SortParams {
- status?: BountyStatus;
- type?: BountyType;
- difficulty?: DifficultyLevel;
- projectId?: string;
- tags?: string | string[];
- search?: string;
+ status?: BountyStatus;
+ type?: BountyType;
+ difficulty?: DifficultyLevel;
+ projectId?: string;
+ tags?: string | string[];
+ search?: string;
}
// Create bounty input
export const createBountySchema = bountySchema.omit({
- id: true,
- createdAt: true,
- updatedAt: true,
- status: true,
+ id: true,
+ createdAt: true,
+ updatedAt: true,
+ status: true,
});
export type CreateBountyInput = z.infer;
@@ -69,39 +82,50 @@ export const updateBountySchema = createBountySchema.partial();
export type UpdateBountyInput = z.infer;
// API endpoints
-const BOUNTIES_ENDPOINT = '/api/bounties';
+const BOUNTIES_ENDPOINT = "/api/bounties";
export const bountiesApi = {
- list: (params?: BountyListParams): Promise> => {
- // Convert tags array to comma-separated string for query params
- const queryParams: Record = { ...params };
- if (queryParams.tags && Array.isArray(queryParams.tags)) {
- queryParams.tags = queryParams.tags.join(',');
- }
- return get>(BOUNTIES_ENDPOINT, { params: queryParams });
- },
-
- getById: (id: string): Promise =>
- get(`${BOUNTIES_ENDPOINT}/${id}`),
-
- create: (data: CreateBountyInput): Promise =>
- post(BOUNTIES_ENDPOINT, data),
-
- update: (id: string, data: UpdateBountyInput): Promise =>
- put(`${BOUNTIES_ENDPOINT}/${id}`, data),
-
- delete: (id: string): Promise =>
- del(`${BOUNTIES_ENDPOINT}/${id}`),
-
- claim: (id: string): Promise =>
- post(`${BOUNTIES_ENDPOINT}/${id}/claim`),
+ list: (params?: BountyListParams): Promise> => {
+ // Convert tags array to comma-separated string for query params
+ const queryParams: Record = { ...params };
+ if (queryParams.tags && Array.isArray(queryParams.tags)) {
+ queryParams.tags = queryParams.tags.join(",");
+ }
+ return get>(BOUNTIES_ENDPOINT, {
+ params: queryParams,
+ });
+ },
+
+ getById: (id: string): Promise =>
+ get(`${BOUNTIES_ENDPOINT}/${id}`),
+
+ create: (data: CreateBountyInput): Promise =>
+ post(BOUNTIES_ENDPOINT, data),
+
+ update: (id: string, data: UpdateBountyInput): Promise =>
+ put(`${BOUNTIES_ENDPOINT}/${id}`, data),
+
+ delete: (id: string): Promise =>
+ del(`${BOUNTIES_ENDPOINT}/${id}`),
+
+ claim: (id: string): Promise =>
+ post(`${BOUNTIES_ENDPOINT}/${id}/claim`),
+
+ submit: (
+ id: string,
+ data: SubmissionFormValue & { contributorId: string },
+ ): Promise<{ success: boolean; data: Submission }> =>
+ post<{ success: boolean; data: Submission }>(
+ `${BOUNTIES_ENDPOINT}/${id}/submit`,
+ data,
+ ),
};
// Parse and validate response (use when strict validation needed)
export function parseBounty(data: unknown): Bounty {
- return bountySchema.parse(data);
+ return bountySchema.parse(data);
}
export function parseBountyList(data: unknown): Bounty[] {
- return z.array(bountySchema).parse(data);
+ return z.array(bountySchema).parse(data);
}
diff --git a/package-lock.json b/package-lock.json
index 7ac6ac8..d33de95 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -226,6 +226,7 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
@@ -720,6 +721,7 @@
"version": "1.4.18",
"resolved": "https://registry.npmjs.org/@better-auth/core/-/core-1.4.18.tgz",
"integrity": "sha512-q+awYgC7nkLEBdx2sW0iJjkzgSHlIxGnOpsN1r/O1+a4m7osJNHtfK2mKJSL1I+GfNyIlxJF8WvD/NLuYMpmcg==",
+ "peer": true,
"dependencies": {
"@standard-schema/spec": "^1.0.0",
"zod": "^4.3.5"
@@ -749,12 +751,14 @@
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/@better-auth/utils/-/utils-0.3.0.tgz",
"integrity": "sha512-W+Adw6ZA6mgvnSnhOki270rwJ42t4XzSK6YWGF//BbVXL6SwCLWfyzBc1lN2m/4RM28KubdBKQ4X5VMoLRNPQw==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/@better-fetch/fetch": {
"version": "1.1.21",
"resolved": "https://registry.npmjs.org/@better-fetch/fetch/-/fetch-1.1.21.tgz",
- "integrity": "sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A=="
+ "integrity": "sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==",
+ "peer": true
},
"node_modules/@cspotcode/source-map-support": {
"version": "0.8.1",
@@ -868,6 +872,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
},
@@ -891,6 +896,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18"
}
@@ -6963,6 +6969,7 @@
"resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.21.tgz",
"integrity": "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@tanstack/query-core": "5.90.20"
},
@@ -6997,6 +7004,7 @@
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/runtime": "^7.12.5",
@@ -7383,6 +7391,7 @@
"integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@@ -7392,6 +7401,7 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz",
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"csstype": "^3.2.2"
}
@@ -7402,6 +7412,7 @@
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"peerDependencies": {
"@types/react": "^19.2.0"
}
@@ -7498,6 +7509,7 @@
"integrity": "sha512-IgSWvLobTDOjnaxAfDTIHaECbkNlAlKv2j5SjpB2v7QHKv1FIfjwMy8FsDbVfDX/KjmCmYICcw7uGaXLhtsLNg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.56.0",
"@typescript-eslint/types": "8.56.0",
@@ -8232,6 +8244,7 @@
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -8884,6 +8897,7 @@
"resolved": "https://registry.npmjs.org/better-call/-/better-call-1.1.8.tgz",
"integrity": "sha512-XMQ2rs6FNXasGNfMjzbyroSwKwYbZ/T3IxruSS6U2MJRsSYh3wYtG3o6H00ZlKZ/C/UPOAD97tqgQJNsxyeTXw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@better-auth/utils": "^0.3.0",
"@better-fetch/fetch": "^1.1.4",
@@ -8943,6 +8957,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.9.0",
"caniuse-lite": "^1.0.30001759",
@@ -10196,7 +10211,8 @@
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
"integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/embla-carousel-react": {
"version": "8.6.0",
@@ -10594,6 +10610,7 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -10795,6 +10812,7 @@
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.9",
@@ -11801,6 +11819,7 @@
"resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz",
"integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0"
}
@@ -12125,6 +12144,7 @@
"integrity": "sha512-yoLRW+KRlDmnnROdAu7sX77VNLC0bsFoZyGQJLy1cF+X/SkLg/fWkRGrEEYQK8o2cafJ2wmEaMqMEZB3U3DYDg==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=20"
},
@@ -14291,6 +14311,7 @@
"resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz",
"integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==",
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/panva"
}
@@ -14320,6 +14341,7 @@
"integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"cssstyle": "^4.2.1",
"data-urls": "^5.0.0",
@@ -14453,6 +14475,7 @@
"resolved": "https://registry.npmjs.org/kysely/-/kysely-0.28.11.tgz",
"integrity": "sha512-zpGIFg0HuoC893rIjYX1BETkVWdDnzTzF5e0kWXJFg5lE0k1/LfNWBejrcnOFu8Q2Rfq/hTDTU7XLUM8QOrpzg==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=20.0.0"
}
@@ -16239,6 +16262,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": "^20.0.0 || >=22.0.0"
}
@@ -16271,6 +16295,7 @@
"resolved": "https://registry.npmjs.org/next/-/next-16.1.6.tgz",
"integrity": "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@next/env": "16.1.6",
"@swc/helpers": "0.5.15",
@@ -17294,6 +17319,7 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.2.3.tgz",
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=0.10.0"
}
@@ -17324,6 +17350,7 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"scheduler": "^0.27.0"
},
@@ -17336,6 +17363,7 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz",
"integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==",
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=18.0.0"
},
@@ -18914,7 +18942,8 @@
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.0.tgz",
"integrity": "sha512-yYzTZ4++b7fNYxFfpnberEEKu43w44aqDMNM9MHMmcKuCH7lL8jJ4yJ7LGHv7rSwiqM0nkiobF9I6cLlpS2P7Q==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/tapable": {
"version": "2.3.0",
@@ -19041,6 +19070,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -19180,6 +19210,7 @@
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@cspotcode/source-map-support": "^0.8.0",
"@tsconfig/node10": "^1.0.7",
@@ -19390,6 +19421,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -19851,6 +19883,7 @@
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"esbuild": "^0.27.0",
"fdir": "^6.5.0",
@@ -19944,6 +19977,7 @@
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=12"
},
@@ -19957,6 +19991,7 @@
"integrity": "sha512-hOQuK7h0FGKgBAas7v0mSAsnvrIgAvWmRFjmzpJ7SwFHH3g1k2u37JtYwOwmEKhK6ZO3v9ggDBBm0La1LCK4uQ==",
"devOptional": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@vitest/expect": "4.0.18",
"@vitest/mocker": "4.0.18",
@@ -20419,6 +20454,7 @@
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=10.0.0"
},
@@ -20608,6 +20644,7 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b6aef8e..a6f07c9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -106,7 +106,7 @@ importers:
version: 1.13.5
better-auth:
specifier: ^1.4.12
- version: 1.4.18(next@16.1.1(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vitest@4.0.18(@types/node@20.19.33)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(yaml@2.8.2))
+ version: 1.4.18(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vitest@4.0.18(@types/node@20.19.33)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(yaml@2.8.2))
class-variance-authority:
specifier: ^0.7.1
version: 0.7.1
@@ -138,8 +138,8 @@ importers:
specifier: ^12.29.2
version: 12.34.2(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
next:
- specifier: 16.1.1
- version: 16.1.1(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ specifier: ^16.1.6
+ version: 16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
next-themes:
specifier: ^0.4.6
version: 0.4.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -192,9 +192,6 @@ importers:
'@graphql-codegen/typescript-operations':
specifier: ^5.0.7
version: 5.0.8(graphql@16.12.0)
- '@graphql-codegen/typescript-react-apollo':
- specifier: ^4.4.0
- version: 4.4.0(graphql@16.12.0)
'@tailwindcss/postcss':
specifier: ^4
version: 4.2.0
@@ -225,12 +222,24 @@ importers:
eslint-config-next:
specifier: 16.1.1
version: 16.1.1(@typescript-eslint/parser@8.56.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)
+ eslint-config-prettier:
+ specifier: ^10.1.8
+ version: 10.1.8(eslint@9.39.2(jiti@2.6.1))
+ husky:
+ specifier: ^9.1.7
+ version: 9.1.7
jest:
specifier: ^30.2.0
version: 30.2.0(@types/node@20.19.33)(ts-node@10.9.2(@types/node@20.19.33)(typescript@5.9.3))
jest-environment-jsdom:
specifier: ^30.2.0
version: 30.2.0
+ lint-staged:
+ specifier: ^16.2.7
+ version: 16.2.7
+ prettier:
+ specifier: 3.8.1
+ version: 3.8.1
tailwindcss:
specifier: ^4
version: 4.2.0
@@ -272,12 +281,6 @@ packages:
subscriptions-transport-ws:
optional: true
- '@ardatan/relay-compiler@12.0.0':
- resolution: {integrity: sha512-9anThAaj1dQr6IGmzBMcfzOQKTa5artjuPmw8NYK/fiGEMjADbSguBY2FMDykt+QhilR3wc9VA/3yVju7JHg7Q==}
- hasBin: true
- peerDependencies:
- graphql: '*'
-
'@ardatan/relay-compiler@12.0.3':
resolution: {integrity: sha512-mBDFOGvAoVlWaWqs3hm1AciGHSQE1rqFc/liZTyYz/Oek9yZdT5H26pH2zAFuEiTiBVPPyMuqf5VjOFPI2DGsQ==}
hasBin: true
@@ -303,28 +306,14 @@ packages:
resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==}
engines: {node: '>=6.9.0'}
- '@babel/helper-annotate-as-pure@7.27.3':
- resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-compilation-targets@7.28.6':
resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==}
engines: {node: '>=6.9.0'}
- '@babel/helper-create-class-features-plugin@7.28.6':
- resolution: {integrity: sha512-dTOdvsjnG3xNT9Y0AUg1wAl38y+4Rl4sf9caSQZOXdNqVn+H+HbbJ4IyyHaIqNR6SW9oJpA/RuRjsjCw2IdIow==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
-
'@babel/helper-globals@7.28.0':
resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==}
engines: {node: '>=6.9.0'}
- '@babel/helper-member-expression-to-functions@7.28.5':
- resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-module-imports@7.28.6':
resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==}
engines: {node: '>=6.9.0'}
@@ -335,24 +324,10 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0
- '@babel/helper-optimise-call-expression@7.27.1':
- resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-plugin-utils@7.28.6':
resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==}
engines: {node: '>=6.9.0'}
- '@babel/helper-replace-supers@7.28.6':
- resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0
-
- '@babel/helper-skip-transparent-expression-wrappers@7.27.1':
- resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==}
- engines: {node: '>=6.9.0'}
-
'@babel/helper-string-parser@7.27.1':
resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==}
engines: {node: '>=6.9.0'}
@@ -374,20 +349,6 @@ packages:
engines: {node: '>=6.0.0'}
hasBin: true
- '@babel/plugin-proposal-class-properties@7.18.6':
- resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
- engines: {node: '>=6.9.0'}
- deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-proposal-object-rest-spread@7.20.7':
- resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==}
- engines: {node: '>=6.9.0'}
- deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
'@babel/plugin-syntax-async-generators@7.8.4':
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
peerDependencies:
@@ -409,12 +370,6 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-syntax-flow@7.28.6':
- resolution: {integrity: sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
'@babel/plugin-syntax-import-assertions@7.28.6':
resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==}
engines: {node: '>=6.9.0'}
@@ -491,126 +446,6 @@ packages:
peerDependencies:
'@babel/core': ^7.0.0-0
- '@babel/plugin-transform-arrow-functions@7.27.1':
- resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-block-scoped-functions@7.27.1':
- resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-block-scoping@7.28.6':
- resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-classes@7.28.6':
- resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-computed-properties@7.28.6':
- resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-destructuring@7.28.5':
- resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-flow-strip-types@7.27.1':
- resolution: {integrity: sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-for-of@7.27.1':
- resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-function-name@7.27.1':
- resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-literals@7.27.1':
- resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-member-expression-literals@7.27.1':
- resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-modules-commonjs@7.28.6':
- resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-object-super@7.27.1':
- resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-parameters@7.27.7':
- resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-property-literals@7.27.1':
- resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-react-display-name@7.28.0':
- resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-react-jsx@7.28.6':
- resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-shorthand-properties@7.27.1':
- resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-spread@7.28.6':
- resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
- '@babel/plugin-transform-template-literals@7.27.1':
- resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==}
- engines: {node: '>=6.9.0'}
- peerDependencies:
- '@babel/core': ^7.0.0-0
-
'@babel/runtime@7.28.6':
resolution: {integrity: sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==}
engines: {node: '>=6.9.0'}
@@ -958,11 +793,6 @@ packages:
peerDependencies:
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
- '@graphql-codegen/plugin-helpers@3.1.2':
- resolution: {integrity: sha512-emOQiHyIliVOIjKVKdsI5MXj312zmRDwmHpyUTZMjfpvxq/UVAHUJIVdVf+lnjjrI+LXBTgMlTWTgHQfmICxjg==}
- peerDependencies:
- graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
-
'@graphql-codegen/plugin-helpers@6.1.0':
resolution: {integrity: sha512-JJypehWTcty9kxKiqH7TQOetkGdOYjY78RHlI+23qB59cV2wxjFFVf8l7kmuXS4cpGVUNfIjFhVr7A1W7JMtdA==}
engines: {node: '>=16'}
@@ -991,23 +821,12 @@ packages:
graphql-sock:
optional: true
- '@graphql-codegen/typescript-react-apollo@4.4.0':
- resolution: {integrity: sha512-4U0bRMDanxhUnGh/4qemQaUsuVq8HwqOMf/U9nuDXwnzxBSIPAZx/XpmUWHMtgF66J8RmzIjjB+U8Ykg48M//g==}
- engines: {node: '>= 16.0.0'}
- peerDependencies:
- graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
-
'@graphql-codegen/typescript@5.0.8':
resolution: {integrity: sha512-lUW6ari+rXP6tz5B0LXjmV9rEMOphoCZAkt+SJGObLQ6w6544ZsXSsRga/EJiSvZ1fRfm9yaFoErOZ56IVThyg==}
engines: {node: '>=16'}
peerDependencies:
graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
- '@graphql-codegen/visitor-plugin-common@2.13.8':
- resolution: {integrity: sha512-IQWu99YV4wt8hGxIbBQPtqRuaWZhkQRG2IZKbMoSvh0vGeWb3dB0n0hSgKaOOxDY+tljtOf9MTcUYvJslQucMQ==}
- peerDependencies:
- graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
-
'@graphql-codegen/visitor-plugin-common@6.2.3':
resolution: {integrity: sha512-Rewl/QRFfIOXHFK3i/ts4VodsaB4N22kckH1zweTzq7SFodkfrqGrLa/MrGLJ/q6aUuqGiqao7f4Za2IjjkCxw==}
engines: {node: '>=16'}
@@ -1166,22 +985,12 @@ packages:
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
- '@graphql-tools/optimize@1.4.0':
- resolution: {integrity: sha512-dJs/2XvZp+wgHH8T5J2TqptT9/6uVzIYvA6uFACha+ufvdMBedkfR4b4GbT8jAKLRARiqRTxy3dctnwkTM2tdw==}
- peerDependencies:
- graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
-
'@graphql-tools/optimize@2.0.0':
resolution: {integrity: sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg==}
engines: {node: '>=16.0.0'}
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
- '@graphql-tools/relay-operation-optimizer@6.5.18':
- resolution: {integrity: sha512-mc5VPyTeV+LwiM+DNvoDQfPqwQYhPV/cl5jOBjTgSniyaq8/86aODfMkrE2OduhQ5E00hqrkuL2Fdrgk0w1QJg==}
- peerDependencies:
- graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
-
'@graphql-tools/relay-operation-optimizer@7.0.27':
resolution: {integrity: sha512-rdkL1iDMFaGDiHWd7Bwv7hbhrhnljkJaD0MXeqdwQlZVgVdUDlMot2WuF7CEKVgijpH6eSC6AxXMDeqVgSBS2g==}
engines: {node: '>=16.0.0'}
@@ -1218,11 +1027,6 @@ packages:
peerDependencies:
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
- '@graphql-tools/utils@9.2.1':
- resolution: {integrity: sha512-WUw506Ql6xzmOORlriNrD6Ugx+HjVgYxt9KCXD9mHAak+eaXSwuGGPyE60hy9xaDEoXKBsG7SkG69ybitaVl6A==}
- peerDependencies:
- graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
-
'@graphql-tools/wrap@10.1.4':
resolution: {integrity: sha512-7pyNKqXProRjlSdqOtrbnFRMQAVamCmEREilOXtZujxY6kYit3tvWWSjUrcIOheltTffoRh7EQSjpy2JDCzasg==}
engines: {node: '>=18.0.0'}
@@ -1658,56 +1462,56 @@ packages:
'@napi-rs/wasm-runtime@0.2.12':
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==}
- '@next/env@16.1.1':
- resolution: {integrity: sha512-3oxyM97Sr2PqiVyMyrZUtrtM3jqqFxOQJVuKclDsgj/L728iZt/GyslkN4NwarledZATCenbk4Offjk1hQmaAA==}
+ '@next/env@16.1.6':
+ resolution: {integrity: sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ==}
'@next/eslint-plugin-next@16.1.1':
resolution: {integrity: sha512-Ovb/6TuLKbE1UiPcg0p39Ke3puyTCIKN9hGbNItmpQsp+WX3qrjO3WaMVSi6JHr9X1NrmthqIguVHodMJbh/dw==}
- '@next/swc-darwin-arm64@16.1.1':
- resolution: {integrity: sha512-JS3m42ifsVSJjSTzh27nW+Igfha3NdBOFScr9C80hHGrWx55pTrVL23RJbqir7k7/15SKlrLHhh/MQzqBBYrQA==}
+ '@next/swc-darwin-arm64@16.1.6':
+ resolution: {integrity: sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
- '@next/swc-darwin-x64@16.1.1':
- resolution: {integrity: sha512-hbyKtrDGUkgkyQi1m1IyD3q4I/3m9ngr+V93z4oKHrPcmxwNL5iMWORvLSGAf2YujL+6HxgVvZuCYZfLfb4bGw==}
+ '@next/swc-darwin-x64@16.1.6':
+ resolution: {integrity: sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
- '@next/swc-linux-arm64-gnu@16.1.1':
- resolution: {integrity: sha512-/fvHet+EYckFvRLQ0jPHJCUI5/B56+2DpI1xDSvi80r/3Ez+Eaa2Yq4tJcRTaB1kqj/HrYKn8Yplm9bNoMJpwQ==}
+ '@next/swc-linux-arm64-gnu@16.1.6':
+ resolution: {integrity: sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-arm64-musl@16.1.1':
- resolution: {integrity: sha512-MFHrgL4TXNQbBPzkKKur4Fb5ICEJa87HM7fczFs2+HWblM7mMLdco3dvyTI+QmLBU9xgns/EeeINSZD6Ar+oLg==}
+ '@next/swc-linux-arm64-musl@16.1.6':
+ resolution: {integrity: sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-x64-gnu@16.1.1':
- resolution: {integrity: sha512-20bYDfgOQAPUkkKBnyP9PTuHiJGM7HzNBbuqmD0jiFVZ0aOldz+VnJhbxzjcSabYsnNjMPsE0cyzEudpYxsrUQ==}
+ '@next/swc-linux-x64-gnu@16.1.6':
+ resolution: {integrity: sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-linux-x64-musl@16.1.1':
- resolution: {integrity: sha512-9pRbK3M4asAHQRkwaXwu601oPZHghuSC8IXNENgbBSyImHv/zY4K5udBusgdHkvJ/Tcr96jJwQYOll0qU8+fPA==}
+ '@next/swc-linux-x64-musl@16.1.6':
+ resolution: {integrity: sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-win32-arm64-msvc@16.1.1':
- resolution: {integrity: sha512-bdfQkggaLgnmYrFkSQfsHfOhk/mCYmjnrbRCGgkMcoOBZ4n+TRRSLmT/CU5SATzlBJ9TpioUyBW/vWFXTqQRiA==}
+ '@next/swc-win32-arm64-msvc@16.1.6':
+ resolution: {integrity: sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
- '@next/swc-win32-x64-msvc@16.1.1':
- resolution: {integrity: sha512-Ncwbw2WJ57Al5OX0k4chM68DKhEPlrXBaSXDCi2kPi5f4d8b3ejr3RRJGfKBLrn2YJL5ezNS7w2TZLHSti8CMw==}
+ '@next/swc-win32-x64-msvc@16.1.6':
+ resolution: {integrity: sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -3193,19 +2997,11 @@ packages:
resolution: {integrity: sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==}
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
- babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0:
- resolution: {integrity: sha512-Xj9XuRuz3nTSbaTXWv3itLOcxyF4oPD8douBBmj7U9BBC6nEBYfyOJYQMf/8PJAFotC62UY5dFfIGEPr7WswzQ==}
-
babel-preset-current-node-syntax@1.2.0:
resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==}
peerDependencies:
'@babel/core': ^7.0.0 || ^8.0.0-0
- babel-preset-fbjs@3.4.0:
- resolution: {integrity: sha512-9ywCsCvo1ojrw0b+XYk7aFvTH6D9064t0RIL1rtMf3nsa02Xw41MS7sZw216Im35xj/UY0PDBQsa1brUDDF1Ow==}
- peerDependencies:
- '@babel/core': ^7.0.0
-
babel-preset-jest@30.2.0:
resolution: {integrity: sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==}
engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0}
@@ -3408,9 +3204,6 @@ packages:
client-only@0.0.1:
resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==}
- cliui@6.0.0:
- resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
-
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@@ -3449,6 +3242,10 @@ packages:
comma-separated-tokens@2.0.3:
resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+ commander@14.0.3:
+ resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==}
+ engines: {node: '>=20'}
+
common-tags@1.8.2:
resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==}
engines: {node: '>=4.0.0'}
@@ -3603,10 +3400,6 @@ packages:
supports-color:
optional: true
- decamelize@1.2.0:
- resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
- engines: {node: '>=0.10.0'}
-
decimal.js-light@2.5.1:
resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
@@ -3646,10 +3439,6 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
- dependency-graph@0.11.0:
- resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==}
- engines: {node: '>= 0.6.0'}
-
dependency-graph@1.0.0:
resolution: {integrity: sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg==}
engines: {node: '>=4'}
@@ -3832,6 +3621,12 @@ packages:
typescript:
optional: true
+ eslint-config-prettier@10.1.8:
+ resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==}
+ hasBin: true
+ peerDependencies:
+ eslint: '>=7.0.0'
+
eslint-import-resolver-node@0.3.9:
resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==}
@@ -4288,6 +4083,11 @@ packages:
resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==}
engines: {node: '>=10.17.0'}
+ husky@9.1.7:
+ resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==}
+ engines: {node: '>=18'}
+ hasBin: true
+
iconv-lite@0.6.3:
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
engines: {node: '>=0.10.0'}
@@ -4855,6 +4655,11 @@ packages:
lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+ lint-staged@16.2.7:
+ resolution: {integrity: sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==}
+ engines: {node: '>=20.17'}
+ hasBin: true
+
listr2@9.0.5:
resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==}
engines: {node: '>=20.0.0'}
@@ -5142,6 +4947,10 @@ packages:
resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==}
engines: {node: ^18.17.0 || >=20.5.0}
+ nano-spawn@2.0.0:
+ resolution: {integrity: sha512-tacvGzUY5o2D8CBh2rrwxyNojUsZNU2zjNTzKQrkgGJQTbGAfArVWXSKMBokBeeg6C7OLRGUEyoFlYbfeWQIqw==}
+ engines: {node: '>=20.17'}
+
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -5165,8 +4974,8 @@ packages:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
- next@16.1.1:
- resolution: {integrity: sha512-QI+T7xrxt1pF6SQ/JYFz95ro/mg/1Znk5vBebsWwbpejj1T0A23hO7GYEaVac9QUOT2BIMiuzm0L99ooq7k0/w==}
+ next@16.1.6:
+ resolution: {integrity: sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==}
engines: {node: '>=20.9.0'}
hasBin: true
peerDependencies:
@@ -5387,6 +5196,11 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
+ pidtree@0.6.0:
+ resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==}
+ engines: {node: '>=0.10'}
+ hasBin: true
+
pirates@4.0.7:
resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
engines: {node: '>= 6'}
@@ -5415,6 +5229,11 @@ packages:
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
engines: {node: '>= 0.8.0'}
+ prettier@3.8.1:
+ resolution: {integrity: sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==}
+ engines: {node: '>=14'}
+ hasBin: true
+
pretty-format@27.5.1:
resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==}
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
@@ -5575,9 +5394,6 @@ packages:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
- require-main-filename@2.0.0:
- resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
-
resolve-cwd@3.0.0:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
@@ -5665,9 +5481,6 @@ packages:
sentence-case@3.0.4:
resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
- set-blocking@2.0.0:
- resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
-
set-cookie-parser@2.7.2:
resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
@@ -5793,6 +5606,10 @@ packages:
resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==}
engines: {node: '>= 0.4'}
+ string-argv@0.3.2:
+ resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
+ engines: {node: '>=0.6.19'}
+
string-env-interpolation@1.0.1:
resolution: {integrity: sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg==}
@@ -6011,9 +5828,6 @@ packages:
tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
- tslib@2.4.1:
- resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==}
-
tslib@2.6.3:
resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==}
@@ -6291,9 +6105,6 @@ packages:
resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==}
engines: {node: '>= 0.4'}
- which-module@2.0.1:
- resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
-
which-typed-array@1.1.20:
resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==}
engines: {node: '>= 0.4'}
@@ -6370,9 +6181,6 @@ packages:
resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==}
engines: {node: '>=0.4.0'}
- y18n@4.0.3:
- resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
-
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@@ -6385,18 +6193,10 @@ packages:
engines: {node: '>= 14.6'}
hasBin: true
- yargs-parser@18.1.3:
- resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
- engines: {node: '>=6'}
-
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
- yargs@15.4.1:
- resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
- engines: {node: '>=8'}
-
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
@@ -6445,30 +6245,6 @@ snapshots:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
- '@ardatan/relay-compiler@12.0.0(graphql@16.12.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/generator': 7.29.1
- '@babel/parser': 7.29.0
- '@babel/runtime': 7.28.6
- '@babel/traverse': 7.29.0
- '@babel/types': 7.29.0
- babel-preset-fbjs: 3.4.0(@babel/core@7.29.0)
- chalk: 4.1.2
- fb-watchman: 2.0.2
- fbjs: 3.0.5
- glob: 7.2.3
- graphql: 16.12.0
- immutable: 3.7.6
- invariant: 2.2.4
- nullthrows: 1.1.1
- relay-runtime: 12.0.0
- signedsource: 1.0.0
- yargs: 15.4.1
- transitivePeerDependencies:
- - encoding
- - supports-color
-
'@ardatan/relay-compiler@12.0.3(graphql@16.12.0)':
dependencies:
'@babel/generator': 7.29.1
@@ -6529,10 +6305,6 @@ snapshots:
'@jridgewell/trace-mapping': 0.3.31
jsesc: 3.1.0
- '@babel/helper-annotate-as-pure@7.27.3':
- dependencies:
- '@babel/types': 7.29.0
-
'@babel/helper-compilation-targets@7.28.6':
dependencies:
'@babel/compat-data': 7.29.0
@@ -6541,28 +6313,8 @@ snapshots:
lru-cache: 5.1.1
semver: 6.3.1
- '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-annotate-as-pure': 7.27.3
- '@babel/helper-member-expression-to-functions': 7.28.5
- '@babel/helper-optimise-call-expression': 7.27.1
- '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)
- '@babel/helper-skip-transparent-expression-wrappers': 7.27.1
- '@babel/traverse': 7.29.0
- semver: 6.3.1
- transitivePeerDependencies:
- - supports-color
-
'@babel/helper-globals@7.28.0': {}
- '@babel/helper-member-expression-to-functions@7.28.5':
- dependencies:
- '@babel/traverse': 7.29.0
- '@babel/types': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
'@babel/helper-module-imports@7.28.6':
dependencies:
'@babel/traverse': 7.29.0
@@ -6579,28 +6331,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
- '@babel/helper-optimise-call-expression@7.27.1':
- dependencies:
- '@babel/types': 7.29.0
-
'@babel/helper-plugin-utils@7.28.6': {}
- '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-member-expression-to-functions': 7.28.5
- '@babel/helper-optimise-call-expression': 7.27.1
- '@babel/traverse': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
- '@babel/helper-skip-transparent-expression-wrappers@7.27.1':
- dependencies:
- '@babel/traverse': 7.29.0
- '@babel/types': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
'@babel/helper-string-parser@7.27.1': {}
'@babel/helper-validator-identifier@7.28.5': {}
@@ -6616,23 +6348,6 @@ snapshots:
dependencies:
'@babel/types': 7.29.0
- '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)
- '@babel/helper-plugin-utils': 7.28.6
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.29.0)':
- dependencies:
- '@babel/compat-data': 7.29.0
- '@babel/core': 7.29.0
- '@babel/helper-compilation-targets': 7.28.6
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0)
- '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0)
-
'@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
@@ -6653,11 +6368,6 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
'@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)':
dependencies:
'@babel/core': 7.29.0
@@ -6728,140 +6438,6 @@ snapshots:
'@babel/core': 7.29.0
'@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-annotate-as-pure': 7.27.3
- '@babel/helper-compilation-targets': 7.28.6
- '@babel/helper-globals': 7.28.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)
- '@babel/traverse': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/template': 7.28.6
-
- '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/traverse': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0)
-
- '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/helper-skip-transparent-expression-wrappers': 7.27.1
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-compilation-targets': 7.28.6
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/traverse': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)
- '@babel/helper-plugin-utils': 7.28.6
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-annotate-as-pure': 7.27.3
- '@babel/helper-module-imports': 7.28.6
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
- '@babel/types': 7.29.0
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
- '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
- '@babel/helper-skip-transparent-expression-wrappers': 7.27.1
- transitivePeerDependencies:
- - supports-color
-
- '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)':
- dependencies:
- '@babel/core': 7.29.0
- '@babel/helper-plugin-utils': 7.28.6
-
'@babel/runtime@7.28.6': {}
'@babel/template@7.28.6':
@@ -7205,16 +6781,6 @@ snapshots:
transitivePeerDependencies:
- encoding
- '@graphql-codegen/plugin-helpers@3.1.2(graphql@16.12.0)':
- dependencies:
- '@graphql-tools/utils': 9.2.1(graphql@16.12.0)
- change-case-all: 1.0.15
- common-tags: 1.8.2
- graphql: 16.12.0
- import-from: 4.0.0
- lodash: 4.17.23
- tslib: 2.4.1
-
'@graphql-codegen/plugin-helpers@6.1.0(graphql@16.12.0)':
dependencies:
'@graphql-tools/utils': 10.11.0(graphql@16.12.0)
@@ -7254,18 +6820,6 @@ snapshots:
transitivePeerDependencies:
- encoding
- '@graphql-codegen/typescript-react-apollo@4.4.0(graphql@16.12.0)':
- dependencies:
- '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.12.0)
- '@graphql-codegen/visitor-plugin-common': 2.13.8(graphql@16.12.0)
- auto-bind: 4.0.0
- change-case-all: 1.0.15
- graphql: 16.12.0
- tslib: 2.8.1
- transitivePeerDependencies:
- - encoding
- - supports-color
-
'@graphql-codegen/typescript@5.0.8(graphql@16.12.0)':
dependencies:
'@graphql-codegen/plugin-helpers': 6.1.0(graphql@16.12.0)
@@ -7277,23 +6831,6 @@ snapshots:
transitivePeerDependencies:
- encoding
- '@graphql-codegen/visitor-plugin-common@2.13.8(graphql@16.12.0)':
- dependencies:
- '@graphql-codegen/plugin-helpers': 3.1.2(graphql@16.12.0)
- '@graphql-tools/optimize': 1.4.0(graphql@16.12.0)
- '@graphql-tools/relay-operation-optimizer': 6.5.18(graphql@16.12.0)
- '@graphql-tools/utils': 9.2.1(graphql@16.12.0)
- auto-bind: 4.0.0
- change-case-all: 1.0.15
- dependency-graph: 0.11.0
- graphql: 16.12.0
- graphql-tag: 2.12.6(graphql@16.12.0)
- parse-filepath: 1.0.2
- tslib: 2.4.1
- transitivePeerDependencies:
- - encoding
- - supports-color
-
'@graphql-codegen/visitor-plugin-common@6.2.3(graphql@16.12.0)':
dependencies:
'@graphql-codegen/plugin-helpers': 6.1.0(graphql@16.12.0)
@@ -7564,26 +7101,11 @@ snapshots:
graphql: 16.12.0
tslib: 2.8.1
- '@graphql-tools/optimize@1.4.0(graphql@16.12.0)':
- dependencies:
- graphql: 16.12.0
- tslib: 2.8.1
-
'@graphql-tools/optimize@2.0.0(graphql@16.12.0)':
dependencies:
graphql: 16.12.0
tslib: 2.8.1
- '@graphql-tools/relay-operation-optimizer@6.5.18(graphql@16.12.0)':
- dependencies:
- '@ardatan/relay-compiler': 12.0.0(graphql@16.12.0)
- '@graphql-tools/utils': 9.2.1(graphql@16.12.0)
- graphql: 16.12.0
- tslib: 2.8.1
- transitivePeerDependencies:
- - encoding
- - supports-color
-
'@graphql-tools/relay-operation-optimizer@7.0.27(graphql@16.12.0)':
dependencies:
'@ardatan/relay-compiler': 12.0.3(graphql@16.12.0)
@@ -7660,12 +7182,6 @@ snapshots:
graphql: 16.12.0
tslib: 2.8.1
- '@graphql-tools/utils@9.2.1(graphql@16.12.0)':
- dependencies:
- '@graphql-typed-document-node/core': 3.2.0(graphql@16.12.0)
- graphql: 16.12.0
- tslib: 2.8.1
-
'@graphql-tools/wrap@10.1.4(graphql@16.12.0)':
dependencies:
'@graphql-tools/delegate': 10.2.23(graphql@16.12.0)
@@ -8166,34 +7682,34 @@ snapshots:
'@tybys/wasm-util': 0.10.1
optional: true
- '@next/env@16.1.1': {}
+ '@next/env@16.1.6': {}
'@next/eslint-plugin-next@16.1.1':
dependencies:
fast-glob: 3.3.1
- '@next/swc-darwin-arm64@16.1.1':
+ '@next/swc-darwin-arm64@16.1.6':
optional: true
- '@next/swc-darwin-x64@16.1.1':
+ '@next/swc-darwin-x64@16.1.6':
optional: true
- '@next/swc-linux-arm64-gnu@16.1.1':
+ '@next/swc-linux-arm64-gnu@16.1.6':
optional: true
- '@next/swc-linux-arm64-musl@16.1.1':
+ '@next/swc-linux-arm64-musl@16.1.6':
optional: true
- '@next/swc-linux-x64-gnu@16.1.1':
+ '@next/swc-linux-x64-gnu@16.1.6':
optional: true
- '@next/swc-linux-x64-musl@16.1.1':
+ '@next/swc-linux-x64-musl@16.1.6':
optional: true
- '@next/swc-win32-arm64-msvc@16.1.1':
+ '@next/swc-win32-arm64-msvc@16.1.6':
optional: true
- '@next/swc-win32-x64-msvc@16.1.1':
+ '@next/swc-win32-x64-msvc@16.1.6':
optional: true
'@noble/ciphers@2.1.1': {}
@@ -9676,8 +9192,6 @@ snapshots:
dependencies:
'@types/babel__core': 7.20.5
- babel-plugin-syntax-trailing-function-commas@7.0.0-beta.0: {}
-
babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.29.0
@@ -9697,39 +9211,6 @@ snapshots:
'@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0)
'@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0)
- babel-preset-fbjs@3.4.0(@babel/core@7.29.0):
- dependencies:
- '@babel/core': 7.29.0
- '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0)
- '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.29.0)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0)
- '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0)
- '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)
- '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0)
- '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0)
- '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0)
- '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0)
- '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0)
- babel-plugin-syntax-trailing-function-commas: 7.0.0-beta.0
- transitivePeerDependencies:
- - supports-color
-
babel-preset-jest@30.2.0(@babel/core@7.29.0):
dependencies:
'@babel/core': 7.29.0
@@ -9742,7 +9223,7 @@ snapshots:
baseline-browser-mapping@2.10.0: {}
- better-auth@1.4.18(next@16.1.1(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vitest@4.0.18(@types/node@20.19.33)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(yaml@2.8.2)):
+ better-auth@1.4.18(next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(vitest@4.0.18(@types/node@20.19.33)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(yaml@2.8.2)):
dependencies:
'@better-auth/core': 1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0)
'@better-auth/telemetry': 1.4.18(@better-auth/core@1.4.18(@better-auth/utils@0.3.0)(@better-fetch/fetch@1.1.21)(better-call@1.1.8(zod@4.3.6))(jose@6.1.3)(kysely@0.28.11)(nanostores@1.1.0))
@@ -9757,7 +9238,7 @@ snapshots:
nanostores: 1.1.0
zod: 4.3.6
optionalDependencies:
- next: 16.1.1(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ next: 16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
vitest: 4.0.18(@types/node@20.19.33)(jiti@2.6.1)(jsdom@26.1.0)(lightningcss@1.31.1)(yaml@2.8.2)
@@ -9904,12 +9385,6 @@ snapshots:
client-only@0.0.1: {}
- cliui@6.0.0:
- dependencies:
- string-width: 4.2.3
- strip-ansi: 6.0.1
- wrap-ansi: 6.2.0
-
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@@ -9948,6 +9423,8 @@ snapshots:
comma-separated-tokens@2.0.3: {}
+ commander@14.0.3: {}
+
common-tags@1.8.2: {}
concat-map@0.0.1: {}
@@ -10086,8 +9563,6 @@ snapshots:
dependencies:
ms: 2.1.3
- decamelize@1.2.0: {}
-
decimal.js-light@2.5.1: {}
decimal.js@10.6.0: {}
@@ -10118,8 +9593,6 @@ snapshots:
delayed-stream@1.0.0: {}
- dependency-graph@0.11.0: {}
-
dependency-graph@1.0.0: {}
dequal@2.0.3: {}
@@ -10381,6 +9854,10 @@ snapshots:
- eslint-plugin-import-x
- supports-color
+ eslint-config-prettier@10.1.8(eslint@9.39.2(jiti@2.6.1)):
+ dependencies:
+ eslint: 9.39.2(jiti@2.6.1)
+
eslint-import-resolver-node@0.3.9:
dependencies:
debug: 3.2.7
@@ -10942,6 +10419,8 @@ snapshots:
human-signals@2.1.0: {}
+ husky@9.1.7: {}
+
iconv-lite@0.6.3:
dependencies:
safer-buffer: 2.1.2
@@ -11682,6 +11161,16 @@ snapshots:
lines-and-columns@1.2.4: {}
+ lint-staged@16.2.7:
+ dependencies:
+ commander: 14.0.3
+ listr2: 9.0.5
+ micromatch: 4.0.8
+ nano-spawn: 2.0.0
+ pidtree: 0.6.0
+ string-argv: 0.3.2
+ yaml: 2.8.2
+
listr2@9.0.5:
dependencies:
cli-truncate: 5.1.1
@@ -12161,6 +11650,8 @@ snapshots:
mute-stream@2.0.0: {}
+ nano-spawn@2.0.0: {}
+
nanoid@3.3.11: {}
nanostores@1.1.0: {}
@@ -12174,9 +11665,9 @@ snapshots:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
- next@16.1.1(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ next@16.1.6(@babel/core@7.29.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies:
- '@next/env': 16.1.1
+ '@next/env': 16.1.6
'@swc/helpers': 0.5.15
baseline-browser-mapping: 2.10.0
caniuse-lite: 1.0.30001770
@@ -12185,14 +11676,14 @@ snapshots:
react-dom: 19.2.3(react@19.2.3)
styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.3)
optionalDependencies:
- '@next/swc-darwin-arm64': 16.1.1
- '@next/swc-darwin-x64': 16.1.1
- '@next/swc-linux-arm64-gnu': 16.1.1
- '@next/swc-linux-arm64-musl': 16.1.1
- '@next/swc-linux-x64-gnu': 16.1.1
- '@next/swc-linux-x64-musl': 16.1.1
- '@next/swc-win32-arm64-msvc': 16.1.1
- '@next/swc-win32-x64-msvc': 16.1.1
+ '@next/swc-darwin-arm64': 16.1.6
+ '@next/swc-darwin-x64': 16.1.6
+ '@next/swc-linux-arm64-gnu': 16.1.6
+ '@next/swc-linux-arm64-musl': 16.1.6
+ '@next/swc-linux-x64-gnu': 16.1.6
+ '@next/swc-linux-x64-musl': 16.1.6
+ '@next/swc-win32-arm64-msvc': 16.1.6
+ '@next/swc-win32-x64-msvc': 16.1.6
sharp: 0.34.5
transitivePeerDependencies:
- '@babel/core'
@@ -12413,6 +11904,8 @@ snapshots:
picomatch@4.0.3: {}
+ pidtree@0.6.0: {}
+
pirates@4.0.7: {}
pkg-dir@4.2.0:
@@ -12440,6 +11933,8 @@ snapshots:
prelude-ls@1.2.1: {}
+ prettier@3.8.1: {}
+
pretty-format@27.5.1:
dependencies:
ansi-regex: 5.0.1
@@ -12650,8 +12145,6 @@ snapshots:
require-directory@2.1.1: {}
- require-main-filename@2.0.0: {}
-
resolve-cwd@3.0.0:
dependencies:
resolve-from: 5.0.0
@@ -12766,8 +12259,6 @@ snapshots:
tslib: 2.8.1
upper-case-first: 2.0.2
- set-blocking@2.0.0: {}
-
set-cookie-parser@2.7.2: {}
set-function-length@1.2.2:
@@ -12937,6 +12428,8 @@ snapshots:
es-errors: 1.3.0
internal-slot: 1.1.0
+ string-argv@0.3.2: {}
+
string-env-interpolation@1.0.1: {}
string-length@4.0.2:
@@ -13173,8 +12666,6 @@ snapshots:
minimist: 1.2.8
strip-bom: 3.0.0
- tslib@2.4.1: {}
-
tslib@2.6.3: {}
tslib@2.8.1: {}
@@ -13508,8 +12999,6 @@ snapshots:
is-weakmap: 2.0.2
is-weakset: 2.0.4
- which-module@2.0.1: {}
-
which-typed-array@1.1.20:
dependencies:
available-typed-arrays: 1.0.7
@@ -13572,35 +13061,14 @@ snapshots:
xmlhttprequest-ssl@2.1.2: {}
- y18n@4.0.3: {}
-
y18n@5.0.8: {}
yallist@3.1.1: {}
yaml@2.8.2: {}
- yargs-parser@18.1.3:
- dependencies:
- camelcase: 5.3.1
- decamelize: 1.2.0
-
yargs-parser@21.1.1: {}
- yargs@15.4.1:
- dependencies:
- cliui: 6.0.0
- decamelize: 1.2.0
- find-up: 4.1.0
- get-caller-file: 2.0.5
- require-directory: 2.1.1
- require-main-filename: 2.0.0
- set-blocking: 2.0.0
- string-width: 4.2.3
- which-module: 2.0.1
- y18n: 4.0.3
- yargs-parser: 18.1.3
-
yargs@17.7.2:
dependencies:
cliui: 8.0.1
diff --git a/types/participation.ts b/types/participation.ts
index c091efb..889f66b 100644
--- a/types/participation.ts
+++ b/types/participation.ts
@@ -1,65 +1,78 @@
-export type ApplicationStatus = 'pending' | 'approved' | 'rejected'
+export type ApplicationStatus = "pending" | "approved" | "rejected";
export interface Application {
- id: string
- bountyId: string
- applicantId: string
- applicantName?: string // Optional for UI convenience
- coverLetter: string
- portfolioUrl?: string
- status: ApplicationStatus
- submittedAt: string
- reviewedAt?: string
- feedback?: string
+ id: string;
+ bountyId: string;
+ applicantId: string;
+ applicantName?: string; // Optional for UI convenience
+ coverLetter: string;
+ portfolioUrl?: string;
+ status: ApplicationStatus;
+ submittedAt: string;
+ reviewedAt?: string;
+ feedback?: string;
}
-export type SubmissionStatus = 'pending' | 'accepted' | 'rejected'
+export type SubmissionStatus = "pending" | "accepted" | "rejected";
export interface Submission {
- id: string
- bountyId: string
- contributorId: string
- contributorName?: string
- content: string // URL or text description
- status: SubmissionStatus
- submittedAt: string
- reviewedAt?: string
- feedback?: string
+ id: string;
+ bountyId: string;
+ contributorId: string;
+ contributorName?: string;
+ content: string;
+ githubUrl?: string;
+ demoUrl?: string;
+ explanation: string;
+ attachments?: string[];
+ walletAddress: string;
+ status: SubmissionStatus;
+ submittedAt: string;
+ reviewedAt?: string;
+ feedback?: string;
}
-export type ReviewStatus = 'pending' | 'approved' | 'rejected' | 'revision_requested'
+export type ReviewStatus =
+ | "pending"
+ | "approved"
+ | "rejected"
+ | "revision_requested";
export type ReviewSubmission = {
- submissionId: string
- contributor: {
- username: string
- avatarUrl?: string
- }
- milestoneId?: string
- submittedAt: string
- status: ReviewStatus
-}
+ submissionId: string;
+ contributor: {
+ username: string;
+ avatarUrl?: string;
+ };
+ milestoneId?: string;
+ submittedAt: string;
+ status: ReviewStatus;
+};
-export type MilestoneStatus = 'active' | 'completed' | 'advanced'
+export type MilestoneStatus = "active" | "completed" | "advanced";
export interface MilestoneParticipation {
- id: string
- bountyId: string
- contributorId: string
- contributorName?: string
- currentMilestone: number // 1-based index
- status: MilestoneStatus
- joinedAt: string
- lastUpdatedAt: string
- totalMilestones?: number // Optional override or cached value
+ id: string;
+ bountyId: string;
+ contributorId: string;
+ contributorName?: string;
+ currentMilestone: number; // 1-based index
+ status: MilestoneStatus;
+ joinedAt: string;
+ lastUpdatedAt: string;
+ totalMilestones?: number; // Optional override or cached value
}
-export type CompetitionStatus = 'registered' | 'qualified' | 'disqualified' | 'winner'
+export type CompetitionStatus =
+ | "registered"
+ | "qualified"
+ | "disqualified"
+ | "winner";
export interface CompetitionParticipation {
- id: string
- bountyId: string
- contributorId: string
- status: CompetitionStatus
- registeredAt: string
+ id: string;
+ bountyId: string;
+ contributorId: string;
+ status: CompetitionStatus;
+ registeredAt: string;
}