From cdea36f795417c47831dfb8b47a2d2b8bbf61ae7 Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 15 Nov 2025 09:41:12 +0530 Subject: [PATCH 1/2] docs: Update README with enhanced platform description and remove SECURITY.md - Expand README with comprehensive platform highlights and value proposition - Reorganize features section with detailed descriptions of core capabilities - Update intellectual property notice with clearer GitHub organization information - Add emphasis on multi-company marketplace, analytics, and event management features - Remove outdated SECURITY.md template file - Enhance company events management page with event deletion functionality - Add delete event button with confirmation dialog to prevent accidental removal - Implement API integration for event deletion with proper error handling and user feedback - Add loading state indicator during event deletion process - Consolidate event management UI with edit, view, and delete actions --- README.md | 48 +++++++++---- SECURITY.md | 21 ------ app/dashboard/company/[slug]/events/page.tsx | 75 +++++++++++++++++++- app/dashboard/company/events/page.tsx | 75 +++++++++++++++++++- 4 files changed, 183 insertions(+), 36 deletions(-) delete mode 100644 SECURITY.md diff --git a/README.md b/README.md index a4f324de..cd7626fa 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,46 @@ # 🌐 Codeunia -*Codeunia* is a dynamic platform designed to empower developers by keeping them informed and inspired. Stay updated with the latest hackathons, AI breakthroughs, tech blogs, and developer tools — all in one place. +*Codeunia* is a professional developer platform designed to power the modern tech ecosystem. We bring organizations, developers, and innovators together through a unified marketplace for hackathons, events, insights, and tools — all in one place. -## 🚀 Features +## 🚀 Platform Highlights -- 🔍 Discover Upcoming Hackathons -- 🧠 Latest News in Artificial Intelligence & Machine Learning -- ✍ Developer-Focused Blog Posts -- 📅 Event Calendar and Reminders -- 🧰 Curated Tools and Resources for Developers *(Coming Soon)* -- 📬 Newsletter Subscription *(Coming Soon)* -- 📊 Community Polls and Discussions *(Coming Soon)* +* 🏢 **Multi-Company Event Marketplace** + Verified organizations can host, manage, and scale their own hackathons and tech events. + +* 🔍 **Discover Global Hackathons** + Stay updated with curated events from top companies and institutions. + +* 🧠 **Tech & AI Insights** + Access the latest breakthroughs in AI, ML, startups, and software engineering. + +* ✍ **Developer Articles & Blogs** + In-depth writeups from experts, engineers, and industry contributors. + +* 📅 **Smart Event Calendar & Reminders** + Never miss an opportunity — get personalized updates and alerts. + +* 🎯 **Organization Dashboards** + Complete event lifecycle management: creation, moderation, registrations, analytics, and monetization. + +* 📊 **Advanced Analytics for Hosts** + Real-time insights into views, clicks, conversions, and performance trends. + +* 🧰 **Developer Tools & Resources** *(Coming Soon)* + Curated utilities and productivity enhancers for engineering teams. + +* 📬 **Tech Newsletter** *(Coming Soon)* + Weekly insights for developers and organizations. --- -### ⚠️ Disclaimer +## ⚠️ Intellectual Property Notice + +Codeunia operates multiple GitHub organizations for structured development and deployment: -> We do have an official GitHub organization: [github.com/codeunia](https://github.com/codeunia). -> However, due to being a student-led initiative and operating with limited resources (like funds for paid GitHub features), we are currently using [github.com/codeunia-dev](https://github.com/codeunia-dev) to manage our repositories and development. +* **github.com/codeunia** — Official organization +* **github.com/codeunia-dev** — Development & engineering projects -> **All code, assets, and content under both profiles are the intellectual property of Codeunia. Unauthorized use, reproduction, or redistribution is strictly prohibited without written permission.** +**All source code, assets, and content under these organizations are the intellectual property of Codeunia. +Unauthorized use, reproduction, or redistribution is strictly prohibited without prior written approval.** --- diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 034e8480..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,21 +0,0 @@ -# Security Policy - -## Supported Versions - -Use this section to tell people about which versions of your project are -currently being supported with security updates. - -| Version | Supported | -| ------- | ------------------ | -| 5.1.x | :white_check_mark: | -| 5.0.x | :x: | -| 4.0.x | :white_check_mark: | -| < 4.0 | :x: | - -## Reporting a Vulnerability - -Use this section to tell people how to report a vulnerability. - -Tell them where to go, how often they can expect to get an update on a -reported vulnerability, what to expect if the vulnerability is accepted or -declined, etc. diff --git a/app/dashboard/company/[slug]/events/page.tsx b/app/dashboard/company/[slug]/events/page.tsx index 630139a1..e46252cf 100644 --- a/app/dashboard/company/[slug]/events/page.tsx +++ b/app/dashboard/company/[slug]/events/page.tsx @@ -7,16 +7,28 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Badge } from '@/components/ui/badge' import { Input } from '@/components/ui/input' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Calendar, Search, Plus, Edit, Eye, Clock, CheckCircle, XCircle, AlertCircle } from 'lucide-react' +import { Calendar, Search, Plus, Edit, Eye, Clock, CheckCircle, XCircle, AlertCircle, Trash2 } from 'lucide-react' import { toast } from 'sonner' import Link from 'next/link' import { Event } from '@/types/events' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from '@/components/ui/alert-dialog' export default function CompanyEventsPage() { const { currentCompany, loading: companyLoading } = useCompanyContext() const [events, setEvents] = useState([]) const [loading, setLoading] = useState(true) const [searchTerm, setSearchTerm] = useState('') + const [deletingEventSlug, setDeletingEventSlug] = useState(null) const fetchEvents = useCallback(async () => { if (!currentCompany) return @@ -51,6 +63,30 @@ export default function CompanyEventsPage() { event.category.toLowerCase().includes(searchTerm.toLowerCase()) ) + const handleDeleteEvent = async (eventSlug: string) => { + try { + setDeletingEventSlug(eventSlug) + + const response = await fetch(`/api/events/${eventSlug}`, { + method: 'DELETE', + }) + + if (!response.ok) { + throw new Error('Failed to delete event') + } + + toast.success('Event deleted successfully') + + // Refresh the events list + await fetchEvents() + } catch (error) { + console.error('Error deleting event:', error) + toast.error('Failed to delete event') + } finally { + setDeletingEventSlug(null) + } + } + const stats = { total: events.length, approved: events.filter(e => e.approval_status === 'approved').length, @@ -276,6 +312,43 @@ export default function CompanyEventsPage() { )} + + + + + + + Delete Event + + Are you sure you want to delete "{event.title}"? This action cannot be undone. + {event.registered && event.registered > 0 && ( + + Warning: This event has {event.registered} registered participant{event.registered > 1 ? 's' : ''}. + + )} + + + + Cancel + handleDeleteEvent(event.slug)} + className="bg-red-600 hover:bg-red-700" + > + Delete + + + + diff --git a/app/dashboard/company/events/page.tsx b/app/dashboard/company/events/page.tsx index 630139a1..e46252cf 100644 --- a/app/dashboard/company/events/page.tsx +++ b/app/dashboard/company/events/page.tsx @@ -7,16 +7,28 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/com import { Badge } from '@/components/ui/badge' import { Input } from '@/components/ui/input' import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table' -import { Calendar, Search, Plus, Edit, Eye, Clock, CheckCircle, XCircle, AlertCircle } from 'lucide-react' +import { Calendar, Search, Plus, Edit, Eye, Clock, CheckCircle, XCircle, AlertCircle, Trash2 } from 'lucide-react' import { toast } from 'sonner' import Link from 'next/link' import { Event } from '@/types/events' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, + AlertDialogTrigger, +} from '@/components/ui/alert-dialog' export default function CompanyEventsPage() { const { currentCompany, loading: companyLoading } = useCompanyContext() const [events, setEvents] = useState([]) const [loading, setLoading] = useState(true) const [searchTerm, setSearchTerm] = useState('') + const [deletingEventSlug, setDeletingEventSlug] = useState(null) const fetchEvents = useCallback(async () => { if (!currentCompany) return @@ -51,6 +63,30 @@ export default function CompanyEventsPage() { event.category.toLowerCase().includes(searchTerm.toLowerCase()) ) + const handleDeleteEvent = async (eventSlug: string) => { + try { + setDeletingEventSlug(eventSlug) + + const response = await fetch(`/api/events/${eventSlug}`, { + method: 'DELETE', + }) + + if (!response.ok) { + throw new Error('Failed to delete event') + } + + toast.success('Event deleted successfully') + + // Refresh the events list + await fetchEvents() + } catch (error) { + console.error('Error deleting event:', error) + toast.error('Failed to delete event') + } finally { + setDeletingEventSlug(null) + } + } + const stats = { total: events.length, approved: events.filter(e => e.approval_status === 'approved').length, @@ -276,6 +312,43 @@ export default function CompanyEventsPage() { )} + + + + + + + Delete Event + + Are you sure you want to delete "{event.title}"? This action cannot be undone. + {event.registered && event.registered > 0 && ( + + Warning: This event has {event.registered} registered participant{event.registered > 1 ? 's' : ''}. + + )} + + + + Cancel + handleDeleteEvent(event.slug)} + className="bg-red-600 hover:bg-red-700" + > + Delete + + + + From 2f871d1463e3ab109c5b9c2cdcad92f112b4ed0d Mon Sep 17 00:00:00 2001 From: Akshay Date: Sat, 15 Nov 2025 10:16:01 +0530 Subject: [PATCH 2/2] feat(events): Enhance event edit page layout and add collapsible company info - Reorganize edit event page with improved dark mode support and full-height container - Move delete button to danger zone section at bottom of page with descriptive warning - Simplify back button styling and positioning for better UX - Add collapsible company information section to reduce visual clutter - Implement Collapsible UI component for expandable/collapsible sections - Update EventForm with collapsible company info and improved dark mode styling - Add ChevronDown icon for collapsible state indication - Improve visual hierarchy and spacing throughout the edit event interface - Enhance dark mode compatibility with updated background and border colors --- .../[slug]/events/[eventSlug]/edit/page.tsx | 110 +++++++++--------- components/dashboard/EventForm.tsx | 77 +++++++----- components/ui/collapsible.tsx | 33 ++++++ package-lock.json | 1 + package.json | 1 + 5 files changed, 138 insertions(+), 84 deletions(-) create mode 100644 components/ui/collapsible.tsx diff --git a/app/dashboard/company/[slug]/events/[eventSlug]/edit/page.tsx b/app/dashboard/company/[slug]/events/[eventSlug]/edit/page.tsx index fc40af68..28be0733 100644 --- a/app/dashboard/company/[slug]/events/[eventSlug]/edit/page.tsx +++ b/app/dashboard/company/[slug]/events/[eventSlug]/edit/page.tsx @@ -109,61 +109,67 @@ export default function EditEventPage() { } return ( -
- {/* Header */} -
-
- - - -
-

