From 522f28314000deb8bd5e03340d5c2faa1f06f20d Mon Sep 17 00:00:00 2001 From: arraysid Date: Sun, 1 Jun 2025 04:53:46 +0700 Subject: [PATCH] feat: add feature request and projects voting components --- .../_components/feature-request-cta.tsx | 51 ++++ .../roadmap/_components/projects-vote.tsx | 233 ++++++++++++++++++ .../landing/src/app/(public)/roadmap/page.tsx | 11 + .../src/app/(public)/roadmaps/page.tsx | 3 - 4 files changed, 295 insertions(+), 3 deletions(-) create mode 100644 apps/landing/src/app/(public)/roadmap/_components/feature-request-cta.tsx create mode 100644 apps/landing/src/app/(public)/roadmap/_components/projects-vote.tsx create mode 100644 apps/landing/src/app/(public)/roadmap/page.tsx delete mode 100644 apps/landing/src/app/(public)/roadmaps/page.tsx diff --git a/apps/landing/src/app/(public)/roadmap/_components/feature-request-cta.tsx b/apps/landing/src/app/(public)/roadmap/_components/feature-request-cta.tsx new file mode 100644 index 0000000..eb19a56 --- /dev/null +++ b/apps/landing/src/app/(public)/roadmap/_components/feature-request-cta.tsx @@ -0,0 +1,51 @@ +'use client'; + +import { motion } from 'framer-motion'; +import { FiPlus } from 'react-icons/fi'; + +export function FeatureRequestCTA() { + const handleSubmitFeature = () => { + alert('Feature submission form would appear here!'); + }; + + return ( + +
+ + Punya Ide Bagus untuk IMPHNEN? + + + Bagikan ide fitur atau layanan yang ingin Anda lihat di komunitas. Ide + terbaik dengan vote tertinggi akan kami prioritaskan! + + + + Ajukan Fitur + +
+
+ ); +} diff --git a/apps/landing/src/app/(public)/roadmap/_components/projects-vote.tsx b/apps/landing/src/app/(public)/roadmap/_components/projects-vote.tsx new file mode 100644 index 0000000..b68daba --- /dev/null +++ b/apps/landing/src/app/(public)/roadmap/_components/projects-vote.tsx @@ -0,0 +1,233 @@ +'use client'; + +import { Button, Card, CardContent, CardHeader, CardTitle } from '@components'; +import { AnimatePresence, motion } from 'framer-motion'; +import { useState } from 'react'; +import { BiUpvote } from 'react-icons/bi'; +import { FiCheckCircle } from 'react-icons/fi'; +import { MdOutlineOpenInNew } from 'react-icons/md'; + +export default function ProjectsVote() { + const [upcomingItems, setUpcomingItems] = useState([ + { + title: 'IMPHNEN Meme Generator', + description: 'Bikin meme kocak kapanpun dengan mudah', + votes: 42, + voted: false, + }, + ]); + + const inProgressItems = [ + { + title: 'IMPHNEN Twibbon', + description: 'Buat Twibbon kece untuk profile media sosialmu', + }, + { + title: 'IMPHNEN Cerficate', + description: 'Cetak sertifikat keren secara instan untuk anggota IMPHNEN', + }, + ]; + + const completedItems = [ + { + title: 'IMPHNEN List Event', + description: + 'Koleksi daftar event dan kolaborasi seru yang bisa kamu ikuti', + }, + { + title: 'IMPHNEN Testimoni', + description: 'Berikan testimonial gokil buat komunitas IMPHNEN', + }, + { + title: 'IMPHNEN Roadmap by Vote', + description: 'Usulkan ide fitur seru dan ajak anggota lain buat voting', + }, + ]; + + const handleVote = (index: number) => { + const newItems = [...upcomingItems]; + newItems[index] = { + ...newItems[index], + votes: newItems[index].voted + ? newItems[index].votes - 1 + : newItems[index].votes + 1, + voted: !newItems[index].voted, + }; + setUpcomingItems(newItems); + }; + + const containerVariants = { + hidden: { opacity: 0 }, + visible: { + opacity: 1, + transition: { + staggerChildren: 0.05, + }, + }, + }; + + const itemVariants = { + hidden: { opacity: 0, y: 10 }, + visible: { opacity: 1, y: 0, transition: { duration: 0.2 } }, + }; + + return ( +
+ {/* Vote Now Column */} +
+
+
+ 🔥 +
+

Vote Now

+
+ + + + {upcomingItems.map((item, index) => ( + + + + + {item.title} + + + +

+ {item.description} +

+
+ handleVote(index)} + className={`flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-medium transition-all ${ + item.voted + ? 'bg-primary-500 text-white hover:bg-primary-600' + : 'bg-gray-100 text-gray-700 hover:bg-gray-200' + }`} + > + + + + {item.voted ? 'Voted' : 'Vote'} + +
+ + + {item.votes} + +
+
+
+
+
+ ))} +
+
+
+ + {/* In Progress Column */} +
+
+
+ 🧑‍🔧 +
+

In Progress

+
+ + + + {inProgressItems.map((item, index) => ( + + + + + {item.title} + + + +

{item.description}

+
+
+
+
+

+ {index === 0 ? 'Development started' : 'In development'} +

+
+
+
+
+ ))} +
+
+
+ + {/* Completed Column */} +
+
+
+ 🤓 +
+

Completed

+
+ + + + {completedItems.map((item, index) => ( + + + + + {item.title} + + + +

+ {item.description} +

+
+
+ + Implemented +
+ +
+
+
+
+ ))} +
+
+
+
+ ); +} diff --git a/apps/landing/src/app/(public)/roadmap/page.tsx b/apps/landing/src/app/(public)/roadmap/page.tsx new file mode 100644 index 0000000..b7f979d --- /dev/null +++ b/apps/landing/src/app/(public)/roadmap/page.tsx @@ -0,0 +1,11 @@ +import { FeatureRequestCTA } from './_components/feature-request-cta'; +import ProjectsVote from './_components/projects-vote'; + +export default function Page() { + return ( +
+ + +
+ ); +} diff --git a/apps/landing/src/app/(public)/roadmaps/page.tsx b/apps/landing/src/app/(public)/roadmaps/page.tsx deleted file mode 100644 index 7d1e0b7..0000000 --- a/apps/landing/src/app/(public)/roadmaps/page.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export default function Page() { - return <>; -}