Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 77 additions & 61 deletions app/dashboard/company/[slug]/events/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ import {
} from '@/components/ui/alert-dialog'

export default function CompanyEventsPage() {
const { currentCompany, loading: companyLoading } = useCompanyContext()
const { currentCompany, userRole, loading: companyLoading } = useCompanyContext()
const isPendingInvitation = usePendingInvitationRedirect()
const [events, setEvents] = useState<Event[]>([])
const [loading, setLoading] = useState(true)
const [searchTerm, setSearchTerm] = useState('')
const [deletingEventSlug, setDeletingEventSlug] = useState<string | null>(null)

const canManageEvents = userRole && ['owner', 'admin', 'editor'].includes(userRole)

const fetchEvents = useCallback(async () => {
if (!currentCompany) return

Expand Down Expand Up @@ -170,15 +172,17 @@ export default function CompanyEventsPage() {
<div>
<h1 className="text-3xl font-bold tracking-tight">Events</h1>
<p className="text-muted-foreground mt-1">
Manage your company&apos;s events and hackathons
{canManageEvents ? "Manage your company's events and hackathons" : "View your company's events"}
</p>
</div>
<Link href="/dashboard/company/events/create">
<Button>
<Plus className="h-4 w-4 mr-2" />
Create Event
</Button>
</Link>
{canManageEvents && (
<Link href={`/dashboard/company/${currentCompany?.slug}/events/create`}>
<Button>
<Plus className="h-4 w-4 mr-2" />
Create Event
</Button>
</Link>
)}
</div>

{/* Stats Cards */}
Expand Down Expand Up @@ -239,7 +243,7 @@ export default function CompanyEventsPage() {
<CardHeader>
<CardTitle>All Events ({filteredEvents.length})</CardTitle>
<CardDescription>
View and manage all your events
{canManageEvents ? 'View and manage all your events' : 'View all company events'}
</CardDescription>
</CardHeader>
<CardContent>
Expand All @@ -254,10 +258,10 @@ export default function CompanyEventsPage() {
No events found
</h3>
<p className="text-gray-500 dark:text-gray-400 mb-4">
{searchTerm ? 'Try adjusting your search' : 'Get started by creating your first event'}
{searchTerm ? 'Try adjusting your search' : canManageEvents ? 'Get started by creating your first event' : 'No events available yet'}
</p>
{!searchTerm && (
<Link href="/dashboard/company/events/create">
{!searchTerm && canManageEvents && (
<Link href={`/dashboard/company/${currentCompany?.slug}/events/create`}>
<Button>
<Plus className="h-4 w-4 mr-2" />
Create Event
Expand All @@ -276,7 +280,7 @@ export default function CompanyEventsPage() {
<TableHead>Approval</TableHead>
<TableHead>Views</TableHead>
<TableHead>Registered</TableHead>
<TableHead>Actions</TableHead>
{canManageEvents && <TableHead>Actions</TableHead>}
</TableRow>
</TableHeader>
<TableBody>
Expand Down Expand Up @@ -308,59 +312,71 @@ export default function CompanyEventsPage() {
</div>
</TableCell>
<TableCell>{event.registered || 0}</TableCell>
<TableCell>
<div className="flex items-center gap-2">
<Link href={`/dashboard/company/${currentCompany.slug}/events/${event.slug}/edit`}>
<Button variant="outline" size="sm">
<Edit className="h-4 w-4" />
</Button>
</Link>
{event.approval_status === 'approved' && (
{canManageEvents ? (
<TableCell>
<div className="flex items-center gap-2">
<Link href={`/dashboard/company/${currentCompany.slug}/events/${event.slug}/edit`}>
<Button variant="outline" size="sm">
<Edit className="h-4 w-4" />
</Button>
</Link>
{event.approval_status === 'approved' && (
<Link href={`/events/${event.slug}`} target="_blank">
<Button variant="outline" size="sm">
<Eye className="h-4 w-4" />
</Button>
</Link>
)}
<AlertDialog>
<AlertDialogTrigger asChild>
<Button
variant="outline"
size="sm"
disabled={deletingEventSlug === event.slug}
>
{deletingEventSlug === event.slug ? (
<div className="h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-gray-600" />
) : (
<Trash2 className="h-4 w-4 text-red-600" />
)}
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete Event</AlertDialogTitle>
<AlertDialogDescription>
Are you sure you want to delete &quot;{event.title}&quot;? This action cannot be undone.
{event.registered && event.registered > 0 && (
<span className="block mt-2 text-red-600 font-medium">
Warning: This event has {event.registered} registered participant{event.registered > 1 ? 's' : ''}.
</span>
)}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={() => handleDeleteEvent(event.slug)}
className="bg-red-600 hover:bg-red-700"
>
Delete
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
</TableCell>
) : (
event.approval_status === 'approved' && (
<TableCell>
<Link href={`/events/${event.slug}`} target="_blank">
<Button variant="outline" size="sm">
<Eye className="h-4 w-4" />
</Button>
</Link>
)}
<AlertDialog>
<AlertDialogTrigger asChild>
<Button
variant="outline"
size="sm"
disabled={deletingEventSlug === event.slug}
>
{deletingEventSlug === event.slug ? (
<div className="h-4 w-4 animate-spin rounded-full border-2 border-gray-300 border-t-gray-600" />
) : (
<Trash2 className="h-4 w-4 text-red-600" />
)}
</Button>
</AlertDialogTrigger>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Delete Event</AlertDialogTitle>
<AlertDialogDescription>
Are you sure you want to delete &quot;{event.title}&quot;? This action cannot be undone.
{event.registered && event.registered > 0 && (
<span className="block mt-2 text-red-600 font-medium">
Warning: This event has {event.registered} registered participant{event.registered > 1 ? 's' : ''}.
</span>
)}
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction
onClick={() => handleDeleteEvent(event.slug)}
className="bg-red-600 hover:bg-red-700"
>
Delete
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</div>
</TableCell>
</TableCell>
)
)}
</TableRow>
))}
</TableBody>
Expand Down
58 changes: 37 additions & 21 deletions app/dashboard/company/[slug]/hackathons/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ interface Hackathon {
}

export default function CompanyHackathonsPage() {
const { currentCompany, loading: companyLoading } = useCompanyContext()
const { currentCompany, userRole, loading: companyLoading } = useCompanyContext()
const isPendingInvitation = usePendingInvitationRedirect()
const [hackathons, setHackathons] = useState<Hackathon[]>([])
const [loading, setLoading] = useState(true)
const [searchTerm, setSearchTerm] = useState('')

const canManageEvents = userRole && ['owner', 'admin', 'editor'].includes(userRole)

const fetchHackathons = useCallback(async () => {
if (!currentCompany) return

Expand Down Expand Up @@ -149,15 +151,17 @@ export default function CompanyHackathonsPage() {
<div>
<h1 className="text-3xl font-bold tracking-tight">Hackathons</h1>
<p className="text-muted-foreground mt-1">
Manage your company&apos;s hackathons and coding challenges
{canManageEvents ? "Manage your company's hackathons and coding challenges" : "View your company's hackathons"}
</p>
</div>
<Link href={`/dashboard/company/${currentCompany.slug}/hackathons/create`}>
<Button>
<Plus className="h-4 w-4 mr-2" />
Create Hackathon
</Button>
</Link>
{canManageEvents && (
<Link href={`/dashboard/company/${currentCompany.slug}/hackathons/create`}>
<Button>
<Plus className="h-4 w-4 mr-2" />
Create Hackathon
</Button>
</Link>
)}
</div>

{/* Stats Cards */}
Expand Down Expand Up @@ -218,7 +222,7 @@ export default function CompanyHackathonsPage() {
<CardHeader>
<CardTitle>All Hackathons ({filteredHackathons.length})</CardTitle>
<CardDescription>
View and manage all your hackathons
{canManageEvents ? 'View and manage all your hackathons' : 'View all company hackathons'}
</CardDescription>
</CardHeader>
<CardContent>
Expand Down Expand Up @@ -247,7 +251,7 @@ export default function CompanyHackathonsPage() {
<TableHead>Approval</TableHead>
<TableHead>Views</TableHead>
<TableHead>Participants</TableHead>
<TableHead>Actions</TableHead>
{canManageEvents && <TableHead>Actions</TableHead>}
</TableRow>
</TableHeader>
<TableBody>
Expand Down Expand Up @@ -279,22 +283,34 @@ export default function CompanyHackathonsPage() {
</div>
</TableCell>
<TableCell>{hackathon.registered || 0}</TableCell>
<TableCell>
<div className="flex items-center gap-2">
<Link href={`/dashboard/company/${currentCompany.slug}/hackathons/${hackathon.slug}/edit`}>
<Button variant="outline" size="sm">
<Edit className="h-4 w-4" />
</Button>
</Link>
{hackathon.approval_status === 'approved' && (
{canManageEvents ? (
<TableCell>
<div className="flex items-center gap-2">
<Link href={`/dashboard/company/${currentCompany.slug}/hackathons/${hackathon.slug}/edit`}>
<Button variant="outline" size="sm">
<Edit className="h-4 w-4" />
</Button>
</Link>
{hackathon.approval_status === 'approved' && (
<Link href={`/hackathons/${hackathon.slug}`} target="_blank">
<Button variant="outline" size="sm">
<Eye className="h-4 w-4" />
</Button>
</Link>
)}
</div>
</TableCell>
) : (
hackathon.approval_status === 'approved' && (
<TableCell>
<Link href={`/hackathons/${hackathon.slug}`} target="_blank">
<Button variant="outline" size="sm">
<Eye className="h-4 w-4" />
</Button>
</Link>
)}
</div>
</TableCell>
</TableCell>
)
)}
</TableRow>
))}
</TableBody>
Expand Down
34 changes: 19 additions & 15 deletions app/dashboard/company/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,16 @@ export default function CompanySlugDashboardPage() {
Here&apos;s what&apos;s happening with {currentCompany.name}
</p>
</div>
<div className="flex gap-2">
<Button asChild>
<Link href={`/dashboard/company/${currentCompany.slug}/events/create`}>
<Plus className="mr-2 h-4 w-4" />
Create Event
</Link>
</Button>
</div>
{userRole && ['owner', 'admin', 'editor'].includes(userRole) && (
<div className="flex gap-2">
<Button asChild>
<Link href={`/dashboard/company/${currentCompany.slug}/events/create`}>
<Plus className="mr-2 h-4 w-4" />
Create Event
</Link>
</Button>
</div>
)}
</div>

{/* Subscription Expiry Warning */}
Expand Down Expand Up @@ -162,13 +164,15 @@ export default function CompanySlugDashboardPage() {
</p>
</div>
</div>
<div className="pt-4">
<Button asChild variant="outline">
<Link href={`/dashboard/company/${currentCompany.slug}/settings`}>
Edit Company Profile
</Link>
</Button>
</div>
{userRole && ['owner', 'admin'].includes(userRole) && (
<div className="pt-4">
<Button asChild variant="outline">
<Link href={`/dashboard/company/${currentCompany.slug}/settings`}>
Edit Company Profile
</Link>
</Button>
</div>
)}
</CardContent>
</Card>
</div>
Expand Down
18 changes: 10 additions & 8 deletions app/dashboard/company/[slug]/subscription/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { companyService } from '@/lib/services/company-service'
import { SubscriptionManagement } from '@/components/subscription/SubscriptionManagement'

export const metadata: Metadata = {
title: 'Subscription Management | CodeUnia',
description: 'Manage your company subscription and billing',
title: 'Subscription | CodeUnia',
description: 'View your company subscription and billing information',
}

interface PageProps {
Expand Down Expand Up @@ -59,17 +59,19 @@ export default async function SubscriptionPage({ params }: PageProps) {
redirect('/dashboard/company')
}

// Only owners and admins can manage subscription
if (!['owner', 'admin'].includes(membership.role)) {
redirect(`/dashboard/company/${slug}`)
}
// Check if user can manage subscription
const canManageSubscription = ['owner', 'admin'].includes(membership.role)

return (
<div className="container mx-auto py-8 px-4 max-w-6xl">
<div className="mb-8">
<h1 className="text-3xl font-bold mb-2">Subscription Management</h1>
<h1 className="text-3xl font-bold mb-2">
{canManageSubscription ? 'Subscription Management' : 'Subscription Information'}
</h1>
<p className="text-muted-foreground">
Manage your subscription plan and view usage details
{canManageSubscription
? 'Manage your subscription plan and view usage details'
: 'View your company subscription plan and usage details'}
</p>
</div>

Expand Down
Loading
Loading