Edit Event

-

- Update your event details -

-
+
+
+ {/* Back Button */} + + + + + {/* Header */} +
+

Edit Event

+

+ Update your event details +

- {/* Delete Button */} - - - - - - - Are you sure? - - This action cannot be undone. This will permanently delete the event - "{event.title}" and all associated data. - - - - Cancel - - {deleting ? 'Deleting...' : 'Delete Event'} - - - - -
+ {/* Event Form */} + - {/* Event Form */} - + {/* Delete Button at Bottom */} +
+
+

Danger Zone

+

Once you delete an event, there is no going back.

+
+ + + + + + + Are you sure? + + This action cannot be undone. This will permanently delete the event + "{event.title}" and all associated data. + + + + Cancel + + {deleting ? 'Deleting...' : 'Delete Event'} + + + + +
+
) } diff --git a/components/dashboard/EventForm.tsx b/components/dashboard/EventForm.tsx index 3635ce52..7d2f93a5 100644 --- a/components/dashboard/EventForm.tsx +++ b/components/dashboard/EventForm.tsx @@ -8,9 +8,10 @@ import { Label } from '@/components/ui/label' import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select' import { Badge } from '@/components/ui/badge' +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible' import { Event } from '@/types/events' import { Company } from '@/types/company' -import { Save, Send, AlertCircle } from 'lucide-react' +import { Save, Send, AlertCircle, ChevronDown } from 'lucide-react' import { toast } from 'sonner' interface EventFormProps { @@ -22,6 +23,7 @@ interface EventFormProps { export function EventForm({ company, event, mode, onSuccess }: EventFormProps) { const [loading, setLoading] = useState(false) + const [companyInfoOpen, setCompanyInfoOpen] = useState(false) const [formData, setFormData] = useState({ title: event?.title || '', slug: event?.slug || '', @@ -149,37 +151,48 @@ export function EventForm({ company, event, mode, onSuccess }: EventFormProps) { return (
- {/* Company Info */} - - - Company Information - - This event will be associated with {company.name} - - - -
- {company.logo_url && ( - // eslint-disable-next-line @next/next/no-img-element - {company.name} - )} -
-

{company.name}

- - Verified - -
-
-
-
+ {/* Company Info - Collapsible */} + + + + +
+
+ Company Information + + This event will be associated with {company.name} + +
+ +
+
+
+ + +
+ {company.logo_url && ( + // eslint-disable-next-line @next/next/no-img-element + {company.name} + )} +
+

{company.name}

+ + Verified + +
+
+
+
+
+
{/* Event rejection reason */} {event?.approval_status === 'rejected' && event.rejection_reason && ( - + @@ -193,7 +206,7 @@ export function EventForm({ company, event, mode, onSuccess }: EventFormProps) { )} {/* Basic Information */} - + Basic Information @@ -251,7 +264,7 @@ export function EventForm({ company, event, mode, onSuccess }: EventFormProps) { {/* Event Details */} - + Event Details @@ -348,7 +361,7 @@ export function EventForm({ company, event, mode, onSuccess }: EventFormProps) { {/* Registration & Pricing */} - + Registration & Pricing diff --git a/components/ui/collapsible.tsx b/components/ui/collapsible.tsx new file mode 100644 index 00000000..ae9fad04 --- /dev/null +++ b/components/ui/collapsible.tsx @@ -0,0 +1,33 @@ +"use client" + +import * as CollapsiblePrimitive from "@radix-ui/react-collapsible" + +function Collapsible({ + ...props +}: React.ComponentProps) { + return +} + +function CollapsibleTrigger({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +function CollapsibleContent({ + ...props +}: React.ComponentProps) { + return ( + + ) +} + +export { Collapsible, CollapsibleTrigger, CollapsibleContent } diff --git a/package-lock.json b/package-lock.json index d7b5c6aa..b96f898e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.1", + "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.14", "@radix-ui/react-label": "^2.1.6", diff --git a/package.json b/package.json index 409e5a02..e4db4c92 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "@radix-ui/react-alert-dialog": "^1.1.15", "@radix-ui/react-avatar": "^1.1.10", "@radix-ui/react-checkbox": "^1.3.1", + "@radix-ui/react-collapsible": "^1.1.12", "@radix-ui/react-dialog": "^1.1.14", "@radix-ui/react-dropdown-menu": "^2.1.14", "@radix-ui/react-label": "^2.1.6",