From 3a7a6dea40828478154b148f5aa8b49a4ab2653b Mon Sep 17 00:00:00 2001 From: Ndevu12 Date: Tue, 27 Jan 2026 20:28:26 +0200 Subject: [PATCH] feat: add UI components for table, tabs, textarea, toast, and toggle elements - Implemented Table, TableHeader, TableBody, TableFooter, TableRow, TableHead, TableCell, and TableCaption components for structured data display. - Created Tabs, TabsList, TabsTrigger, and TabsContent components for tabbed navigation. - Added Textarea component for multi-line text input. - Developed Toast, ToastProvider, ToastViewport, ToastAction, ToastClose, ToastTitle, and ToastDescription components for notifications. - Introduced Toggle and ToggleGroup components for toggle button functionality. - Added utility hooks for mobile detection and toast management. - Created constants for community content, workshops, events, open source projects, startup resources, and team members. - Implemented utility functions for class name merging. --- app/auth/login/page.tsx | 40 +- app/auth/signup/page.tsx | 86 +++- app/community/code-of-conduct/page.tsx | 29 +- app/community/contribute/page.tsx | 56 ++- app/community/join/page.tsx | 38 +- app/community/page.tsx | 33 +- app/community/sponsorship/page.tsx | 87 ++-- app/contact/page.tsx | 69 ++- app/events/[id]/page.tsx | 134 ++++-- app/events/page.tsx | 40 +- app/get-started/page.tsx | 60 ++- app/globals.css | 127 ++++-- app/layout.tsx | 12 +- app/page.tsx | 22 +- app/privacy/page.tsx | 89 ++-- app/register/events/[id]/page.tsx | 70 +-- app/register/workshops/page.tsx | 77 +++- app/resources/funding-directory/page.tsx | 94 ++-- app/resources/mentorship/page.tsx | 75 ++-- app/resources/page.tsx | 55 ++- app/resources/problem-solutions/page.tsx | 59 ++- app/resources/startup-toolkit/page.tsx | 108 +++-- app/sitemap/page.tsx | 27 +- app/terms/page.tsx | 102 +++-- app/workshops/[id]/page.tsx | 154 +++++-- app/workshops/page.tsx | 43 +- components/hero.tsx | 88 ---- components/ui/button.tsx | 60 --- components/ui/spinner.tsx | 16 - .../components}/community-section.tsx | 36 +- .../components}/events-section.tsx | 28 +- {components => src/components}/footer.tsx | 58 ++- {components => src/components}/header.tsx | 40 +- src/components/hero.tsx | 117 +++++ .../components}/open-source-section.tsx | 59 ++- .../components}/resources-section.tsx | 48 +- .../components}/team-section.tsx | 28 +- .../components}/theme-provider.tsx | 0 .../components}/ui/accordion.tsx | 26 +- .../components}/ui/alert-dialog.tsx | 52 +-- {components => src/components}/ui/alert.tsx | 34 +- .../components}/ui/aspect-ratio.tsx | 0 {components => src/components}/ui/avatar.tsx | 22 +- {components => src/components}/ui/badge.tsx | 30 +- .../components}/ui/breadcrumb.tsx | 54 +-- .../components}/ui/button-group.tsx | 36 +- src/components/ui/button.tsx | 62 +++ .../components}/ui/calendar.tsx | 116 ++--- {components => src/components}/ui/card.tsx | 48 +- .../components}/ui/carousel.tsx | 174 +++---- {components => src/components}/ui/chart.tsx | 192 ++++---- .../components}/ui/checkbox.tsx | 16 +- .../components}/ui/collapsible.tsx | 0 {components => src/components}/ui/command.tsx | 60 +-- .../components}/ui/context-menu.tsx | 64 +-- {components => src/components}/ui/dialog.tsx | 50 +-- {components => src/components}/ui/drawer.tsx | 54 +-- .../components}/ui/dropdown-menu.tsx | 64 +-- {components => src/components}/ui/empty.tsx | 50 +-- {components => src/components}/ui/field.tsx | 124 ++--- {components => src/components}/ui/form.tsx | 91 ++-- .../components}/ui/hover-card.tsx | 20 +- .../components}/ui/input-group.tsx | 106 ++--- .../components}/ui/input-otp.tsx | 42 +- {components => src/components}/ui/input.tsx | 16 +- {components => src/components}/ui/item.tsx | 104 ++--- {components => src/components}/ui/kbd.tsx | 18 +- {components => src/components}/ui/label.tsx | 14 +- {components => src/components}/ui/menubar.tsx | 74 +-- .../components}/ui/navigation-menu.tsx | 54 +-- .../components}/ui/pagination.tsx | 54 +-- {components => src/components}/ui/popover.tsx | 22 +- .../components}/ui/progress.tsx | 14 +- .../components}/ui/radio-group.tsx | 20 +- .../components}/ui/resizable.tsx | 24 +- .../components}/ui/scroll-area.tsx | 28 +- {components => src/components}/ui/select.tsx | 58 +-- .../components}/ui/separator.tsx | 16 +- {components => src/components}/ui/sheet.tsx | 68 +-- {components => src/components}/ui/sidebar.tsx | 424 +++++++++--------- .../components}/ui/skeleton.tsx | 10 +- {components => src/components}/ui/slider.tsx | 20 +- {components => src/components}/ui/sonner.tsx | 0 src/components/ui/spinner.tsx | 16 + {components => src/components}/ui/switch.tsx | 16 +- {components => src/components}/ui/table.tsx | 56 +-- {components => src/components}/ui/tabs.tsx | 24 +- .../components}/ui/textarea.tsx | 12 +- {components => src/components}/ui/toast.tsx | 66 +-- {components => src/components}/ui/toaster.tsx | 12 +- .../components}/ui/toggle-group.tsx | 30 +- {components => src/components}/ui/toggle.tsx | 30 +- {components => src/components}/ui/tooltip.tsx | 20 +- .../components}/ui/use-mobile.tsx | 0 {hooks => src/components/ui}/use-toast.ts | 2 +- .../components}/workshops-section.tsx | 43 +- {hooks => src/hooks}/use-mobile.ts | 0 {components/ui => src/hooks}/use-toast.ts | 2 +- {lib => src/lib}/constants.ts | 9 + {lib => src/lib}/utils.ts | 0 100 files changed, 3047 insertions(+), 2280 deletions(-) delete mode 100644 components/hero.tsx delete mode 100644 components/ui/button.tsx delete mode 100644 components/ui/spinner.tsx rename {components => src/components}/community-section.tsx (60%) rename {components => src/components}/events-section.tsx (80%) rename {components => src/components}/footer.tsx (71%) rename {components => src/components}/header.tsx (73%) create mode 100644 src/components/hero.tsx rename {components => src/components}/open-source-section.tsx (60%) rename {components => src/components}/resources-section.tsx (60%) rename {components => src/components}/team-section.tsx (76%) rename {components => src/components}/theme-provider.tsx (100%) rename {components => src/components}/ui/accordion.tsx (77%) rename {components => src/components}/ui/alert-dialog.tsx (76%) rename {components => src/components}/ui/alert.tsx (52%) rename {components => src/components}/ui/aspect-ratio.tsx (100%) rename {components => src/components}/ui/avatar.tsx (63%) rename {components => src/components}/ui/badge.tsx (51%) rename {components => src/components}/ui/breadcrumb.tsx (62%) rename {components => src/components}/ui/button-group.tsx (67%) create mode 100644 src/components/ui/button.tsx rename {components => src/components}/ui/calendar.tsx (59%) rename {components => src/components}/ui/card.tsx (62%) rename {components => src/components}/ui/carousel.tsx (54%) rename {components => src/components}/ui/chart.tsx (65%) rename {components => src/components}/ui/checkbox.tsx (73%) rename {components => src/components}/ui/collapsible.tsx (100%) rename {components => src/components}/ui/command.tsx (78%) rename {components => src/components}/ui/context-menu.tsx (88%) rename {components => src/components}/ui/dialog.tsx (78%) rename {components => src/components}/ui/drawer.tsx (74%) rename {components => src/components}/ui/dropdown-menu.tsx (89%) rename {components => src/components}/ui/empty.tsx (62%) rename {components => src/components}/ui/field.tsx (55%) rename {components => src/components}/ui/form.tsx (66%) rename {components => src/components}/ui/hover-card.tsx (76%) rename {components => src/components}/ui/input-group.tsx (54%) rename {components => src/components}/ui/input-otp.tsx (69%) rename {components => src/components}/ui/input.tsx (60%) rename {components => src/components}/ui/item.tsx (61%) rename {components => src/components}/ui/kbd.tsx (50%) rename {components => src/components}/ui/label.tsx (58%) rename {components => src/components}/ui/menubar.tsx (86%) rename {components => src/components}/ui/navigation-menu.tsx (82%) rename {components => src/components}/ui/pagination.tsx (66%) rename {components => src/components}/ui/popover.tsx (81%) rename {components => src/components}/ui/progress.tsx (67%) rename {components => src/components}/ui/radio-group.tsx (71%) rename {components => src/components}/ui/resizable.tsx (77%) rename {components => src/components}/ui/scroll-area.tsx (68%) rename {components => src/components}/ui/select.tsx (82%) rename {components => src/components}/ui/separator.tsx (56%) rename {components => src/components}/ui/sheet.tsx (67%) rename {components => src/components}/ui/sidebar.tsx (59%) rename {components => src/components}/ui/skeleton.tsx (51%) rename {components => src/components}/ui/slider.tsx (76%) rename {components => src/components}/ui/sonner.tsx (100%) create mode 100644 src/components/ui/spinner.tsx rename {components => src/components}/ui/switch.tsx (68%) rename {components => src/components}/ui/table.tsx (63%) rename {components => src/components}/ui/tabs.tsx (78%) rename {components => src/components}/ui/textarea.tsx (75%) rename {components => src/components}/ui/toast.tsx (74%) rename {components => src/components}/ui/toaster.tsx (81%) rename {components => src/components}/ui/toggle-group.tsx (69%) rename {components => src/components}/ui/toggle.tsx (65%) rename {components => src/components}/ui/tooltip.tsx (84%) rename {components => src/components}/ui/use-mobile.tsx (100%) rename {hooks => src/components/ui}/use-toast.ts (97%) rename {components => src/components}/workshops-section.tsx (68%) rename {hooks => src/hooks}/use-mobile.ts (100%) rename {components/ui => src/hooks}/use-toast.ts (97%) rename {lib => src/lib}/constants.ts (96%) rename {lib => src/lib}/utils.ts (100%) diff --git a/app/auth/login/page.tsx b/app/auth/login/page.tsx index 4b3efe2..33a4479 100644 --- a/app/auth/login/page.tsx +++ b/app/auth/login/page.tsx @@ -1,30 +1,34 @@ -import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Mail, Lock, ArrowRight } from "lucide-react" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import { Button } from "@/src/components/ui/button"; +import { Mail, Lock, ArrowRight } from "lucide-react"; +import Link from "next/link"; export const metadata = { title: "Sign In | Django Rwanda Community", description: "Sign in to your Django Rwanda Community account", -} +}; export default function LoginPage() { return ( -
+
-
+
D

Welcome Back

-

Sign in to your Django Rwanda Community account

+

+ Sign in to your Django Rwanda Community account +

{/* Email */}
- +
- +
@@ -60,7 +69,7 @@ export default function LoginPage() {
{/* Submit */} - @@ -87,11 +96,14 @@ export default function LoginPage() { {/* Sign up link */}

Don't have an account?{" "} - + Sign up here

- ) + ); } diff --git a/app/auth/signup/page.tsx b/app/auth/signup/page.tsx index c3f4173..c9987ce 100644 --- a/app/auth/signup/page.tsx +++ b/app/auth/signup/page.tsx @@ -1,30 +1,36 @@ -import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { User, Mail, Lock, Zap } from "lucide-react" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import { Button } from "@/src/components/ui/button"; +import { User, Mail, Lock, Zap } from "lucide-react"; +import Link from "next/link"; export const metadata = { title: "Sign Up | Django Rwanda Community", description: "Create your Django Rwanda Community account", -} +}; export default function SignupPage() { return ( -
+
-
+
D
-

Join Django Rwanda

-

Create your account and start your journey

+

+ Join Django Rwanda +

+

+ Create your account and start your journey +

{/* Full Name */}
- +
- +
- +
- +
- +
@@ -99,21 +125,30 @@ export default function SignupPage() { {/* Terms agreement */} {/* Submit */} - @@ -140,11 +175,14 @@ export default function SignupPage() { {/* Sign in link */}

Already have an account?{" "} - + Sign in here

- ) + ); } diff --git a/app/community/code-of-conduct/page.tsx b/app/community/code-of-conduct/page.tsx index 3fd1fe9..84d9d1f 100644 --- a/app/community/code-of-conduct/page.tsx +++ b/app/community/code-of-conduct/page.tsx @@ -1,10 +1,10 @@ -import { Card } from "@/components/ui/card" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import Link from "next/link"; export const metadata = { title: "Code of Conduct | Django Rwanda Community", description: "Our community values and principles", -} +}; const sections = [ { @@ -32,17 +32,22 @@ const sections = [ content: "Violations of this code of conduct will be taken seriously and may result in temporary or permanent removal from the community. Reports should be sent to conduct@djangorwanda.dev.", }, -] +]; export default function CodeOfConductPage() { return ( -
+
- + ← Back to Community -

Code of Conduct

+

+ Code of Conduct +

Our values and principles for a respectful and inclusive community.

@@ -54,8 +59,12 @@ export default function CodeOfConductPage() {
{sections.map((section, idx) => ( -

{section.title}

- {section.content &&

{section.content}

} +

+ {section.title} +

+ {section.content && ( +

{section.content}

+ )} {section.items && (
    {section.items.map((item, i) => ( @@ -72,5 +81,5 @@ export default function CodeOfConductPage() {
- ) + ); } diff --git a/app/community/contribute/page.tsx b/app/community/contribute/page.tsx index aeffdb0..5625829 100644 --- a/app/community/contribute/page.tsx +++ b/app/community/contribute/page.tsx @@ -1,47 +1,57 @@ -import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { BookOpen, Code, Users, Megaphone } from "lucide-react" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import { Button } from "@/src/components/ui/button"; +import { BookOpen, Code, Users, Megaphone } from "lucide-react"; +import Link from "next/link"; export const metadata = { title: "Contribute | Django Rwanda Community", description: "Help shape the future of Django Rwanda", -} +}; const contributionAreas = [ { icon: Code, title: "Code & Development", - description: "Contribute to our open-source projects and help build solutions for African communities.", + description: + "Contribute to our open-source projects and help build solutions for African communities.", }, { icon: BookOpen, title: "Content & Documentation", - description: "Help us create tutorials, guides, and documentation for the community.", + description: + "Help us create tutorials, guides, and documentation for the community.", }, { icon: Users, title: "Community Support", - description: "Become a mentor, organize events, or moderate our community channels.", + description: + "Become a mentor, organize events, or moderate our community channels.", }, { icon: Megaphone, title: "Marketing & Outreach", - description: "Help spread the word about Django Rwanda and grow our community.", + description: + "Help spread the word about Django Rwanda and grow our community.", }, -] +]; export default function ContributePage() { return ( -
+
- + ← Back to Community -

How to Contribute

+

+ How to Contribute +

- Every contribution matters. There are many ways to help build and improve Django Rwanda. + Every contribution matters. There are many ways to help build and + improve Django Rwanda.

@@ -50,22 +60,26 @@ export default function ContributePage() {
{contributionAreas.map((area, idx) => { - const Icon = area.icon + const Icon = area.icon; return (
-

{area.title}

+

+ {area.title} +

{area.description}

- ) + ); })}
{/* Getting Started */} -

Getting Started

+

+ Getting Started +

  1. 1. @@ -85,13 +99,11 @@ export default function ContributePage() {
- +
- ) + ); } diff --git a/app/community/join/page.tsx b/app/community/join/page.tsx index 530757a..90e643f 100644 --- a/app/community/join/page.tsx +++ b/app/community/join/page.tsx @@ -1,12 +1,12 @@ -import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Check } from "lucide-react" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import { Button } from "@/src/components/ui/button"; +import { Check } from "lucide-react"; +import Link from "next/link"; export const metadata = { title: "Join Community | Django Rwanda", description: "Become a member of Django Rwanda Community", -} +}; const benefits = [ "Access to exclusive workshops and training materials", @@ -15,19 +15,25 @@ const benefits = [ "Get mentorship from experienced developers", "Access to job board and opportunities", "Connect with 500+ community members", -] +]; export default function JoinPage() { return ( -
+
- + ← Back to Community -

Join Django Rwanda

+

+ Join Django Rwanda +

- Be part of a vibrant community of African developers dedicated to innovation and learning. + Be part of a vibrant community of African developers dedicated to + innovation and learning.

@@ -37,7 +43,9 @@ export default function JoinPage() {
{/* Benefits */}
-

Membership Benefits

+

+ Membership Benefits +

    {benefits.map((benefit, idx) => ( @@ -52,7 +60,9 @@ export default function JoinPage() { {/* Signup Form */}
    -

    Get Started

    +

    + Get Started +

    - @@ -86,5 +96,5 @@ export default function JoinPage() {
- ) + ); } diff --git a/app/community/page.tsx b/app/community/page.tsx index 63886aa..388f2a5 100644 --- a/app/community/page.tsx +++ b/app/community/page.tsx @@ -1,11 +1,11 @@ -import { Card } from "@/components/ui/card" -import { Users, BookOpen, Share2, Gift, ArrowRight } from "lucide-react" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import { Users, BookOpen, Share2, Gift, ArrowRight } from "lucide-react"; +import Link from "next/link"; export const metadata = { title: "Community | Django Rwanda", description: "Join the Django Rwanda Community and grow with us", -} +}; const communityLinks = [ { @@ -40,18 +40,21 @@ const communityLinks = [ icon: Gift, color: "from-primary/10 to-secondary/10", }, -] +]; export default function CommunityPage() { return ( -
+
{/* Header */}
-

Community

+

+ Community +

- Join, learn, contribute, and grow with Django Rwanda. Choose your journey below. + Join, learn, contribute, and grow with Django Rwanda. Choose your + journey below.

@@ -62,7 +65,7 @@ export default function CommunityPage() {
{communityLinks.map((item) => { - const Icon = item.icon + const Icon = item.icon; return (
-

{item.title}

-

{item.description}

+

+ {item.title} +

+

+ {item.description} +

Explore
- ) + ); })}
- ) + ); } diff --git a/app/community/sponsorship/page.tsx b/app/community/sponsorship/page.tsx index 84aff23..24db96b 100644 --- a/app/community/sponsorship/page.tsx +++ b/app/community/sponsorship/page.tsx @@ -1,25 +1,35 @@ -import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Gift, Star, Crown, Zap } from "lucide-react" -import Link from "next/link" +import { Card } from "@/src/components/ui/card"; +import { Button } from "@/src/components/ui/button"; +import { Gift, Star, Crown, Zap } from "lucide-react"; +import Link from "next/link"; export const metadata = { title: "Sponsorship | Django Rwanda Community", description: "Partner with us to support the community", -} +}; const sponsorshipTiers = [ { name: "Bronze", price: "$500", icon: Gift, - benefits: ["Logo on website", "Social media mention", "Event booth access", "Community newsletter"], + benefits: [ + "Logo on website", + "Social media mention", + "Event booth access", + "Community newsletter", + ], }, { name: "Silver", price: "$2,500", icon: Star, - benefits: ["All Bronze benefits", "Speaking opportunity", "Job board listing", "Quarterly newsletter feature"], + benefits: [ + "All Bronze benefits", + "Speaking opportunity", + "Job board listing", + "Quarterly newsletter feature", + ], }, { name: "Gold", @@ -36,21 +46,32 @@ const sponsorshipTiers = [ name: "Platinum", price: "Custom", icon: Zap, - benefits: ["All Gold benefits", "Custom partnership plan", "Executive visibility", "Strategic collaboration"], + benefits: [ + "All Gold benefits", + "Custom partnership plan", + "Executive visibility", + "Strategic collaboration", + ], }, -] +]; export default function SponsorshipPage() { return ( -
+
- + ← Back to Community -

Become a Sponsor

+

+ Become a Sponsor +

- Partner with Django Rwanda to support African developers and make a lasting impact on our community. + Partner with Django Rwanda to support African developers and make a + lasting impact on our community.

@@ -59,10 +80,12 @@ export default function SponsorshipPage() {
{/* Sponsorship Tiers */}
-

Sponsorship Packages

+

+ Sponsorship Packages +

{sponsorshipTiers.map((tier, idx) => { - const Icon = tier.icon + const Icon = tier.icon; return (
-

{tier.name}

-

{tier.price}

+

+ {tier.name} +

+

+ {tier.price} +

    {tier.benefits.map((benefit, i) => ( -
  • +
  • {benefit}
  • ))}
- - ) + ); })}
{/* Why Sponsor */} -

Why Sponsor Django Rwanda?

+

+ Why Sponsor Django Rwanda? +

  • - Reach 500+ active developers and tech professionals across Africa + + Reach 500+ active developers and tech professionals across + Africa +
  • - Build brand recognition in the growing African tech ecosystem + + Build brand recognition in the growing African tech ecosystem +
  • @@ -117,7 +154,7 @@ export default function SponsorshipPage() {

    Ready to partner with us?

    - @@ -125,5 +162,5 @@ export default function SponsorshipPage() {
- ) + ); } diff --git a/app/contact/page.tsx b/app/contact/page.tsx index 776f068..9ae5df8 100644 --- a/app/contact/page.tsx +++ b/app/contact/page.tsx @@ -1,18 +1,20 @@ -import { Card } from "@/components/ui/card" -import { Button } from "@/components/ui/button" -import { Mail, Phone, MapPin, Send } from "lucide-react" +import { Card } from "@/src/components/ui/card"; +import { Button } from "@/src/components/ui/button"; +import { Mail, Phone, MapPin, Send } from "lucide-react"; export const metadata = { title: "Contact Us | Django Rwanda Community", description: "Get in touch with Django Rwanda Community", -} +}; export default function ContactPage() { return ( -
+
-

Contact Us

+

+ Contact Us +

Have questions or suggestions? We'd love to hear from you.

@@ -25,7 +27,9 @@ export default function ContactPage() { {/* Contact Info */}
-

Get in Touch

+

+ Get in Touch +

@@ -33,19 +37,25 @@ export default function ContactPage() {
-
- +
+
@@ -57,26 +67,35 @@ export default function ContactPage() {

Location

-

Kigali Innovation Hub, Kigali, Rwanda

+

+ Kigali Innovation Hub, Kigali, Rwanda +

- -

Response Time

+ +

+ Response Time +

- We typically respond to inquiries within 24 hours during business days. + We typically respond to inquiries within 24 hours during + business days.

{/* Contact Form */} -

Send us a Message

+

+ Send us a Message +

- +
- +
- +
- +