init push

This commit is contained in:
Rama Priyanto 2026-03-18 15:02:37 +07:00
parent d648545be5
commit 76f9af6b8d
36 changed files with 1354 additions and 124 deletions

32
app/auth/layout.tsx Normal file
View File

@ -0,0 +1,32 @@
import Footer from "@/components/layout/footer"
import Image from "next/image"
export default function AuthLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="min-h-screen w-full">
<div className="grid min-h-screen grid-cols-1 md:grid-cols-2">
<div className="relative hidden md:block">
<Image
src="/silancar.jpg"
alt="auth-image"
fill
priority
className="object-cover object-center"
/>
</div>
<div className="flex flex-col justify-between bg-[url('/main-background.png')] bg-cover bg-center px-6 py-8 sm:px-10 md:px-12 lg:px-16">
<div className="flex flex-1 items-center justify-center">
<div className="w-full max-w-md">{children}</div>
</div>
<Footer />
</div>
</div>
</div>
)
}

View File

@ -0,0 +1,7 @@
export default function SignInLayout({
children,
}: {
children: React.ReactNode
}) {
return <>{children}</>
}

121
app/auth/sign-in/page.tsx Normal file
View File

@ -0,0 +1,121 @@
"use client"
import { useForm, Controller } from "react-hook-form"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import Link from "next/link"
import { useRouter } from "next/navigation"
type FormValues = {
nrp: string
password: string
}
export default function SignInPage() {
const router = useRouter()
const {
control,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<FormValues>({
defaultValues: {
nrp: "",
password: "",
},
})
const onSubmit = async (data: FormValues) => {
console.log("DATA LOGIN:", data)
await new Promise((res) => setTimeout(res, 1000))
router.push("/dashboard")
}
return (
<form
onSubmit={handleSubmit(onSubmit)}
className="mx-auto w-full max-w-md text-white"
>
<h1 className="font-heading mb-8 text-2xl font-bold sm:text-3xl">
Masuk
</h1>
<div className="space-y-8">
<div>
<label className="text-sm">
NRP<span className="text-red-500">*</span>
</label>
<Controller
name="nrp"
control={control}
rules={{ required: "NRP wajib diisi" }}
render={({ field }) => (
<Input
{...field}
placeholder="Masukkan nrp anda"
className="mt-2 h-10 border-none bg-white! text-black focus-visible:ring-0"
/>
)}
/>
{errors.nrp && (
<p className="mt-1 text-xs text-red-400">{errors.nrp.message}</p>
)}
</div>
<div>
<label className="text-sm">
Kata Sandi<span className="text-red-500">*</span>
</label>
<Controller
name="password"
control={control}
rules={{
required: "Password wajib diisi",
minLength: {
value: 6,
message: "Minimal 6 karakter",
},
}}
render={({ field }) => (
<Input
{...field}
type="password"
placeholder="Masukkan kata sandi anda"
className="mt-2 h-10 border-none bg-white! text-black focus-visible:ring-0"
/>
)}
/>
{errors.password && (
<p className="mt-1 text-xs text-red-400">
{errors.password.message}
</p>
)}
</div>
<Button
type="submit"
disabled={isSubmitting}
className="h-12 w-full bg-[#001353] text-white hover:bg-blue-800"
>
{isSubmitting ? "Loading..." : "Masuk"}
</Button>
<p className="text-center text-sm text-white/80">
Belum punya akun?{" "}
<Link
href={"/auth/sign-up"}
className="cursor-pointer font-semibold underline"
>
Daftar Sekarang
</Link>
</p>
</div>
</form>
)
}

View File

@ -0,0 +1,7 @@
export default function SignUpLayout({
children,
}: {
children: React.ReactNode
}) {
return <>{children}</>
}

115
app/auth/sign-up/page.tsx Normal file
View File

@ -0,0 +1,115 @@
"use client"
import { useForm, Controller } from "react-hook-form"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import Link from "next/link"
type FormValues = {
nrp: string
email: string
}
export default function SignUpPage() {
const {
control,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<FormValues>({
defaultValues: {
nrp: "",
email: "",
},
})
const onSubmit = async (data: FormValues) => {
console.log("DATA LOGIN:", data)
await new Promise((res) => setTimeout(res, 1000))
}
return (
<form
onSubmit={handleSubmit(onSubmit)}
className="mx-auto w-full max-w-md text-white"
>
<h1 className="font-heading mb-8 text-2xl font-bold sm:text-3xl">
Daftar
</h1>
<div className="space-y-8">
<div>
<label className="text-sm">
Email<span className="text-red-500">*</span>
</label>
<Controller
name="email"
control={control}
rules={{ required: "Email wajib diisi" }}
render={({ field }) => (
<Input
{...field}
type="email"
placeholder="Masukkan email anda"
className="mt-2 h-10 border-none bg-white! text-black focus-visible:ring-0"
/>
)}
/>
{errors.email && (
<p className="mt-1 text-xs text-red-400">{errors.email.message}</p>
)}
</div>
<div>
<label className="text-sm">
NRP<span className="text-red-500">*</span>
</label>
<Controller
name="nrp"
control={control}
rules={{
required: "NRP wajib diisi",
minLength: {
value: 8,
message: "Minimal 8 karakter",
},
}}
render={({ field }) => (
<Input
{...field}
type="number"
placeholder="Masukkan NRP anda"
className="mt-2 h-10 border-none bg-white! text-black focus-visible:ring-0"
/>
)}
/>
{errors.nrp && (
<p className="mt-1 text-xs text-red-400">{errors.nrp.message}</p>
)}
</div>
<Button
type="submit"
disabled={isSubmitting}
className="h-12 w-full bg-[#001353] text-white hover:bg-blue-800"
>
{isSubmitting ? "Loading..." : "Daftar"}
</Button>
<p className="text-center text-sm text-white/80">
Sudah memiliki akun?{" "}
<Link
href={"/auth/sign-in"}
className="cursor-pointer font-semibold underline"
>
Masuk Sekarang
</Link>
</p>
</div>
</form>
)
}

View File

@ -0,0 +1,7 @@
export default function EtleLayout({
children,
}: {
children: React.ReactNode
}) {
return <>{children}</>
}

115
app/dashboard/etle/page.tsx Normal file
View File

@ -0,0 +1,115 @@
"use client"
import { ArrowLeftIcon, ChevronLeft } from "lucide-react"
import Link from "next/link"
import { useRouter } from "next/navigation"
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer"
import {
Sheet,
SheetClose,
SheetContent,
SheetDescription,
SheetFooter,
SheetHeader,
SheetTitle,
SheetTrigger,
} from "@/components/ui/sheet"
import { Button } from "@/components/ui/button"
import Image from "next/image"
const dummy = [
{ url: "/sample-1.jpg" },
{ url: "/sample-2.jpg" },
{ url: "/sample-3.jpg" },
{ url: "/sample-4.jpg" },
{ url: "/sample-1.jpg" },
{ url: "/sample-2.jpg" },
{ url: "/sample-3.jpg" },
{ url: "/sample-4.jpg" },
{ url: "/sample-1.jpg" },
]
export default function Etle() {
const router = useRouter()
return (
<div className="flex flex-col">
<div className="flex h-[8vh] flex-row items-center gap-10 bg-[#0057B3] px-8 py-5">
<Link href="/dashboard">
<ArrowLeftIcon />
</Link>
<p className="text-2xl font-semibold">ETLE Toll</p>
</div>
<div className="flex h-[92vh] flex-col items-start gap-5 bg-gray-200 p-8 text-black">
<p className="text-2xl font-semibold">TRAFFIC VIOLATIONS</p>
<Image
src={"/sample-1.jpg"}
width={1280}
height={960}
alt={"main-image"}
className="w-screen rounded-lg md:w-full xl:w-180"
/>
<Button
variant="ghost"
className="h-12 bg-white px-10 text-xl shadow-sm"
>
D1234PZ
</Button>
<p className="text-2xl font-semibold">VIOLATIONS</p>
<p>
Plat yang terdeteksi berangka D1234PZ di 2026-01-08 jam 17:55:26
berada di jalur 2
</p>
</div>
<Drawer direction="right">
<DrawerTrigger asChild>
<Button className="fixed top-1/2 right-0 h-20 w-6 -translate-y-1/2 cursor-pointer rounded-none rounded-l-md bg-white">
<ChevronLeft />
</Button>
</DrawerTrigger>
<DrawerContent>
<div className="no-scrollbar space-y-3 overflow-y-auto bg-[#CBCBCBCC] px-4 py-4 text-black">
<div className="rounded-lg bg-white p-3 text-lg">
Total Image: 10
</div>{" "}
{dummy.map((item, index) => (
<div key={index} className="rounded-lg bg-white p-3 text-lg">
<Image
src={item.url}
width={1280}
height={960}
alt={"image" + index}
className="rounded-lg"
/>
</div>
))}
</div>
</DrawerContent>
</Drawer>
{/* <Sheet>
<SheetTrigger asChild>
<Button className="fixed top-1/2 right-0 h-20 w-6 -translate-y-1/2 rounded-l-md">
<ChevronLeft />
</Button>
</SheetTrigger>
<SheetContent>
<div className="grid flex-1 auto-rows-min gap-6 bg-[#CBCBCBCC] px-4 py-10 text-black">
<div className="flex flex-col gap-4">
<div className="rounded-lg bg-white p-3 text-lg">
Total Image: 10
</div>{" "}
</div>
</div>
</SheetContent>
</Sheet> */}
</div>
)
}

7
app/dashboard/layout.tsx Normal file
View File

@ -0,0 +1,7 @@
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return <>{children}</>
}

54
app/dashboard/page.tsx Normal file
View File

@ -0,0 +1,54 @@
import DashboardSideMenu from "@/components/layout/dashboard-side-menu"
import Footer from "@/components/layout/footer"
import { PinIcon } from "lucide-react"
import Image from "next/image"
import Link from "next/link"
const dummy = { name: "Andri2 Ferinata", plat: "B 14 QU" }
const menu = [
{ name: "Tugas", href: "/assignment", icon: "icon-tugas.svg" },
{ name: "Patroli Rutin", href: "/assignment", icon: "icon-patrol.svg" },
{ name: "Pengawalan Polisi", href: "/assignment", icon: "icon-patrol.svg" },
{ name: "Komunikasi", href: "/assignment", icon: "icon-komunikasi.svg" },
{ name: "SOS", href: "/assignment", icon: "icon-sos.svg" },
{ name: "Peta", href: "/assignment", icon: "icon-map.svg" },
{ name: "SPKLU", href: "/assignment", icon: "icon-spklu.svg" },
{ name: "Kata Ahli", href: "/assignment", icon: "icon-ahli.svg" },
{ name: "ETLE Toll", href: "/dashboard/etle", icon: "icon-etle.svg" },
]
export default function Dashboard() {
return (
<div className="grid grid-cols-3 px-12 py-16">
<div className="col-span-2 flex flex-col pr-8">
<p className="mb-2 text-3xl font-semibold">
No Kendaraan : {dummy.plat}
</p>
<p className="my-2 text-3xl font-semibold">Petugas : {dummy.name}</p>
<div className="my-2 grid grid-cols-4 gap-8">
{menu.map((item) => (
<Link
href={item.href}
key={item.name}
className="flex flex-col items-center justify-center gap-2 rounded-lg bg-white p-6 text-center text-black"
>
<Image
width={48}
height={148}
src={"/" + item.icon}
alt={item.icon}
/>
<p className="text-lg font-semibold">{item.name}</p>
</Link>
))}
</div>
<Footer />
</div>
<div className="h-[87vh] border-l-2 border-white pl-8">
<DashboardSideMenu />
</div>
</div>
)
}

View File

@ -5,124 +5,124 @@
@custom-variant dark (&:is(.dark *));
:root {
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.809 0.105 251.813);
--chart-2: oklch(0.623 0.214 259.815);
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
--background: oklch(1 0 0);
--foreground: oklch(0.145 0 0);
--card: oklch(1 0 0);
--card-foreground: oklch(0.145 0 0);
--popover: oklch(1 0 0);
--popover-foreground: oklch(0.145 0 0);
--primary: oklch(0.205 0 0);
--primary-foreground: oklch(0.985 0 0);
--secondary: oklch(0.97 0 0);
--secondary-foreground: oklch(0.205 0 0);
--muted: oklch(0.97 0 0);
--muted-foreground: oklch(0.556 0 0);
--accent: oklch(0.97 0 0);
--accent-foreground: oklch(0.205 0 0);
--destructive: oklch(0.577 0.245 27.325);
--border: oklch(0.922 0 0);
--input: oklch(0.922 0 0);
--ring: oklch(0.708 0 0);
--chart-1: oklch(0.809 0.105 251.813);
--chart-2: oklch(0.623 0.214 259.815);
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--radius: 0.625rem;
--sidebar: oklch(0.985 0 0);
--sidebar-foreground: oklch(0.145 0 0);
--sidebar-primary: oklch(0.205 0 0);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.97 0 0);
--sidebar-accent-foreground: oklch(0.205 0 0);
--sidebar-border: oklch(0.922 0 0);
--sidebar-ring: oklch(0.708 0 0);
}
.dark {
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.809 0.105 251.813);
--chart-2: oklch(0.623 0.214 259.815);
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
--background: oklch(0.145 0 0);
--foreground: oklch(0.985 0 0);
--card: oklch(0.205 0 0);
--card-foreground: oklch(0.985 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
--primary-foreground: oklch(0.205 0 0);
--secondary: oklch(0.269 0 0);
--secondary-foreground: oklch(0.985 0 0);
--muted: oklch(0.269 0 0);
--muted-foreground: oklch(0.708 0 0);
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
--border: oklch(1 0 0 / 10%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.809 0.105 251.813);
--chart-2: oklch(0.623 0.214 259.815);
--chart-3: oklch(0.546 0.245 262.881);
--chart-4: oklch(0.488 0.243 264.376);
--chart-5: oklch(0.424 0.199 265.638);
--sidebar: oklch(0.205 0 0);
--sidebar-foreground: oklch(0.985 0 0);
--sidebar-primary: oklch(0.488 0.243 264.376);
--sidebar-primary-foreground: oklch(0.985 0 0);
--sidebar-accent: oklch(0.269 0 0);
--sidebar-accent-foreground: oklch(0.985 0 0);
--sidebar-border: oklch(1 0 0 / 10%);
--sidebar-ring: oklch(0.556 0 0);
}
@theme inline {
--font-sans: var(--font-sans);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--color-foreground: var(--foreground);
--color-background: var(--background);
--radius-sm: calc(var(--radius) * 0.6);
--radius-md: calc(var(--radius) * 0.8);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) * 1.4);
--radius-2xl: calc(var(--radius) * 1.8);
--radius-3xl: calc(var(--radius) * 2.2);
--radius-4xl: calc(var(--radius) * 2.6);
--font-sans: var(--font-sans);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
--color-sidebar-accent: var(--sidebar-accent);
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
--color-sidebar-primary: var(--sidebar-primary);
--color-sidebar-foreground: var(--sidebar-foreground);
--color-sidebar: var(--sidebar);
--color-chart-5: var(--chart-5);
--color-chart-4: var(--chart-4);
--color-chart-3: var(--chart-3);
--color-chart-2: var(--chart-2);
--color-chart-1: var(--chart-1);
--color-ring: var(--ring);
--color-input: var(--input);
--color-border: var(--border);
--color-destructive: var(--destructive);
--color-accent-foreground: var(--accent-foreground);
--color-accent: var(--accent);
--color-muted-foreground: var(--muted-foreground);
--color-muted: var(--muted);
--color-secondary-foreground: var(--secondary-foreground);
--color-secondary: var(--secondary);
--color-primary-foreground: var(--primary-foreground);
--color-primary: var(--primary);
--color-popover-foreground: var(--popover-foreground);
--color-popover: var(--popover);
--color-card-foreground: var(--card-foreground);
--color-card: var(--card);
--color-foreground: var(--foreground);
--color-background: var(--background);
--radius-sm: calc(var(--radius) * 0.6);
--radius-md: calc(var(--radius) * 0.8);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) * 1.4);
--radius-2xl: calc(var(--radius) * 1.8);
--radius-3xl: calc(var(--radius) * 2.2);
--radius-4xl: calc(var(--radius) * 2.6);
}
@layer base {
* {
@apply border-border outline-ring/50;
}
}
body {
@apply bg-background text-foreground;
}
}
html {
@apply font-sans;
}
}
}

