Files
imphnen-frontend-service/apps/landing/src/app/(public)/roadmap/_components/request-feature-popup.tsx
T
Rasyid 2c347d1cc5 feat: add ui for roadmap ui (#35)
* fix: correct link for Roadmap navigation item

* feat: add feature request and projects voting components

* fix: correct spelling of 'Certificate' in ProjectsVote component

* feat: add Request Feature popup with responsive dialog and drawer components

* feat: enhance Header component with mobile menu animations and improved navigation styling

* refactor: simplify Header component by removing unused scroll handling and improving mobile menu structure

* fix: replace motion span with static span for header underline

* fix: update FeatureRequestCTA text for clarity and adjust page layout margins

* fix: remove DialogDescription from RequestFeaturePopup and update textarea placeholder for clarity

* fix: remove DrawerDescription from RequestFeaturePopup for cleaner UI

* fix: remove unused icon exports from icons

* fix: replace XIcon with LuX in DialogClose for consistency

* fix: remove unused icon export from index for cleaner module structure
2025-06-18 18:40:19 +07:00

121 lines
3.1 KiB
TypeScript

'use client';
import * as React from 'react';
import { useMediaQuery } from '@/hooks/use-media-query';
import {
Button,
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
DialogTrigger,
Drawer,
DrawerClose,
DrawerContent,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
Input,
Label,
Textarea,
} from '@components';
import { cn } from '@utils';
export function RequestFeaturePopup() {
const [open, setOpen] = React.useState(false);
const isDesktop = useMediaQuery('(min-width: 768px)');
if (isDesktop) {
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogTrigger asChild>
<Button variant="secondary">Request Fitur</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-[600px]">
<DialogHeader>
<DialogTitle className="text-2xl">Request Fitur</DialogTitle>
</DialogHeader>
<ProfileForm />
</DialogContent>
</Dialog>
);
}
return (
<Drawer open={open} onOpenChange={setOpen}>
<DrawerTrigger asChild>
<Button variant="secondary">Request Fitur</Button>
</DrawerTrigger>
<DrawerContent>
<DrawerHeader className="text-left">
<DrawerTitle>Request Fitur</DrawerTitle>
</DrawerHeader>
<ProfileForm className="px-4" />
<DrawerFooter className="pt-2">
<DrawerClose asChild>
<Button variant="bordered">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
);
}
interface ProfileFormProps extends React.ComponentProps<'form'> {
showFooterButton?: boolean;
}
function ProfileForm({
className,
showFooterButton = false,
}: ProfileFormProps) {
const [description, setDescription] = React.useState('');
const maxDescriptionLength = 10000;
return (
<form className={cn('grid items-start gap-8', className)}>
<div className="grid gap-4">
<Label htmlFor="namaFitur" className="font-medium">
Nama Fitur *
</Label>
<Input
id="namaFitur"
placeholder="Masukkan nama fitur yang diinginkan"
className="h-11"
/>
</div>
<div className="grid gap-4">
<div className="flex justify-between items-center">
<Label htmlFor="deskripsiFitur" className="font-medium">
Deskripsi Fitur *
</Label>
<span className="text-sm text-muted-foreground">
{description.length}/{maxDescriptionLength}
</span>
</div>
<Textarea
id="deskripsiFitur"
placeholder="Jelaskan fitur yang Anda inginkan secara detail"
maxLength={maxDescriptionLength}
rows={6}
className="min-h-[150px]"
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
<p className="text-sm text-muted-foreground -mt-2">
Jelaskan manfaat dan cara kerja fitur yang Anda inginkan
</p>
</div>
{!showFooterButton && (
<Button type="submit" size="lg" className="mt-2">
Kirim Permintaan
</Button>
)}
</form>
);
}