Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
'use client'
|
|
|
|
|
|
|
|
|
|
import { useState, useCallback, useMemo } from 'react'
|
|
|
|
|
import Link from 'next/link'
|
|
|
|
|
import Papa from 'papaparse'
|
|
|
|
|
import { trpc } from '@/lib/trpc/client'
|
|
|
|
|
import { Button } from '@/components/ui/button'
|
|
|
|
|
import {
|
|
|
|
|
Card,
|
|
|
|
|
CardContent,
|
|
|
|
|
CardDescription,
|
|
|
|
|
CardHeader,
|
|
|
|
|
CardTitle,
|
|
|
|
|
} from '@/components/ui/card'
|
|
|
|
|
import { Input } from '@/components/ui/input'
|
|
|
|
|
import { Label } from '@/components/ui/label'
|
|
|
|
|
import { Badge } from '@/components/ui/badge'
|
|
|
|
|
import { Progress } from '@/components/ui/progress'
|
|
|
|
|
import {
|
|
|
|
|
Select,
|
|
|
|
|
SelectContent,
|
|
|
|
|
SelectItem,
|
|
|
|
|
SelectTrigger,
|
|
|
|
|
SelectValue,
|
|
|
|
|
} from '@/components/ui/select'
|
|
|
|
|
import {
|
|
|
|
|
Table,
|
|
|
|
|
TableBody,
|
|
|
|
|
TableCell,
|
|
|
|
|
TableHead,
|
|
|
|
|
TableHeader,
|
|
|
|
|
TableRow,
|
|
|
|
|
} from '@/components/ui/table'
|
|
|
|
|
import {
|
|
|
|
|
ArrowLeft,
|
|
|
|
|
ArrowRight,
|
|
|
|
|
AlertCircle,
|
|
|
|
|
CheckCircle2,
|
|
|
|
|
Loader2,
|
|
|
|
|
Users,
|
|
|
|
|
X,
|
2026-02-02 20:07:03 +01:00
|
|
|
Plus,
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
FileSpreadsheet,
|
2026-02-02 20:07:03 +01:00
|
|
|
UserPlus,
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
} from 'lucide-react'
|
|
|
|
|
import { cn } from '@/lib/utils'
|
|
|
|
|
|
|
|
|
|
type Step = 'input' | 'preview' | 'sending' | 'complete'
|
|
|
|
|
type Role = 'JURY_MEMBER' | 'MENTOR' | 'OBSERVER'
|
|
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
interface MemberRow {
|
|
|
|
|
id: string
|
|
|
|
|
name: string
|
|
|
|
|
email: string
|
|
|
|
|
role: Role
|
2026-02-03 15:25:28 +01:00
|
|
|
expertiseTags: string[]
|
|
|
|
|
tagInput: string
|
2026-02-02 20:07:03 +01:00
|
|
|
}
|
|
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
interface ParsedUser {
|
|
|
|
|
email: string
|
|
|
|
|
name?: string
|
2026-02-02 20:07:03 +01:00
|
|
|
role: Role
|
2026-02-03 15:25:28 +01:00
|
|
|
expertiseTags?: string[]
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
isValid: boolean
|
|
|
|
|
error?: string
|
|
|
|
|
isDuplicate?: boolean
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
|
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
const ROLE_LABELS: Record<Role, string> = {
|
|
|
|
|
JURY_MEMBER: 'Jury Member',
|
|
|
|
|
MENTOR: 'Mentor',
|
|
|
|
|
OBSERVER: 'Observer',
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let rowIdCounter = 0
|
|
|
|
|
function nextRowId(): string {
|
|
|
|
|
return `row-${++rowIdCounter}`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function createEmptyRow(role: Role = 'JURY_MEMBER'): MemberRow {
|
2026-02-03 15:25:28 +01:00
|
|
|
return { id: nextRowId(), name: '', email: '', role, expertiseTags: [], tagInput: '' }
|
2026-02-02 20:07:03 +01:00
|
|
|
}
|
|
|
|
|
|
2026-02-03 15:25:28 +01:00
|
|
|
// Common expertise tags for suggestions
|
|
|
|
|
const SUGGESTED_TAGS = [
|
|
|
|
|
'Marine Biology',
|
|
|
|
|
'Ocean Conservation',
|
|
|
|
|
'Coral Reef Restoration',
|
|
|
|
|
'Sustainable Fisheries',
|
|
|
|
|
'Marine Policy',
|
|
|
|
|
'Ocean Technology',
|
|
|
|
|
'Climate Science',
|
|
|
|
|
'Biodiversity',
|
|
|
|
|
'Blue Economy',
|
|
|
|
|
'Coastal Management',
|
|
|
|
|
'Oceanography',
|
|
|
|
|
'Marine Pollution',
|
|
|
|
|
'Plastic Reduction',
|
|
|
|
|
'Renewable Energy',
|
|
|
|
|
'Business Development',
|
|
|
|
|
'Impact Investment',
|
|
|
|
|
'Social Entrepreneurship',
|
|
|
|
|
'Startup Mentoring',
|
|
|
|
|
]
|
|
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
export default function MemberInvitePage() {
|
|
|
|
|
const [step, setStep] = useState<Step>('input')
|
2026-02-02 20:07:03 +01:00
|
|
|
const [inputMethod, setInputMethod] = useState<'manual' | 'csv'>('manual')
|
|
|
|
|
const [rows, setRows] = useState<MemberRow[]>([createEmptyRow()])
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
const [parsedUsers, setParsedUsers] = useState<ParsedUser[]>([])
|
|
|
|
|
const [sendProgress, setSendProgress] = useState(0)
|
2026-02-02 20:07:03 +01:00
|
|
|
const [result, setResult] = useState<{
|
|
|
|
|
created: number
|
|
|
|
|
skipped: number
|
|
|
|
|
} | null>(null)
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
|
2026-02-03 22:15:22 +01:00
|
|
|
const utils = trpc.useUtils()
|
|
|
|
|
const bulkCreate = trpc.user.bulkCreate.useMutation({
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
// Invalidate user list to refresh the members table when navigating back
|
|
|
|
|
utils.user.list.invalidate()
|
|
|
|
|
},
|
|
|
|
|
})
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
// --- Manual entry helpers ---
|
2026-02-03 15:25:28 +01:00
|
|
|
const updateRow = (id: string, field: keyof MemberRow, value: string | string[]) => {
|
2026-02-02 20:07:03 +01:00
|
|
|
setRows((prev) =>
|
|
|
|
|
prev.map((r) => (r.id === id ? { ...r, [field]: value } : r))
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const removeRow = (id: string) => {
|
|
|
|
|
setRows((prev) => {
|
|
|
|
|
const filtered = prev.filter((r) => r.id !== id)
|
|
|
|
|
return filtered.length === 0 ? [createEmptyRow()] : filtered
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
})
|
2026-02-02 20:07:03 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const addRow = () => {
|
|
|
|
|
const lastRole = rows[rows.length - 1]?.role || 'JURY_MEMBER'
|
|
|
|
|
setRows((prev) => [...prev, createEmptyRow(lastRole)])
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-03 15:25:28 +01:00
|
|
|
// Per-row tag management
|
|
|
|
|
const addTagToRow = (id: string, tag: string) => {
|
|
|
|
|
const trimmed = tag.trim()
|
|
|
|
|
if (!trimmed) return
|
|
|
|
|
setRows((prev) =>
|
|
|
|
|
prev.map((r) => {
|
|
|
|
|
if (r.id !== id) return r
|
|
|
|
|
if (r.expertiseTags.includes(trimmed)) return r
|
|
|
|
|
return { ...r, expertiseTags: [...r.expertiseTags, trimmed], tagInput: '' }
|
|
|
|
|
})
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const removeTagFromRow = (id: string, tag: string) => {
|
|
|
|
|
setRows((prev) =>
|
|
|
|
|
prev.map((r) =>
|
|
|
|
|
r.id === id
|
|
|
|
|
? { ...r, expertiseTags: r.expertiseTags.filter((t) => t !== tag) }
|
|
|
|
|
: r
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get suggestions that haven't been added yet for a specific row
|
|
|
|
|
const getSuggestionsForRow = (row: MemberRow) => {
|
|
|
|
|
return SUGGESTED_TAGS.filter(
|
|
|
|
|
(tag) =>
|
|
|
|
|
!row.expertiseTags.includes(tag) &&
|
|
|
|
|
tag.toLowerCase().includes(row.tagInput.toLowerCase())
|
|
|
|
|
).slice(0, 5)
|
|
|
|
|
}
|
|
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
// --- CSV helpers ---
|
|
|
|
|
const handleCSVUpload = useCallback(
|
|
|
|
|
(e: React.ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
const file = e.target.files?.[0]
|
|
|
|
|
if (!file) return
|
|
|
|
|
Papa.parse<Record<string, string>>(file, {
|
|
|
|
|
header: true,
|
|
|
|
|
skipEmptyLines: true,
|
|
|
|
|
complete: (results) => {
|
|
|
|
|
const seenEmails = new Set<string>()
|
|
|
|
|
const users: ParsedUser[] = results.data.map((row) => {
|
|
|
|
|
const emailKey = Object.keys(row).find(
|
|
|
|
|
(key) =>
|
|
|
|
|
key.toLowerCase() === 'email' ||
|
|
|
|
|
key.toLowerCase().includes('email')
|
|
|
|
|
)
|
|
|
|
|
const nameKey = Object.keys(row).find(
|
|
|
|
|
(key) =>
|
|
|
|
|
key.toLowerCase() === 'name' ||
|
|
|
|
|
key.toLowerCase().includes('name')
|
|
|
|
|
)
|
|
|
|
|
const roleKey = Object.keys(row).find(
|
|
|
|
|
(key) =>
|
|
|
|
|
key.toLowerCase() === 'role' ||
|
|
|
|
|
key.toLowerCase().includes('role')
|
|
|
|
|
)
|
|
|
|
|
const email = emailKey ? row[emailKey]?.trim().toLowerCase() : ''
|
|
|
|
|
const name = nameKey ? row[nameKey]?.trim() : undefined
|
|
|
|
|
const rawRole = roleKey ? row[roleKey]?.trim().toUpperCase() : ''
|
|
|
|
|
const role: Role =
|
|
|
|
|
rawRole === 'MENTOR'
|
|
|
|
|
? 'MENTOR'
|
|
|
|
|
: rawRole === 'OBSERVER'
|
|
|
|
|
? 'OBSERVER'
|
|
|
|
|
: 'JURY_MEMBER'
|
|
|
|
|
const isValidFormat = emailRegex.test(email)
|
|
|
|
|
const isDuplicate = email ? seenEmails.has(email) : false
|
|
|
|
|
if (isValidFormat && !isDuplicate && email) seenEmails.add(email)
|
|
|
|
|
return {
|
|
|
|
|
email,
|
|
|
|
|
name,
|
|
|
|
|
role,
|
|
|
|
|
isValid: isValidFormat && !isDuplicate,
|
|
|
|
|
isDuplicate,
|
|
|
|
|
error: !email
|
|
|
|
|
? 'No email found'
|
|
|
|
|
: !isValidFormat
|
|
|
|
|
? 'Invalid email format'
|
|
|
|
|
: isDuplicate
|
|
|
|
|
? 'Duplicate email'
|
|
|
|
|
: undefined,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
setParsedUsers(users.filter((u) => u.email))
|
|
|
|
|
setStep('preview')
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
},
|
|
|
|
|
[]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// --- Parse manual rows into ParsedUser format ---
|
|
|
|
|
const parseManualRows = (): ParsedUser[] => {
|
|
|
|
|
const seenEmails = new Set<string>()
|
|
|
|
|
return rows
|
|
|
|
|
.filter((r) => r.email.trim())
|
|
|
|
|
.map((r) => {
|
|
|
|
|
const email = r.email.trim().toLowerCase()
|
|
|
|
|
const isValidFormat = emailRegex.test(email)
|
|
|
|
|
const isDuplicate = seenEmails.has(email)
|
|
|
|
|
if (isValidFormat && !isDuplicate) seenEmails.add(email)
|
|
|
|
|
return {
|
|
|
|
|
email,
|
|
|
|
|
name: r.name.trim() || undefined,
|
|
|
|
|
role: r.role,
|
2026-02-03 15:25:28 +01:00
|
|
|
expertiseTags: r.expertiseTags.length > 0 ? r.expertiseTags : undefined,
|
2026-02-02 20:07:03 +01:00
|
|
|
isValid: isValidFormat && !isDuplicate,
|
|
|
|
|
isDuplicate,
|
|
|
|
|
error: !isValidFormat
|
|
|
|
|
? 'Invalid email format'
|
|
|
|
|
: isDuplicate
|
|
|
|
|
? 'Duplicate email'
|
|
|
|
|
: undefined,
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
const handleManualProceed = () => {
|
|
|
|
|
const parsed = parseManualRows()
|
|
|
|
|
if (parsed.length === 0) return
|
|
|
|
|
setParsedUsers(parsed)
|
|
|
|
|
setStep('preview')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// --- Summary ---
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
const summary = useMemo(() => {
|
|
|
|
|
const validUsers = parsedUsers.filter((u) => u.isValid)
|
|
|
|
|
const invalidUsers = parsedUsers.filter((u) => !u.isValid)
|
2026-02-02 20:07:03 +01:00
|
|
|
return {
|
|
|
|
|
total: parsedUsers.length,
|
|
|
|
|
valid: validUsers.length,
|
|
|
|
|
invalid: invalidUsers.length,
|
|
|
|
|
validUsers,
|
|
|
|
|
invalidUsers,
|
|
|
|
|
}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
}, [parsedUsers])
|
|
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
const removeInvalidUsers = () =>
|
|
|
|
|
setParsedUsers(parsedUsers.filter((u) => u.isValid))
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
// --- Send ---
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
const handleSendInvites = async () => {
|
|
|
|
|
if (summary.valid === 0) return
|
2026-02-02 20:07:03 +01:00
|
|
|
setStep('sending')
|
|
|
|
|
setSendProgress(0)
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
try {
|
|
|
|
|
const result = await bulkCreate.mutateAsync({
|
2026-02-02 20:07:03 +01:00
|
|
|
users: summary.validUsers.map((u) => ({
|
|
|
|
|
email: u.email,
|
|
|
|
|
name: u.name,
|
|
|
|
|
role: u.role,
|
2026-02-03 15:25:28 +01:00
|
|
|
expertiseTags: u.expertiseTags,
|
2026-02-02 20:07:03 +01:00
|
|
|
})),
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
})
|
2026-02-02 20:07:03 +01:00
|
|
|
setSendProgress(100)
|
|
|
|
|
setResult(result)
|
|
|
|
|
setStep('complete')
|
|
|
|
|
} catch {
|
|
|
|
|
setStep('preview')
|
|
|
|
|
}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
}
|
|
|
|
|
|
2026-02-02 20:07:03 +01:00
|
|
|
const resetForm = () => {
|
|
|
|
|
setStep('input')
|
|
|
|
|
setRows([createEmptyRow()])
|
|
|
|
|
setParsedUsers([])
|
|
|
|
|
setResult(null)
|
|
|
|
|
setSendProgress(0)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const hasManualData = rows.some((r) => r.email.trim() || r.name.trim())
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
|
|
|
|
|
const steps: Array<{ key: Step; label: string }> = [
|
2026-02-02 20:07:03 +01:00
|
|
|
{ key: 'input', label: 'Input' },
|
|
|
|
|
{ key: 'preview', label: 'Preview' },
|
|
|
|
|
{ key: 'sending', label: 'Send' },
|
|
|
|
|
{ key: 'complete', label: 'Done' },
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
]
|
|
|
|
|
const currentStepIndex = steps.findIndex((s) => s.key === step)
|
|
|
|
|
|
|
|
|
|
const renderStep = () => {
|
|
|
|
|
switch (step) {
|
|
|
|
|
case 'input':
|
|
|
|
|
return (
|
|
|
|
|
<Card>
|
|
|
|
|
<CardHeader>
|
|
|
|
|
<CardTitle>Invite Members</CardTitle>
|
2026-02-02 20:07:03 +01:00
|
|
|
<CardDescription>
|
|
|
|
|
Add members individually or upload a CSV file
|
|
|
|
|
</CardDescription>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</CardHeader>
|
|
|
|
|
<CardContent className="space-y-6">
|
2026-02-02 20:07:03 +01:00
|
|
|
{/* Method toggle */}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div className="flex gap-2">
|
2026-02-02 20:07:03 +01:00
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant={inputMethod === 'manual' ? 'default' : 'outline'}
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={() => setInputMethod('manual')}
|
|
|
|
|
>
|
|
|
|
|
<UserPlus className="mr-2 h-4 w-4" />
|
|
|
|
|
Add Manually
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant={inputMethod === 'csv' ? 'default' : 'outline'}
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={() => setInputMethod('csv')}
|
|
|
|
|
>
|
|
|
|
|
<FileSpreadsheet className="mr-2 h-4 w-4" />
|
|
|
|
|
Upload CSV
|
|
|
|
|
</Button>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
|
|
|
|
{inputMethod === 'manual' ? (
|
2026-02-03 15:25:28 +01:00
|
|
|
<div className="space-y-4">
|
|
|
|
|
{/* Member cards */}
|
|
|
|
|
{rows.map((row, index) => (
|
2026-02-02 20:07:03 +01:00
|
|
|
<div
|
|
|
|
|
key={row.id}
|
2026-02-03 15:25:28 +01:00
|
|
|
className="rounded-lg border p-4 space-y-3"
|
2026-02-02 20:07:03 +01:00
|
|
|
>
|
2026-02-03 15:25:28 +01:00
|
|
|
<div className="flex items-center justify-between">
|
|
|
|
|
<span className="text-sm font-medium text-muted-foreground">
|
|
|
|
|
Member {index + 1}
|
|
|
|
|
</span>
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={() => removeRow(row.id)}
|
|
|
|
|
className="text-muted-foreground hover:text-destructive h-8 w-8 p-0"
|
|
|
|
|
>
|
|
|
|
|
<X className="h-4 w-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div className="grid gap-3 sm:grid-cols-[1fr_1fr_140px]">
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Full name"
|
|
|
|
|
value={row.name}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
updateRow(row.id, 'name', e.target.value)
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
<Input
|
|
|
|
|
type="email"
|
|
|
|
|
placeholder="email@example.com"
|
|
|
|
|
value={row.email}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
updateRow(row.id, 'email', e.target.value)
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
<Select
|
|
|
|
|
value={row.role}
|
|
|
|
|
onValueChange={(v) =>
|
|
|
|
|
updateRow(row.id, 'role', v)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
<SelectTrigger>
|
|
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
<SelectContent>
|
|
|
|
|
<SelectItem value="JURY_MEMBER">
|
|
|
|
|
Jury Member
|
|
|
|
|
</SelectItem>
|
|
|
|
|
<SelectItem value="MENTOR">Mentor</SelectItem>
|
|
|
|
|
<SelectItem value="OBSERVER">Observer</SelectItem>
|
|
|
|
|
</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Per-member expertise tags */}
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label className="text-xs text-muted-foreground">
|
|
|
|
|
Expertise Tags (optional)
|
|
|
|
|
</Label>
|
|
|
|
|
<div className="relative">
|
|
|
|
|
<Input
|
|
|
|
|
placeholder="Type tag and press Enter or comma..."
|
|
|
|
|
value={row.tagInput}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
updateRow(row.id, 'tagInput', e.target.value)
|
|
|
|
|
}
|
|
|
|
|
onKeyDown={(e) => {
|
|
|
|
|
if (e.key === 'Enter' || e.key === ',') {
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
addTagToRow(row.id, row.tagInput)
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Tag suggestions */}
|
|
|
|
|
{row.tagInput && getSuggestionsForRow(row).length > 0 && (
|
|
|
|
|
<div className="flex flex-wrap gap-1">
|
|
|
|
|
{getSuggestionsForRow(row).map((suggestion) => (
|
|
|
|
|
<Button
|
|
|
|
|
key={suggestion}
|
|
|
|
|
type="button"
|
|
|
|
|
variant="outline"
|
|
|
|
|
size="sm"
|
|
|
|
|
className="h-6 text-xs"
|
|
|
|
|
onClick={() => addTagToRow(row.id, suggestion)}
|
|
|
|
|
>
|
|
|
|
|
+ {suggestion}
|
|
|
|
|
</Button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Quick suggestions when empty */}
|
|
|
|
|
{!row.tagInput && row.expertiseTags.length === 0 && (
|
|
|
|
|
<div className="flex flex-wrap gap-1">
|
|
|
|
|
<span className="text-xs text-muted-foreground mr-1">
|
|
|
|
|
Suggestions:
|
|
|
|
|
</span>
|
|
|
|
|
{SUGGESTED_TAGS.slice(0, 5).map((suggestion) => (
|
|
|
|
|
<Button
|
|
|
|
|
key={suggestion}
|
|
|
|
|
type="button"
|
|
|
|
|
variant="ghost"
|
|
|
|
|
size="sm"
|
|
|
|
|
className="h-6 text-xs px-2"
|
|
|
|
|
onClick={() => addTagToRow(row.id, suggestion)}
|
|
|
|
|
>
|
|
|
|
|
+ {suggestion}
|
|
|
|
|
</Button>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
|
|
|
|
|
{/* Added tags */}
|
|
|
|
|
{row.expertiseTags.length > 0 && (
|
|
|
|
|
<div className="flex flex-wrap gap-1.5">
|
|
|
|
|
{row.expertiseTags.map((tag) => (
|
|
|
|
|
<Badge
|
|
|
|
|
key={tag}
|
|
|
|
|
variant="secondary"
|
|
|
|
|
className="gap-1 pr-1"
|
|
|
|
|
>
|
|
|
|
|
{tag}
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
onClick={() => removeTagFromRow(row.id, tag)}
|
|
|
|
|
className="ml-1 hover:text-destructive rounded-full"
|
|
|
|
|
>
|
|
|
|
|
<X className="h-3 w-3" />
|
|
|
|
|
</button>
|
|
|
|
|
</Badge>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
type="button"
|
|
|
|
|
variant="outline"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={addRow}
|
|
|
|
|
className="w-full"
|
|
|
|
|
>
|
|
|
|
|
<Plus className="mr-2 h-4 w-4" />
|
|
|
|
|
Add another member
|
|
|
|
|
</Button>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="space-y-2">
|
|
|
|
|
<Label>CSV File</Label>
|
2026-02-02 20:07:03 +01:00
|
|
|
<p className="text-xs text-muted-foreground">
|
|
|
|
|
CSV should have columns: name, email, role (optional)
|
|
|
|
|
</p>
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
'border-2 border-dashed rounded-lg p-6 text-center cursor-pointer transition-colors',
|
|
|
|
|
'hover:border-primary/50'
|
|
|
|
|
)}
|
|
|
|
|
onClick={() =>
|
|
|
|
|
document.getElementById('csv-input')?.click()
|
|
|
|
|
}
|
|
|
|
|
>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<FileSpreadsheet className="mx-auto h-10 w-10 text-muted-foreground" />
|
2026-02-02 20:07:03 +01:00
|
|
|
<p className="mt-2 font-medium">
|
|
|
|
|
Drop CSV file here or click to browse
|
|
|
|
|
</p>
|
|
|
|
|
<Input
|
|
|
|
|
id="csv-input"
|
|
|
|
|
type="file"
|
|
|
|
|
accept=".csv"
|
|
|
|
|
onChange={handleCSVUpload}
|
|
|
|
|
className="hidden"
|
|
|
|
|
/>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
2026-02-02 20:07:03 +01:00
|
|
|
|
|
|
|
|
{/* Actions */}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div className="flex justify-between pt-4">
|
2026-02-02 20:07:03 +01:00
|
|
|
<Button variant="outline" asChild>
|
|
|
|
|
<Link href="/admin/members">
|
|
|
|
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
|
|
|
Cancel
|
|
|
|
|
</Link>
|
|
|
|
|
</Button>
|
|
|
|
|
{inputMethod === 'manual' && (
|
|
|
|
|
<Button
|
|
|
|
|
onClick={handleManualProceed}
|
|
|
|
|
disabled={!hasManualData}
|
|
|
|
|
>
|
|
|
|
|
Preview
|
|
|
|
|
<ArrowRight className="ml-2 h-4 w-4" />
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
)
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
case 'preview':
|
|
|
|
|
return (
|
|
|
|
|
<Card>
|
2026-02-02 20:07:03 +01:00
|
|
|
<CardHeader>
|
|
|
|
|
<CardTitle>Preview Invitations</CardTitle>
|
|
|
|
|
<CardDescription>
|
|
|
|
|
Review the list of members to invite
|
|
|
|
|
</CardDescription>
|
|
|
|
|
</CardHeader>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<CardContent className="space-y-6">
|
|
|
|
|
<div className="grid gap-4 sm:grid-cols-3">
|
2026-02-02 20:07:03 +01:00
|
|
|
<div className="rounded-lg bg-muted p-4 text-center">
|
|
|
|
|
<p className="text-3xl font-bold">{summary.total}</p>
|
|
|
|
|
<p className="text-sm text-muted-foreground">Total</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="rounded-lg bg-green-500/10 p-4 text-center">
|
|
|
|
|
<p className="text-3xl font-bold text-green-600">
|
|
|
|
|
{summary.valid}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-sm text-muted-foreground">Valid</p>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="rounded-lg bg-red-500/10 p-4 text-center">
|
|
|
|
|
<p className="text-3xl font-bold text-red-600">
|
|
|
|
|
{summary.invalid}
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-sm text-muted-foreground">Invalid</p>
|
|
|
|
|
</div>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
{summary.invalid > 0 && (
|
|
|
|
|
<div className="flex items-start gap-3 rounded-lg bg-amber-500/10 p-4 text-amber-700">
|
2026-02-02 20:07:03 +01:00
|
|
|
<AlertCircle className="h-5 w-5 shrink-0 mt-0.5" />
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<p className="font-medium">
|
|
|
|
|
{summary.invalid} email(s) have issues
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
<Button
|
|
|
|
|
variant="outline"
|
|
|
|
|
size="sm"
|
|
|
|
|
onClick={removeInvalidUsers}
|
|
|
|
|
className="shrink-0"
|
|
|
|
|
>
|
|
|
|
|
Remove Invalid
|
|
|
|
|
</Button>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
|
|
|
|
)}
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div className="rounded-lg border max-h-80 overflow-y-auto">
|
|
|
|
|
<Table>
|
2026-02-02 20:07:03 +01:00
|
|
|
<TableHeader>
|
|
|
|
|
<TableRow>
|
|
|
|
|
<TableHead>Name</TableHead>
|
|
|
|
|
<TableHead>Email</TableHead>
|
|
|
|
|
<TableHead>Role</TableHead>
|
|
|
|
|
<TableHead>Status</TableHead>
|
|
|
|
|
</TableRow>
|
|
|
|
|
</TableHeader>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<TableBody>
|
|
|
|
|
{parsedUsers.map((user, index) => (
|
2026-02-02 20:07:03 +01:00
|
|
|
<TableRow
|
|
|
|
|
key={index}
|
|
|
|
|
className={cn(!user.isValid && 'bg-red-500/5')}
|
|
|
|
|
>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<TableCell>{user.name || '-'}</TableCell>
|
2026-02-02 20:07:03 +01:00
|
|
|
<TableCell className="font-mono text-sm">
|
|
|
|
|
{user.email}
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell>
|
|
|
|
|
<Badge variant="outline">
|
|
|
|
|
{ROLE_LABELS[user.role]}
|
|
|
|
|
</Badge>
|
|
|
|
|
</TableCell>
|
|
|
|
|
<TableCell>
|
|
|
|
|
{user.isValid ? (
|
|
|
|
|
<Badge
|
|
|
|
|
variant="outline"
|
|
|
|
|
className="text-green-600"
|
|
|
|
|
>
|
|
|
|
|
<CheckCircle2 className="mr-1 h-3 w-3" />
|
|
|
|
|
Valid
|
|
|
|
|
</Badge>
|
|
|
|
|
) : (
|
|
|
|
|
<Badge variant="destructive">{user.error}</Badge>
|
|
|
|
|
)}
|
|
|
|
|
</TableCell>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</TableRow>
|
|
|
|
|
))}
|
|
|
|
|
</TableBody>
|
|
|
|
|
</Table>
|
|
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div className="flex justify-between pt-4">
|
2026-02-02 20:07:03 +01:00
|
|
|
<Button
|
|
|
|
|
variant="outline"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
setParsedUsers([])
|
|
|
|
|
setStep('input')
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
|
|
|
Back
|
|
|
|
|
</Button>
|
|
|
|
|
<Button
|
|
|
|
|
onClick={handleSendInvites}
|
|
|
|
|
disabled={summary.valid === 0 || bulkCreate.isPending}
|
|
|
|
|
>
|
|
|
|
|
{bulkCreate.isPending ? (
|
|
|
|
|
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
|
|
|
) : (
|
|
|
|
|
<Users className="mr-2 h-4 w-4" />
|
|
|
|
|
)}
|
|
|
|
|
Create & Invite {summary.valid} Member
|
|
|
|
|
{summary.valid !== 1 ? 's' : ''}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</Button>
|
|
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
|
|
|
|
{bulkCreate.error && (
|
|
|
|
|
<div className="flex items-center gap-2 rounded-lg bg-destructive/10 p-4 text-destructive">
|
|
|
|
|
<AlertCircle className="h-5 w-5" />
|
|
|
|
|
<span>{bulkCreate.error.message}</span>
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
)
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
case 'sending':
|
|
|
|
|
return (
|
2026-02-02 20:07:03 +01:00
|
|
|
<Card>
|
|
|
|
|
<CardContent className="flex flex-col items-center justify-center py-12">
|
|
|
|
|
<Loader2 className="h-12 w-12 animate-spin text-primary" />
|
|
|
|
|
<p className="mt-4 font-medium">
|
|
|
|
|
Creating members and sending invitations...
|
|
|
|
|
</p>
|
|
|
|
|
<Progress value={sendProgress} className="mt-4 w-48" />
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
)
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
case 'complete':
|
|
|
|
|
return (
|
|
|
|
|
<Card>
|
|
|
|
|
<CardContent className="flex flex-col items-center justify-center py-12">
|
2026-02-02 20:07:03 +01:00
|
|
|
<div className="flex h-16 w-16 items-center justify-center rounded-full bg-green-500/10">
|
|
|
|
|
<CheckCircle2 className="h-8 w-8 text-green-600" />
|
|
|
|
|
</div>
|
|
|
|
|
<p className="mt-4 text-xl font-semibold">
|
|
|
|
|
Invitations Sent!
|
|
|
|
|
</p>
|
|
|
|
|
<p className="text-muted-foreground text-center max-w-sm mt-2">
|
|
|
|
|
{result?.created} member{result?.created !== 1 ? 's' : ''}{' '}
|
|
|
|
|
created and invited.
|
|
|
|
|
{result?.skipped
|
|
|
|
|
? ` ${result.skipped} skipped (already exist).`
|
|
|
|
|
: ''}
|
|
|
|
|
</p>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div className="mt-6 flex gap-3">
|
2026-02-02 20:07:03 +01:00
|
|
|
<Button variant="outline" asChild>
|
|
|
|
|
<Link href="/admin/members">View Members</Link>
|
|
|
|
|
</Button>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<Button onClick={resetForm}>Invite More</Button>
|
|
|
|
|
</div>
|
|
|
|
|
</CardContent>
|
|
|
|
|
</Card>
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-6">
|
|
|
|
|
<div className="flex items-center gap-4">
|
2026-02-02 20:07:03 +01:00
|
|
|
<Button variant="ghost" asChild className="-ml-4">
|
|
|
|
|
<Link href="/admin/members">
|
|
|
|
|
<ArrowLeft className="mr-2 h-4 w-4" />
|
|
|
|
|
Back to Members
|
|
|
|
|
</Link>
|
|
|
|
|
</Button>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div>
|
2026-02-02 20:07:03 +01:00
|
|
|
<h1 className="text-2xl font-semibold tracking-tight">
|
|
|
|
|
Invite Members
|
|
|
|
|
</h1>
|
|
|
|
|
<p className="text-muted-foreground">
|
|
|
|
|
Add new members to the platform
|
|
|
|
|
</p>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
|
|
|
|
{/* Step indicator */}
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
<div className="flex items-center justify-center gap-2">
|
|
|
|
|
{steps.map((s, index) => (
|
|
|
|
|
<div key={s.key} className="flex items-center">
|
2026-02-02 20:07:03 +01:00
|
|
|
{index > 0 && (
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
'h-0.5 w-8 mx-1',
|
|
|
|
|
index <= currentStepIndex ? 'bg-primary' : 'bg-muted'
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
<div
|
|
|
|
|
className={cn(
|
|
|
|
|
'flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium',
|
|
|
|
|
index === currentStepIndex
|
|
|
|
|
? 'bg-primary text-primary-foreground'
|
|
|
|
|
: index < currentStepIndex
|
|
|
|
|
? 'bg-primary/20 text-primary'
|
|
|
|
|
: 'bg-muted text-muted-foreground'
|
|
|
|
|
)}
|
|
|
|
|
>
|
|
|
|
|
{index + 1}
|
|
|
|
|
</div>
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
</div>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
2026-02-02 20:07:03 +01:00
|
|
|
|
Implement Prototype 1 improvements: unified members, project filters, audit expansion, filtering rounds, special awards
- Unified Member Management: merge /admin/users and /admin/mentors into /admin/members with role tabs, search, pagination
- Project List Filters: add search, multi-status filter, round/category/country selects, boolean toggles, URL persistence
- Audit Log Expansion: track logins, round state changes, evaluation submissions, file access, role changes via shared logAudit utility
- Founding Date Field: add foundedAt to Project model with CSV import support
- Filtering Round System: configurable rules (field-based, document check, AI screening), execution engine, results review with override/reinstate
- Special Awards System: named awards with eligibility criteria, dedicated jury, PICK_WINNER/RANKED/SCORED voting modes, AI eligibility
- Dashboard resilience: wrap heavy queries in try-catch to prevent error boundary on transient DB failures
- Reusable pagination component extracted to src/components/shared/pagination.tsx
- Old /admin/users and /admin/mentors routes redirect to /admin/members
- Prisma migration for all schema additions (additive, no data loss)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:58:29 +01:00
|
|
|
{renderStep()}
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|