View File

@ -1,16 +1,22 @@
import { Geist, Geist_Mono, Inter } from "next/font/google"
import { Geist_Mono, Inter, Roboto } from "next/font/google"
import "./globals.css"
import { ThemeProvider } from "@/components/theme-provider"
import { cn } from "@/lib/utils";
import { cn } from "@/lib/utils"
const inter = Inter({subsets:['latin'],variable:'--font-sans'})
const inter = Inter({ subsets: ["latin"], variable: "--font-sans" })
const fontMono = Geist_Mono({
subsets: ["latin"],
variable: "--font-mono",
})
const roboto = Roboto({
subsets: ["latin"],
weight: ["400", "700", "900"],
variable: "--font-roboto",
})
export default function RootLayout({
children,
}: Readonly<{
@ -20,9 +26,15 @@ export default function RootLayout({
<html
lang="en"
suppressHydrationWarning
className={cn("antialiased", fontMono.variable, "font-sans", inter.variable)}
className={cn(
"antialiased",
fontMono.variable,
inter.variable,
roboto.variable,
"font-sans"
)}
>
<body>
<body className="min-h-screen bg-[url('/main-background.png')] bg-cover bg-center bg-no-repeat">
<ThemeProvider>{children}</ThemeProvider>
</body>
</html>

View File

@ -1,19 +1,35 @@
"use client"
import Footer from "@/components/layout/footer"
import { Button } from "@/components/ui/button"
import Image from "next/image"
import { useRouter } from "next/navigation"
export default function Page() {
const router = useRouter()
return (
<div className="flex min-h-svh p-6">
<div className="flex max-w-md min-w-0 flex-col gap-4 text-sm leading-loose">
<div>
<h1 className="font-medium">Project ready!</h1>
<p>You may now add components and start building.</p>
<p>We&apos;ve already added the button component for you.</p>
<Button className="mt-2">Button</Button>
</div>
<div className="font-mono text-xs text-muted-foreground">
(Press <kbd>d</kbd> to toggle dark mode)
</div>
<div className="flex min-h-screen flex-col px-4 py-6 sm:px-6 md:px-10">
<div className="flex flex-1 flex-col items-center justify-center text-center">
<Image
src="/main-icon.png"
width={160}
height={160}
alt="main-icon"
className="mb-6 w-24 sm:w-28 md:w-32 lg:w-36"
/>
<h1 className="font-heading text-center text-2xl leading-[120%] font-black tracking-[-0.4px] sm:text-3xl md:text-[36px] lg:text-[48px]">
Selamat Datang <br /> di <br /> Silancar!
</h1>
<Button
className="mt-8 h-11 w-full max-w-xs cursor-pointer rounded-lg sm:max-w-sm md:max-w-md"
onClick={() => router.push("/auth/sign-in")}
>
Next
</Button>
</div>
<Footer />
</div>
)
}

View File

@ -0,0 +1,69 @@
import { RefreshCwIcon } from "lucide-react"
import { Button } from "../ui/button"
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel"
const dummy = [
{
name: "Ipda Iwan",
message: "Ndan, lokasi di Bundaran HI lalu lintas lancar",
time: "16 Oct 2024, 13:44",
},
{
name: "Ipda Iwan",
message: "Ndan, lokasi di Bundaran HI lalu lintas lancar",
time: "16 Oct 2024, 13:44",
},
]
export default function DashboardSideMenu() {
return (
<div className="flex flex-col gap-10">
<div className="flex flex-col gap-2">
<div className="flex justify-between text-2xl font-semibold">
Pesan Pribadi Terakhir
<Button>
<RefreshCwIcon />
</Button>
</div>
<Carousel className="w-full">
<CarouselContent>
{dummy.map((list, index) => (
<CarouselItem key={index}>
<div className="flex flex-col gap-2 rounded-lg bg-white p-3 text-black">
<p className="text-lg font-bold">{list.name}</p>
<p className="">{list.message}</p>
<p className="text-right text-xs">{list.time}</p>
</div>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
</div>
<div className="flex flex-col gap-2">
<div className="flex justify-between text-2xl font-semibold">
Panggilan Pribadi Terakhir
</div>
<Carousel className="w-full">
<CarouselContent>
{dummy.map((list, index) => (
<CarouselItem key={index}>
<div className="flex flex-col gap-2 rounded-lg bg-white p-3 text-black">
<p className="text-lg font-bold">{list.name}</p>
<p className="">{list.message}</p>
<p className="text-right text-xs">{list.time}</p>
</div>
</CarouselItem>
))}
</CarouselContent>
</Carousel>
</div>
</div>
)
}

View File

@ -0,0 +1,8 @@
export default function Footer() {
return (
<div className="mt-auto flex w-full flex-col items-center justify-center">
<p>ver 1.0.0</p>
<p>@2024 - Korlantas Hak Cipta Dilindungi Undang-Undang.</p>
</div>
)
}

242
components/ui/carousel.tsx Normal file
View File

@ -0,0 +1,242 @@
"use client"
import * as React from "react"
import useEmblaCarousel, {
type UseEmblaCarouselType,
} from "embla-carousel-react"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { ChevronLeftIcon, ChevronRightIcon } from "lucide-react"
type CarouselApi = UseEmblaCarouselType[1]
type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
type CarouselOptions = UseCarouselParameters[0]
type CarouselPlugin = UseCarouselParameters[1]
type CarouselProps = {
opts?: CarouselOptions
plugins?: CarouselPlugin
orientation?: "horizontal" | "vertical"
setApi?: (api: CarouselApi) => void
}
type CarouselContextProps = {
carouselRef: ReturnType<typeof useEmblaCarousel>[0]
api: ReturnType<typeof useEmblaCarousel>[1]
scrollPrev: () => void
scrollNext: () => void
canScrollPrev: boolean
canScrollNext: boolean
} & CarouselProps
const CarouselContext = React.createContext<CarouselContextProps | null>(null)
function useCarousel() {
const context = React.useContext(CarouselContext)
if (!context) {
throw new Error("useCarousel must be used within a <Carousel />")
}
return context
}
function Carousel({
orientation = "horizontal",
opts,
setApi,
plugins,
className,
children,
...props
}: React.ComponentProps<"div"> & CarouselProps) {
const [carouselRef, api] = useEmblaCarousel(
{
...opts,
axis: orientation === "horizontal" ? "x" : "y",
},
plugins
)
const [canScrollPrev, setCanScrollPrev] = React.useState(false)
const [canScrollNext, setCanScrollNext] = React.useState(false)
const onSelect = React.useCallback((api: CarouselApi) => {
if (!api) return
setCanScrollPrev(api.canScrollPrev())
setCanScrollNext(api.canScrollNext())
}, [])
const scrollPrev = React.useCallback(() => {
api?.scrollPrev()
}, [api])
const scrollNext = React.useCallback(() => {
api?.scrollNext()
}, [api])
const handleKeyDown = React.useCallback(
(event: React.KeyboardEvent<HTMLDivElement>) => {
if (event.key === "ArrowLeft") {
event.preventDefault()
scrollPrev()
} else if (event.key === "ArrowRight") {
event.preventDefault()
scrollNext()
}
},
[scrollPrev, scrollNext]
)
React.useEffect(() => {
if (!api || !setApi) return
setApi(api)
}, [api, setApi])
React.useEffect(() => {
if (!api) return
onSelect(api)
api.on("reInit", onSelect)
api.on("select", onSelect)
return () => {
api?.off("select", onSelect)
}
}, [api, onSelect])
return (
<CarouselContext.Provider
value={{
carouselRef,
api: api,
opts,
orientation:
orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
scrollPrev,
scrollNext,
canScrollPrev,
canScrollNext,
}}
>
<div
onKeyDownCapture={handleKeyDown}
className={cn("relative", className)}
role="region"
aria-roledescription="carousel"
data-slot="carousel"
{...props}
>
{children}
</div>
</CarouselContext.Provider>
)
}
function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
const { carouselRef, orientation } = useCarousel()
return (
<div
ref={carouselRef}
className="overflow-hidden"
data-slot="carousel-content"
>
<div
className={cn(
"flex",
orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
className
)}
{...props}
/>
</div>
)
}
function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
const { orientation } = useCarousel()
return (
<div
role="group"
aria-roledescription="slide"
data-slot="carousel-item"
className={cn(
"min-w-0 shrink-0 grow-0 basis-full",
orientation === "horizontal" ? "pl-4" : "pt-4",
className
)}
{...props}
/>
)
}
function CarouselPrevious({
className,
variant = "outline",
size = "icon-sm",
...props
}: React.ComponentProps<typeof Button>) {
const { orientation, scrollPrev, canScrollPrev } = useCarousel()
return (
<Button
data-slot="carousel-previous"
variant={variant}
size={size}
className={cn(
"absolute touch-manipulation rounded-full",
orientation === "horizontal"
? "top-1/2 -left-12 -translate-y-1/2"
: "-top-12 left-1/2 -translate-x-1/2 rotate-90",
className
)}
disabled={!canScrollPrev}
onClick={scrollPrev}
{...props}
>
<ChevronLeftIcon />
<span className="sr-only">Previous slide</span>
</Button>
)
}
function CarouselNext({
className,
variant = "outline",
size = "icon-sm",
...props
}: React.ComponentProps<typeof Button>) {
const { orientation, scrollNext, canScrollNext } = useCarousel()
return (
<Button
data-slot="carousel-next"
variant={variant}
size={size}
className={cn(
"absolute touch-manipulation rounded-full",
orientation === "horizontal"
? "top-1/2 -right-12 -translate-y-1/2"
: "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
className
)}
disabled={!canScrollNext}
onClick={scrollNext}
{...props}
>
<ChevronRightIcon />
<span className="sr-only">Next slide</span>
</Button>
)
}
export {
type CarouselApi,
Carousel,
CarouselContent,
CarouselItem,
CarouselPrevious,
CarouselNext,
useCarousel,
}

131
components/ui/drawer.tsx Normal file
View File

@ -0,0 +1,131 @@
"use client"
import * as React from "react"
import { Drawer as DrawerPrimitive } from "vaul"
import { cn } from "@/lib/utils"
function Drawer({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Root>) {
return <DrawerPrimitive.Root data-slot="drawer" {...props} />
}
function DrawerTrigger({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {
return <DrawerPrimitive.Trigger data-slot="drawer-trigger" {...props} />
}
function DrawerPortal({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {
return <DrawerPrimitive.Portal data-slot="drawer-portal" {...props} />
}
function DrawerClose({
...props
}: React.ComponentProps<typeof DrawerPrimitive.Close>) {
return <DrawerPrimitive.Close data-slot="drawer-close" {...props} />
}
function DrawerOverlay({
className,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {
return (
<DrawerPrimitive.Overlay
data-slot="drawer-overlay"
className={cn(
"fixed inset-0 z-50 bg-black/10 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
className
)}
{...props}
/>
)
}
function DrawerContent({
className,
children,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Content>) {
return (
<DrawerPortal data-slot="drawer-portal">
<DrawerOverlay />
<DrawerPrimitive.Content
data-slot="drawer-content"
className={cn(
"group/drawer-content fixed z-50 flex h-auto flex-col bg-background text-sm data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-xl data-[vaul-drawer-direction=bottom]:border-t data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:rounded-r-xl data-[vaul-drawer-direction=left]:border-r data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:rounded-l-xl data-[vaul-drawer-direction=right]:border-l data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-xl data-[vaul-drawer-direction=top]:border-b data-[vaul-drawer-direction=left]:sm:max-w-sm data-[vaul-drawer-direction=right]:sm:max-w-sm",
className
)}
{...props}
>
<div className="mx-auto mt-4 hidden h-1 w-[100px] shrink-0 rounded-full bg-muted group-data-[vaul-drawer-direction=bottom]/drawer-content:block" />
{children}
</DrawerPrimitive.Content>
</DrawerPortal>
)
}
function DrawerHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="drawer-header"
className={cn(
"flex flex-col gap-0.5 p-4 group-data-[vaul-drawer-direction=bottom]/drawer-content:text-center group-data-[vaul-drawer-direction=top]/drawer-content:text-center md:gap-0.5 md:text-left",
className
)}
{...props}
/>
)
}
function DrawerFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="drawer-footer"
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
)
}
function DrawerTitle({
className,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Title>) {
return (
<DrawerPrimitive.Title
data-slot="drawer-title"
className={cn("text-base font-medium text-foreground", className)}
{...props}
/>
)
}
function DrawerDescription({
className,
...props
}: React.ComponentProps<typeof DrawerPrimitive.Description>) {
return (
<DrawerPrimitive.Description
data-slot="drawer-description"
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
)
}
export {
Drawer,
DrawerPortal,
DrawerOverlay,
DrawerTrigger,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerFooter,
DrawerTitle,
DrawerDescription,
}

19
components/ui/input.tsx Normal file
View File

@ -0,0 +1,19 @@
import * as React from "react"
import { cn } from "@/lib/utils"
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
<input
type={type}
data-slot="input"
className={cn(
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
className
)}
{...props}
/>
)
}
export { Input }

144
components/ui/sheet.tsx Normal file
View File

@ -0,0 +1,144 @@
"use client"
import * as React from "react"
import { Dialog as SheetPrimitive } from "radix-ui"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { XIcon } from "lucide-react"
function Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {
return <SheetPrimitive.Root data-slot="sheet" {...props} />
}
function SheetTrigger({
...props
}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {
return <SheetPrimitive.Trigger data-slot="sheet-trigger" {...props} />
}
function SheetClose({
...props
}: React.ComponentProps<typeof SheetPrimitive.Close>) {
return <SheetPrimitive.Close data-slot="sheet-close" {...props} />
}
function SheetPortal({
...props
}: React.ComponentProps<typeof SheetPrimitive.Portal>) {
return <SheetPrimitive.Portal data-slot="sheet-portal" {...props} />
}
function SheetOverlay({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {
return (
<SheetPrimitive.Overlay
data-slot="sheet-overlay"
className={cn(
"fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0",
className
)}
{...props}
/>
)
}
function SheetContent({
className,
children,
side = "right",
showCloseButton = true,
...props
}: React.ComponentProps<typeof SheetPrimitive.Content> & {
side?: "top" | "right" | "bottom" | "left"
showCloseButton?: boolean
}) {
return (
<SheetPortal>
<SheetOverlay />
<SheetPrimitive.Content
data-slot="sheet-content"
data-side={side}
className={cn(
"fixed z-50 flex flex-col gap-4 bg-background bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10",
className
)}
{...props}
>
{children}
{showCloseButton && (
<SheetPrimitive.Close data-slot="sheet-close" asChild>
<Button
variant="ghost"
className="absolute top-3 right-3"
size="icon-sm"
>
<XIcon
/>
<span className="sr-only">Close</span>
</Button>
</SheetPrimitive.Close>
)}
</SheetPrimitive.Content>
</SheetPortal>
)
}
function SheetHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sheet-header"
className={cn("flex flex-col gap-0.5 p-4", className)}
{...props}
/>
)
}
function SheetFooter({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="sheet-footer"
className={cn("mt-auto flex flex-col gap-2 p-4", className)}
{...props}
/>
)
}
function SheetTitle({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Title>) {
return (
<SheetPrimitive.Title
data-slot="sheet-title"
className={cn("text-base font-medium text-foreground", className)}
{...props}
/>
)
}
function SheetDescription({
className,
...props
}: React.ComponentProps<typeof SheetPrimitive.Description>) {
return (
<SheetPrimitive.Description
data-slot="sheet-description"
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
)
}
export {
Sheet,
SheetTrigger,
SheetClose,
SheetContent,
SheetHeader,
SheetFooter,
SheetTitle,
SheetDescription,
}

57
package-lock.json generated
View File

@ -10,15 +10,18 @@
"dependencies": {
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"embla-carousel-react": "^8.6.0",
"lucide-react": "^0.577.0",
"next": "16.1.7",
"next-themes": "^0.4.6",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-hook-form": "^7.71.2",
"shadcn": "^4.0.8",
"tailwind-merge": "^3.5.0",
"tw-animate-css": "^1.4.0"
"tw-animate-css": "^1.4.0",
"vaul": "^1.1.2"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
@ -5224,6 +5227,31 @@
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.313.tgz",
"integrity": "sha512-QBMrTWEf00GXZmJyx2lbYD45jpI3TUFnNIzJ5BBc8piGUDwMPa1GV6HJWTZVvY/eiN3fSopl7NRbgGp9sZ9LTA=="
},
"node_modules/embla-carousel": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
"integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA=="
},
"node_modules/embla-carousel-react": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.6.0.tgz",
"integrity": "sha512-0/PjqU7geVmo6F734pmPqpyHqiM99olvyecY7zdweCw+6tKEXnrE90pBiBbMMU8s5tICemzpQ3hi5EpxzGW+JA==",
"dependencies": {
"embla-carousel": "8.6.0",
"embla-carousel-reactive-utils": "8.6.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc"
}
},
"node_modules/embla-carousel-reactive-utils": {
"version": "8.6.0",
"resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz",
"integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==",
"peerDependencies": {
"embla-carousel": "8.6.0"
}
},
"node_modules/emoji-regex": {
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
@ -8923,6 +8951,21 @@
"react": "^19.2.4"
}
},
"node_modules/react-hook-form": {
"version": "7.71.2",
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.2.tgz",
"integrity": "sha512-1CHvcDYzuRUNOflt4MOq3ZM46AronNJtQ1S7tnX6YN4y72qhgiUItpacZUAQ0TyWYci3yz1X+rXaSxiuEm86PA==",
"engines": {
"node": ">=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/react-hook-form"
},
"peerDependencies": {
"react": "^16.8.0 || ^17 || ^18 || ^19"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@ -10442,6 +10485,18 @@
"node": ">= 0.8"
}
},
"node_modules/vaul": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vaul/-/vaul-1.1.2.tgz",
"integrity": "sha512-ZFkClGpWyI2WUQjdLJ/BaGuV6AVQiJ3uELGk3OYtP+B6yCO7Cmn9vPFXVJkRaGkOJu3m8bQMgtyzNHixULceQA==",
"dependencies": {
"@radix-ui/react-dialog": "^1.1.1"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",

View File

@ -14,15 +14,18 @@
"dependencies": {
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"embla-carousel-react": "^8.6.0",
"lucide-react": "^0.577.0",
"next": "16.1.7",
"next-themes": "^0.4.6",
"radix-ui": "^1.4.3",
"react": "^19.2.4",
"react-dom": "^19.2.4",
"react-hook-form": "^7.71.2",
"shadcn": "^4.0.8",
"tailwind-merge": "^3.5.0",
"tw-animate-css": "^1.4.0"
"tw-animate-css": "^1.4.0",
"vaul": "^1.1.2"
},
"devDependencies": {
"@eslint/eslintrc": "^3",

3
public/icon-ahli.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.6665 2.66669H5.33317C4.6265 2.66669 3.9465 2.94669 3.45317 3.45335C2.9465 3.94669 2.6665 4.62669 2.6665 5.33335V21.3334C2.6665 22.04 2.9465 22.72 3.45317 23.2134C3.9465 23.72 4.6265 24 5.33317 24H10.6665L15.9998 29.3334L21.3332 24H26.6665C27.3732 24 28.0532 23.72 28.5465 23.2134C29.0398 22.7067 29.3332 22.04 29.3332 21.3334V5.33335C29.3332 4.62669 29.0532 3.94669 28.5465 3.45335C28.0532 2.94669 27.3732 2.66669 26.6665 2.66669ZM13.3998 8.05335C14.1198 7.57335 15.0665 7.33335 16.2532 7.33335C17.5065 7.33335 18.5065 7.61335 19.2265 8.16002C19.9465 8.72002 20.3065 9.46669 20.3065 10.4C20.3065 10.9867 20.1065 11.5067 19.7198 12C19.3332 12.48 18.8265 12.8534 18.2132 13.1334C17.8665 13.3334 17.6398 13.5334 17.5198 13.76C17.3998 14 17.3332 14.2934 17.3332 14.6667H14.6665C14.6665 14 14.7998 13.5467 15.0532 13.2267C15.3332 12.9067 15.7865 12.5334 16.4798 12.1067C16.8265 11.92 17.1065 11.68 17.3332 11.3867C17.5198 11.1067 17.6265 10.7734 17.6265 10.4C17.6265 10 17.5065 9.70669 17.2665 9.48002C17.0265 9.24002 16.6665 9.13335 16.2532 9.13335C15.8932 9.13335 15.5998 9.22669 15.3332 9.41335C15.1198 9.60002 14.9865 9.88002 14.9865 10.2534H12.3598C12.2932 9.33335 12.6665 8.53335 13.3998 8.05335ZM14.6665 18.6667V16H17.3332V18.6667H14.6665Z" fill="#1E1E1E"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

3
public/icon-etle.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.8008 24.2765H22.2332V7.72351H27.8008C28.007 7.72351 28.1757 7.89223 28.1757 8.09844C28.1757 9.99182 29.7317 11.529 31.6251 11.529C31.8313 11.529 32 11.6977 32 11.9039V20.0773C32 20.2836 31.8313 20.4523 31.6251 20.4523C29.7317 20.4523 28.1757 22.0082 28.1757 23.9016C28.1757 24.1078 28.007 24.2765 27.8008 24.2765ZM19.365 22.0645H2.86819C2.66198 22.0645 2.49326 21.8957 2.49326 21.6895C2.49326 21.4833 2.66198 21.3146 2.86819 21.3146H19.365C19.5712 21.3146 19.7399 21.4833 19.7399 21.6895C19.7399 21.8957 19.5712 22.0645 19.365 22.0645ZM19.365 10.6667H2.86819C2.66198 10.6667 2.49326 10.498 2.49326 10.2918C2.49326 10.0855 2.66198 9.91683 2.86819 9.91683H19.365C19.5712 9.91683 19.7399 10.0855 19.7399 10.2918C19.7399 10.498 19.5712 10.6667 19.365 10.6667ZM26.3199 21.1459C26.1136 21.1459 25.9449 20.9772 25.9449 20.771V11.2291C25.9449 11.0229 26.1136 10.8541 26.3199 10.8541C26.5261 10.8541 26.6948 11.0229 26.6948 11.2291V20.771C26.6948 20.9772 26.5448 21.1459 26.3199 21.1459ZM24.239 18.7276C24.0328 18.7276 23.8641 18.5589 23.8641 18.3527V13.6286C23.8641 13.4224 24.0328 13.2537 24.239 13.2537C24.4452 13.2537 24.6139 13.4224 24.6139 13.6286V18.3527C24.6139 18.5589 24.4452 18.7276 24.239 18.7276ZM21.4833 24.2765H0.374927C0.168717 24.2765 0 24.1078 0 23.9016V8.09844C0 7.89223 0.168717 7.72351 0.374927 7.72351H21.4833V24.2765ZM11.8102 17.0217H9.72935C9.52314 17.0217 9.35442 16.853 9.35442 16.6468C9.35442 16.4406 9.52314 16.2718 9.72935 16.2718H11.8102C12.0164 16.2718 12.1851 16.4406 12.1851 16.6468C12.1851 16.853 12.0164 17.0217 11.8102 17.0217ZM15.0346 18.7839H14.7721V19.4025C14.7721 19.9274 14.3409 20.3773 13.7973 20.3773H12.6913C12.1664 20.3773 11.7165 19.9274 11.7165 19.4025V18.7839H9.82308V19.4025C9.80434 19.9274 9.37317 20.3773 8.82953 20.3773H7.74224C7.19859 20.3773 6.74868 19.9274 6.74868 19.4025V18.7839H6.48623C6.07381 18.7839 5.71763 18.4464 5.71763 18.034V15.2595C5.71763 14.8284 6.07381 14.4909 6.48623 14.4909H6.97364L7.686 12.2789C7.87346 11.6977 8.22964 11.6227 8.43585 11.6227H13.1037C13.3099 11.6227 13.6661 11.7165 13.8535 12.2789L14.5659 14.4909H15.0346C15.4657 14.4909 15.8032 14.8284 15.8032 15.2595V16.2906V18.034C15.8032 18.4464 15.4657 18.7839 15.0346 18.7839ZM14.0223 18.7839H12.4663V19.4025C12.4663 19.515 12.5788 19.6274 12.71 19.6274H13.7973C13.9285 19.6274 14.0223 19.515 14.0223 19.4025V18.7839ZM9.07323 18.7839H7.49854V19.4025C7.49854 19.515 7.61101 19.6274 7.74224 19.6274H8.82953C8.96075 19.6274 9.07323 19.515 9.07323 19.4025V18.7839ZM7.76098 14.4909H13.7786L13.1412 12.5038C13.1037 12.4288 13.0849 12.3913 13.0849 12.3726H8.4546C8.43585 12.3913 8.41711 12.4288 8.39836 12.5038L7.76098 14.4909ZM6.48623 15.2408C6.48623 15.2408 6.46749 15.2408 6.46749 15.2595V15.9157H7.36731C7.55477 15.9157 7.70475 15.7657 7.70475 15.5782V15.2408H6.48623ZM6.46749 16.6655V18.034H15.0346L15.0533 16.6655H14.1722C13.5723 16.6655 13.0849 16.1781 13.0849 15.5782V15.2595L8.4546 15.2408V15.5782C8.4546 16.1781 7.96719 16.6655 7.36731 16.6655H6.46749ZM15.0533 15.9157V15.2595H13.8348V15.5782C13.8348 15.7657 13.9848 15.9157 14.1722 15.9157H15.0533Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16 7.00001C13.8251 7.00048 11.6992 7.64565 9.89084 8.854C8.08252 10.0624 6.67298 11.7796 5.84036 13.7889C5.00774 15.7981 4.78941 18.009 5.21297 20.1422C5.63652 22.2755 6.68295 24.2353 8.22001 25.774C8.50114 26.0557 8.65886 26.4375 8.65849 26.8354C8.65811 27.2334 8.49967 27.6149 8.21801 27.896C7.93635 28.1771 7.55454 28.3349 7.15659 28.3345C6.75864 28.3341 6.37714 28.1757 6.09601 27.894C4.13935 25.9356 2.80724 23.441 2.26808 20.7256C1.72892 18.0102 2.00691 15.1959 3.06691 12.6385C4.12691 10.0811 5.92134 7.89534 8.22335 6.35756C10.5254 4.81979 13.2316 3.99902 16 3.99902C18.7684 3.99902 21.4747 4.81979 23.7767 6.35756C26.0787 7.89534 27.8731 10.0811 28.9331 12.6385C29.9931 15.1959 30.2711 18.0102 29.7319 20.7256C29.1928 23.441 27.8607 25.9356 25.904 27.894C25.7657 28.0373 25.6002 28.1517 25.4173 28.2304C25.2343 28.3091 25.0375 28.3506 24.8383 28.3524C24.6392 28.3542 24.4416 28.3163 24.2572 28.241C24.0729 28.1657 23.9053 28.0544 23.7644 27.9136C23.6235 27.7728 23.5121 27.6054 23.4366 27.4211C23.361 27.2368 23.323 27.0393 23.3246 26.8401C23.3263 26.641 23.3676 26.4441 23.4461 26.2611C23.5246 26.078 23.6388 25.9124 23.782 25.774C25.3192 24.2352 26.3657 22.2752 26.7891 20.1417C27.2126 18.0083 26.9941 15.7972 26.1613 13.7879C25.3284 11.7786 23.9186 10.0614 22.1099 8.85317C20.3013 7.64497 18.1751 7.00008 16 7.00001ZM16 15C15.2044 15 14.4413 15.3161 13.8787 15.8787C13.3161 16.4413 13 17.2044 13 18C13 18.7957 13.3161 19.5587 13.8787 20.1213C14.4413 20.6839 15.2044 21 16 21C16.7957 21 17.5587 20.6839 18.1213 20.1213C18.6839 19.5587 19 18.7957 19 18C19 17.2044 18.6839 16.4413 18.1213 15.8787C17.5587 15.3161 16.7957 15 16 15ZM10.5 18C10.5 17.0957 10.7229 16.2053 11.1491 15.4077C11.5753 14.6102 12.1916 13.93 12.9434 13.4274C13.6952 12.9248 14.5593 12.6154 15.4593 12.5265C16.3592 12.4376 17.2672 12.5719 18.1028 12.9177C18.9384 13.2634 19.6759 13.8099 20.2499 14.5086C20.8239 15.2074 21.2168 16.0369 21.3937 16.9238C21.5706 17.8106 21.5262 18.7274 21.2642 19.5929C21.0023 20.4585 20.531 21.2461 19.892 21.886C19.6109 22.1677 19.4531 22.5495 19.4535 22.9474C19.4539 23.3454 19.6123 23.7269 19.894 24.008C20.1757 24.2891 20.5575 24.4469 20.9554 24.4465C21.3534 24.4461 21.7349 24.2877 22.016 24.006C23.2035 22.8167 24.0117 21.3022 24.3386 19.6537C24.6656 18.0052 24.4965 16.2968 23.8527 14.7444C23.209 13.192 22.1195 11.8652 20.722 10.9318C19.3245 9.99839 17.6816 9.5002 16.001 9.5002C14.3204 9.5002 12.6775 9.99839 11.28 10.9318C9.88247 11.8652 8.793 13.192 8.14927 14.7444C7.50555 16.2968 7.33646 18.0052 7.66338 19.6537C7.9903 21.3022 8.79856 22.8167 9.98601 24.006C10.1233 24.1534 10.2889 24.2716 10.4729 24.3536C10.6569 24.4356 10.8556 24.4796 11.057 24.4832C11.2584 24.4867 11.4584 24.4497 11.6452 24.3743C11.832 24.2988 12.0016 24.1865 12.1441 24.0441C12.2865 23.9017 12.3988 23.732 12.4743 23.5452C12.5497 23.3584 12.5867 23.1584 12.5832 22.957C12.5796 22.7556 12.5356 22.5569 12.4536 22.3729C12.3716 22.1889 12.2534 22.0233 12.106 21.886C11.5957 21.3759 11.1911 20.77 10.9155 20.1032C10.6399 19.4363 10.4987 18.7216 10.5 18Z" fill="#1E1E1E"/>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

10
public/icon-map.svg Normal file
View File

@ -0,0 +1,10 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2357_21612)">
<path d="M9.99984 3.62265L2.6665 7.90131V28.6666L9.99984 25.644V3.62265ZM12.6665 25.2133L14.9998 26.5906V22.3333C14.9995 20.786 15.3982 19.2648 16.1572 17.9165C16.9163 16.5681 18.0101 15.4383 19.3332 14.636V6.78798L12.6665 2.85065V25.2133ZM29.3332 3.33331V15.0826C28.2913 14.3181 27.0975 13.7861 25.8323 13.5227C24.5672 13.2594 23.2602 13.2707 21.9998 13.556V6.35598L29.3332 3.33331ZM23.9998 31.6013L23.7292 31.4226C23.4838 31.2613 23.2385 31.1 22.9998 30.9266C22.1008 30.2632 21.2681 29.5144 20.5132 28.6906C19.1865 27.232 17.6665 25.0013 17.6665 22.3333C17.6665 21.5016 17.8303 20.678 18.1486 19.9097C18.4669 19.1413 18.9334 18.4431 19.5215 17.855C20.1096 17.2669 20.8078 16.8004 21.5762 16.4821C22.3446 16.1638 23.1681 16 23.9998 16C24.8315 16 25.6551 16.1638 26.4235 16.4821C27.1919 16.8004 27.8901 17.2669 28.4782 17.855C29.0663 18.4431 29.5328 19.1413 29.8511 19.9097C30.1694 20.678 30.3332 21.5016 30.3332 22.3333C30.3332 25.0013 28.8132 27.232 27.4865 28.6906C26.7316 29.5144 25.8989 30.2632 24.9998 30.9266C24.7612 31.1 24.5158 31.26 24.2705 31.4226L23.9998 31.6013ZM25.6665 21.3333H22.3332V24H25.6665V21.3333Z" fill="#1E1E1E"/>
</g>
<defs>
<clipPath id="clip0_2357_21612">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

19
public/icon-patrol.svg Normal file
View File

@ -0,0 +1,19 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_2357_21564)">
<path d="M13.4429 3.4375H7.86914C8.02477 2.03313 9.21539 0.9375 10.656 0.9375C12.0966 0.9375 13.2873 2.03313 13.4429 3.4375Z" fill="#1E1E1E"/>
<path d="M5.7326 2.75049C5.6146 2.75049 5.49473 2.72799 5.37873 2.68031L3.24823 1.80531C2.77048 1.60912 2.54179 1.06162 2.73748 0.582494C2.93304 0.103369 3.47898 -0.126131 3.95673 0.070244L6.08723 0.945244C6.56498 1.14143 6.79366 1.68893 6.59798 2.16806C6.44985 2.53087 6.10079 2.75049 5.7326 2.75049Z" fill="#1E1E1E"/>
<path d="M15.5799 2.7505C15.2116 2.7505 14.8626 2.53087 14.7145 2.16806C14.5189 1.68894 14.7476 1.14137 15.2252 0.945249L17.3557 0.0702489C17.8337 -0.125939 18.3795 0.103436 18.575 0.582499C18.7706 1.06162 18.5419 1.60919 18.0642 1.80531L15.9337 2.68031C15.8178 2.72794 15.6978 2.7505 15.5799 2.7505Z" fill="#1E1E1E"/>
<path d="M18.7351 8.625H2.57764L3.75389 5.87687C3.90201 5.53437 4.23889 5.3125 4.61139 5.3125H16.7014C17.0739 5.3125 17.4108 5.53437 17.5589 5.87687L18.7351 8.625Z" fill="#1E1E1E"/>
<path d="M6.875 20.8125V21.75C6.875 22.2675 6.455 22.6875 5.9375 22.6875H2.8125C2.295 22.6875 1.875 22.2675 1.875 21.75V20.8125H6.875Z" fill="#1E1E1E"/>
<path d="M20.3775 10.5H0.935C0.41875 10.5 0 10.92 0 11.4375V18C0 18.5175 0.41875 18.9375 0.935 18.9375H10.8737L12.8112 15.75H8.59375C8.07625 15.75 7.65625 15.33 7.65625 14.8125C7.65625 14.295 8.07625 13.875 8.59375 13.875H13.9513L14.1956 13.4731C14.7019 12.6413 15.62 12.125 16.5919 12.125H21.3125V11.4375C21.3125 10.92 20.8938 10.5 20.3775 10.5ZM4.6875 15.6562C4.17 15.6562 3.75 15.2369 3.75 14.7188C3.75 14.2013 4.17 13.7812 4.6875 13.7812C5.205 13.7812 5.625 14.2013 5.625 14.7188C5.625 15.2369 5.205 15.6562 4.6875 15.6562Z" fill="#1E1E1E"/>
<path d="M17.5826 30.125V31.0625C17.5826 31.58 17.1651 32 16.6507 32H13.5476C13.0332 32 12.6157 31.58 12.6157 31.0625V30.125H17.5826Z" fill="#1E1E1E"/>
<path d="M30.1363 30.125V31.0625C30.1363 31.58 29.7188 32 29.2044 32H26.1013C25.5869 32 25.1694 31.58 25.1694 31.0625V30.125H30.1363Z" fill="#1E1E1E"/>
<path d="M29.5038 20.125H13.2482C11.8713 20.125 10.752 21.2512 10.752 22.6362V27.3125C10.752 27.83 11.1695 28.25 11.6838 28.25H31.0682C31.5826 28.25 32.0001 27.83 32.0001 27.3125V22.6362C32.0001 21.2512 30.8807 20.125 29.5038 20.125ZM15.4113 25.125C14.897 25.125 14.4795 24.7056 14.4795 24.1875C14.4795 23.67 14.897 23.25 15.4113 23.25C15.9263 23.25 16.3438 23.67 16.3438 24.1875C16.3438 24.7056 15.9263 25.125 15.4113 25.125ZM23.6126 25.125H19.1395C18.6251 25.125 18.2076 24.705 18.2076 24.1875C18.2076 23.67 18.6251 23.25 19.1395 23.25H23.6126C24.127 23.25 24.5445 23.67 24.5445 24.1875C24.5445 24.705 24.127 25.125 23.6126 25.125ZM27.3407 25.125C26.8257 25.125 26.4082 24.7056 26.4082 24.1875C26.4082 23.67 26.8257 23.25 27.3407 23.25C27.8551 23.25 28.2726 23.67 28.2726 24.1875C28.2726 24.7056 27.8551 25.125 27.3407 25.125Z" fill="#1E1E1E"/>
<path d="M29.2665 18.25H13.4858L15.7971 14.4481C15.9665 14.17 16.2677 14 16.5921 14H26.1602C26.4846 14 26.7858 14.17 26.9552 14.4481L29.2665 18.25Z" fill="#1E1E1E"/>
</g>
<defs>
<clipPath id="clip0_2357_21564">
<rect width="32" height="32" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

4
public/icon-sos.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M16.2761 11.5655C15.2371 11.5655 14.3911 12.385 14.3911 13.3915V18.6085C14.3911 19.6165 15.2366 20.4345 16.2761 20.4345C17.3156 20.4345 18.1611 19.616 18.1611 18.6085V13.3915C18.1606 12.385 17.3151 11.5655 16.2761 11.5655Z" fill="#1E1E1E"/>
<path d="M26 1H6C3.2385 1 1 3.2385 1 6V26C1 28.7615 3.2385 31 6 31H26C28.7615 31 31 28.7615 31 26V6C31 3.2385 28.7615 1 26 1ZM8.333 15.2225C8.791 15.2225 9.2395 15.3165 9.6655 15.501C10.0707 15.6767 10.4395 15.9265 10.753 16.2375C11.0658 16.5442 11.3176 16.9075 11.495 17.308C11.6815 17.729 11.776 18.1685 11.776 18.6145C11.776 19.0715 11.685 19.515 11.5045 19.933C11.3308 20.3361 11.0799 20.7013 10.766 21.008C10.1154 21.6451 9.24062 22.0013 8.33 22C7.865 22 7.305 21.8995 6.881 21.7215C6.4729 21.5525 6.10114 21.3065 5.786 20.997C5.47217 20.6898 5.22132 20.3243 5.0475 19.921C4.86764 19.5051 4.77522 19.0566 4.776 18.6035H6.3665C6.3665 19.6085 7.3075 20.4375 8.3305 20.4375C9.354 20.4375 10.186 19.619 10.186 18.6145C10.186 17.6575 9.3025 16.7855 8.3335 16.7855C7.464 16.7855 6.5685 16.4095 5.877 15.754C5.1785 15.091 4.7765 14.2275 4.7765 13.386C4.7765 12.929 4.8675 12.4855 5.048 12.0675C5.22192 11.664 5.47275 11.2982 5.7865 10.9905C6.1015 10.6811 6.47332 10.4354 6.8815 10.267C7.305 10.089 7.757 10 8.2215 10C8.686 10 9.2465 10.077 9.6705 10.254C10.4922 10.594 11.1496 11.24 11.504 12.0555C11.6845 12.4725 11.7755 12.916 11.7755 13.373H10.185C10.185 12.368 9.244 11.5625 8.221 11.5625C7.1975 11.5625 6.3655 12.38 6.3655 13.3855C6.366 14.2775 7.378 15.2225 8.333 15.2225ZM19.776 18.6085C19.776 19.0665 19.683 19.511 19.5005 19.929C19.3232 20.3338 19.0684 20.7 18.7505 21.007C18.4292 21.3179 18.0514 21.5645 17.6375 21.7335C17.2065 21.91 16.748 22 16.276 22C15.804 22 15.3455 21.91 14.913 21.7335C14.4995 21.5643 14.1221 21.3177 13.801 21.007C13.4826 20.7005 13.2277 20.3341 13.051 19.929C12.8687 19.5127 12.7749 19.063 12.7755 18.6085V13.3915C12.7755 12.9345 12.8685 12.49 13.051 12.071C13.2276 11.6658 13.4824 11.2994 13.801 10.993C14.1218 10.682 14.4993 10.4353 14.913 10.2665C15.345 10.09 15.8035 10 16.276 10C16.7485 10 17.2065 10.09 17.638 10.2665C18.0555 10.4375 18.43 10.6815 18.751 10.993C19.072 11.3045 19.324 11.667 19.501 12.071C19.6835 12.49 19.7765 12.9345 19.7765 13.3915L19.776 18.6085ZM24.334 15.2215C24.7905 15.2215 25.239 15.316 25.6665 15.501C26.48 15.8547 27.1325 16.499 27.4965 17.308C27.6815 17.729 27.776 18.1685 27.776 18.6145C27.776 19.0715 27.6845 19.515 27.5045 19.933C27.3311 20.3363 27.0806 20.7018 26.767 21.009C26.452 21.3186 26.0802 21.5646 25.672 21.7335C25.246 21.91 24.7945 22 24.3295 22C23.8645 22 23.3055 21.8985 22.88 21.7215C22.4724 21.5521 22.101 21.3062 21.786 20.997C21.4719 20.69 21.221 20.3245 21.0475 19.921C20.8678 19.5047 20.7754 19.0559 20.776 18.6025H22.367C22.367 19.6085 23.307 20.4375 24.33 20.4375C25.3535 20.4375 26.186 19.619 26.186 18.6145C26.186 17.6575 25.3035 16.7855 24.3345 16.7855C23.4645 16.7855 22.569 16.4095 21.877 15.754C21.1775 15.091 20.7765 14.2275 20.7765 13.386C20.7766 12.9397 20.866 12.4979 21.0395 12.0867C21.2129 11.6754 21.4669 11.3031 21.7865 10.9915C22.1013 10.6818 22.4727 10.4355 22.8805 10.266C23.3055 10.089 23.7575 10 24.222 10C24.6865 10 25.246 10.077 25.6715 10.254C26.0815 10.425 26.4505 10.669 26.7665 10.9795C27.0802 11.2866 27.3307 11.6521 27.504 12.0555C27.684 12.4725 27.7755 12.916 27.7755 13.373H26.185C26.185 12.368 25.2445 11.5625 24.2215 11.5625C23.198 11.5625 22.366 12.38 22.366 13.3855C22.3665 14.2775 23.377 15.2215 24.334 15.2215Z" fill="#1E1E1E"/>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

4
public/icon-spklu.svg Normal file
View File

@ -0,0 +1,4 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.3602 9.64L26.3735 9.62667L22.1202 5.37333C21.932 5.18736 21.6781 5.08306 21.4135 5.08306C21.1489 5.08306 20.895 5.18736 20.7068 5.37333C20.3202 5.76 20.3202 6.4 20.7068 6.78667L22.8135 8.89333C21.4135 9.42667 20.4668 10.8533 20.7068 12.5067C20.9202 13.9733 22.1735 15.16 23.6402 15.32C24.2668 15.3867 24.8135 15.28 25.3335 15.0533V24.6667C25.3335 25.4 24.7335 26 24.0002 26C23.2668 26 22.6668 25.4 22.6668 24.6667V18.6667C22.6668 17.2 21.4668 16 20.0002 16H18.6668V6.66667C18.6668 5.2 17.4668 4 16.0002 4H8.00016C6.5335 4 5.3335 5.2 5.3335 6.66667V26.6667C5.3335 27.4 5.9335 28 6.66683 28H17.3335C18.0668 28 18.6668 27.4 18.6668 26.6667V18H20.6668V24.48C20.6668 26.2267 21.9202 27.8133 23.6535 27.9867C24.1183 28.0353 24.5882 27.9856 25.0326 27.8408C25.477 27.6961 25.886 27.4595 26.233 27.1464C26.58 26.8333 26.8574 26.4507 27.0469 26.0235C27.2365 25.5963 27.3342 25.134 27.3335 24.6667V12C27.3335 11.08 26.9602 10.24 26.3602 9.64ZM16.0002 13.3333H8.00016V8C8.00016 7.26667 8.60016 6.66667 9.3335 6.66667H14.6668C15.4002 6.66667 16.0002 7.26667 16.0002 8V13.3333ZM24.0002 13.3333C23.2668 13.3333 22.6668 12.7333 22.6668 12C22.6668 11.2667 23.2668 10.6667 24.0002 10.6667C24.7335 10.6667 25.3335 11.2667 25.3335 12C25.3335 12.7333 24.7335 13.3333 24.0002 13.3333Z" fill="#1E1E1E"/>
<path d="M9.5 26.5L11.5 22.75L7.5 22.25L13.5 16.5H14.5L12.5 20.25L16.5 20.75L10.5 26.5H9.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

3
public/icon-tugas.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.6668 2.668C24.427 2.66791 25.1589 2.95639 25.7145 3.47516C26.2701 3.99392 26.6081 4.70428 26.6602 5.46267L26.6668 5.66667V19.1707C26.5059 19.2773 26.3544 19.4018 26.2122 19.544L21.6668 24.088L20.4562 22.8747C19.924 22.3407 19.2095 22.0278 18.4562 21.9987H21.6668C21.932 21.9987 22.1864 21.8933 22.3739 21.7058C22.5615 21.5182 22.6668 21.2639 22.6668 20.9987C22.6668 20.7334 22.5615 20.4791 22.3739 20.2916C22.1864 20.104 21.932 19.9987 21.6668 19.9987H14.9948C14.7296 19.9987 14.4753 20.104 14.2877 20.2916C14.1002 20.4791 13.9948 20.7334 13.9948 20.9987C13.9948 21.2639 14.1002 21.5182 14.2877 21.7058C14.4753 21.8933 14.7296 21.9987 14.9948 21.9987H18.2122C17.6297 22.0223 17.0667 22.2151 16.592 22.5535C16.1173 22.892 15.7516 23.3614 15.5394 23.9044C15.3272 24.4474 15.2779 25.0405 15.3974 25.611C15.5168 26.1816 15.8 26.7051 16.2122 27.1173L18.4242 29.3307H8.3335C7.57333 29.3308 6.84147 29.0423 6.28583 28.5235C5.73018 28.0047 5.39219 27.2944 5.34016 26.536L5.3335 26.3333V5.668C5.3334 4.90783 5.62189 4.17597 6.14065 3.62033C6.65942 3.06468 7.36978 2.7267 8.12816 2.67467L8.3335 2.668H23.6668ZM12.0002 10.3347C12.0002 9.98104 11.8597 9.64191 11.6096 9.39186C11.3596 9.14181 11.0205 9.00133 10.6668 9.00133C10.3132 9.00133 9.97407 9.14181 9.72402 9.39186C9.47397 9.64191 9.3335 9.98104 9.3335 10.3347C9.3335 10.6883 9.47397 11.0274 9.72402 11.2775C9.97407 11.5275 10.3132 11.668 10.6668 11.668C11.0205 11.668 11.3596 11.5275 11.6096 11.2775C11.8597 11.0274 12.0002 10.6883 12.0002 10.3347ZM14.9948 9.33333C14.7296 9.33333 14.4753 9.43869 14.2877 9.62623C14.1002 9.81376 13.9948 10.0681 13.9948 10.3333C13.9948 10.5985 14.1002 10.8529 14.2877 11.0404C14.4753 11.228 14.7296 11.3333 14.9948 11.3333H21.6668C21.932 11.3333 22.1864 11.228 22.3739 11.0404C22.5615 10.8529 22.6668 10.5985 22.6668 10.3333C22.6668 10.0681 22.5615 9.81376 22.3739 9.62623C22.1864 9.43869 21.932 9.33333 21.6668 9.33333H14.9948ZM13.9948 15.6667C13.9948 16.2187 14.4428 16.6667 14.9948 16.6667H21.6668C21.7982 16.6667 21.9282 16.6408 22.0495 16.5905C22.1708 16.5403 22.2811 16.4666 22.3739 16.3738C22.4668 16.2809 22.5405 16.1707 22.5907 16.0494C22.641 15.928 22.6668 15.798 22.6668 15.6667C22.6668 15.5353 22.641 15.4053 22.5907 15.284C22.5405 15.1627 22.4668 15.0524 22.3739 14.9596C22.2811 14.8667 22.1708 14.793 22.0495 14.7428C21.9282 14.6925 21.7982 14.6667 21.6668 14.6667H14.9948C14.7296 14.6667 14.4753 14.772 14.2877 14.9596C14.1002 15.1471 13.9948 15.4015 13.9948 15.6667ZM12.0002 15.6667C12.0002 15.313 11.8597 14.9739 11.6096 14.7239C11.3596 14.4738 11.0205 14.3333 10.6668 14.3333C10.3132 14.3333 9.97407 14.4738 9.72402 14.7239C9.47397 14.9739 9.3335 15.313 9.3335 15.6667C9.3335 16.0203 9.47397 16.3594 9.72402 16.6095C9.97407 16.8595 10.3132 17 10.6668 17C11.0205 17 11.3596 16.8595 11.6096 16.6095C11.8597 16.3594 12.0002 16.0203 12.0002 15.6667ZM12.0002 20.9973C12.0002 20.6437 11.8597 20.3046 11.6096 20.0545C11.3596 19.8045 11.0205 19.664 10.6668 19.664C10.3132 19.664 9.97407 19.8045 9.72402 20.0545C9.47397 20.3046 9.3335 20.6437 9.3335 20.9973C9.3335 21.351 9.47397 21.6901 9.72402 21.9401C9.97407 22.1902 10.3132 22.3307 10.6668 22.3307C11.0205 22.3307 11.3596 22.1902 11.6096 21.9401C11.8597 21.6901 12.0002 21.351 12.0002 20.9973ZM21.6668 26.9187L27.6268 20.9587C27.7191 20.8632 27.8295 20.7871 27.9515 20.7347C28.0736 20.6824 28.2048 20.6548 28.3376 20.6538C28.4704 20.6527 28.602 20.678 28.7249 20.7284C28.8478 20.7787 28.9594 20.853 29.0532 20.9469C29.1471 21.0409 29.2213 21.1526 29.2715 21.2755C29.3217 21.3984 29.347 21.5301 29.3457 21.6629C29.3445 21.7957 29.3169 21.9269 29.2644 22.0488C29.212 22.1708 29.1357 22.2811 29.0402 22.3733L22.3735 29.04L22.3055 29.1027C22.1136 29.262 21.8692 29.344 21.62 29.3324C21.3709 29.3208 21.1351 29.2165 20.9588 29.04L17.6255 25.7053C17.4381 25.5176 17.3329 25.263 17.3332 24.9977C17.3334 24.7324 17.4391 24.4781 17.6268 24.2907C17.8146 24.1032 18.0691 23.9981 18.3344 23.9983C18.5997 23.9986 18.8541 24.1042 19.0415 24.292L21.6668 26.9187Z" fill="#1E1E1E"/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
public/main-background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

BIN
public/main-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 KiB

BIN
public/sample-1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

BIN
public/sample-2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
public/sample-3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
public/sample-4.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

BIN
public/silancar.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

17
tailwind.config.tsx Normal file
View File

@ -0,0 +1,17 @@
import type { Config } from "tailwindcss"
const config: Config = {
content: ["./app/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}"],
theme: {
extend: {
fontFamily: {
sans: ["var(--font-inter)"],
mono: ["var(--font-mono)"],
heading: ["var(--font-roboto)"],
},
},
},
plugins: [],
}
export default config