feat: add NotificationIcon component and update admin layout for improved UI
This commit is contained in:
parent
15f8dbb8e2
commit
661baca101
38
app/components/icons/notification.tsx
Normal file
38
app/components/icons/notification.tsx
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import type { JSX, SVGProps } from 'react'
|
||||||
|
|
||||||
|
interface NotificationIconProperties
|
||||||
|
extends JSX.IntrinsicAttributes,
|
||||||
|
SVGProps<SVGSVGElement> {
|
||||||
|
showBadge?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export const NotificationIcon = ({
|
||||||
|
showBadge = false,
|
||||||
|
...properties
|
||||||
|
}: NotificationIconProperties) => {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={16}
|
||||||
|
height={19}
|
||||||
|
viewBox="0 0 16 19"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
{...properties}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M6.597 18.53a1.616 1.616 0 01-1.608-1.6h3.2c.001.213-.04.425-.12.623-.21.482-.639.833-1.152.944h-.038c-.093.02-.187.03-.282.032zm6.4-2.4H.197v-1.6l1.6-.8v-4.4a6.452 6.452 0 01.739-3.249 3.723 3.723 0 012.46-1.808V2.53h3.2v1.744c2.064.492 3.2 2.287 3.2 5.056v4.4l1.6.8v1.6z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
{showBadge && (
|
||||||
|
<circle
|
||||||
|
cx={11.1968}
|
||||||
|
cy={4.306_64}
|
||||||
|
r={3.6}
|
||||||
|
fill="#EC5252"
|
||||||
|
stroke="#fff"
|
||||||
|
strokeWidth={1.2}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import { APP } from '~/data/meta'
|
|||||||
|
|
||||||
export default function PopupSuccesRegister() {
|
export default function PopupSuccesRegister() {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center">
|
<div className="flex min-h-dvh items-center justify-center">
|
||||||
<div className="w-full max-w-md p-6">
|
<div className="w-full max-w-md p-6">
|
||||||
<div className="absolute top-[80px] left-[50px]">
|
<div className="absolute top-[80px] left-[50px]">
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { APP } from '~/data/meta'
|
|||||||
|
|
||||||
export default function PopupSuccessResetPass() {
|
export default function PopupSuccessResetPass() {
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen items-center justify-center">
|
<div className="flex min-h-dvh items-center justify-center">
|
||||||
<div className="w-full max-w-md p-6">
|
<div className="w-full max-w-md p-6">
|
||||||
<div className="absolute top-[80px] left-[50px]">
|
<div className="absolute top-[80px] left-[50px]">
|
||||||
<Link
|
<Link
|
||||||
|
|||||||
@ -6,11 +6,11 @@ import { Sidebar } from './sidebar'
|
|||||||
export const AdminDashboardLayout = (properties: PropsWithChildren) => {
|
export const AdminDashboardLayout = (properties: PropsWithChildren) => {
|
||||||
const { children } = properties
|
const { children } = properties
|
||||||
return (
|
return (
|
||||||
<div className="grid">
|
<div className="flex flex-col">
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
<div>{children}</div>
|
<div className="min-h-[calc(100dvh-80px)] flex-1">{children}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -1,3 +1,27 @@
|
|||||||
|
import { Link } from 'react-router'
|
||||||
|
|
||||||
|
import { NotificationIcon } from '~/components/icons/notification'
|
||||||
|
import { APP } from '~/data/meta'
|
||||||
|
|
||||||
export const Navbar = () => {
|
export const Navbar = () => {
|
||||||
return <div>Navbar</div>
|
return (
|
||||||
|
<div className="flex h-20 items-center justify-between border-b border-[#ECECEC] bg-white px-10 py-5">
|
||||||
|
<Link
|
||||||
|
to="/news"
|
||||||
|
className="h-full"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={APP.logo}
|
||||||
|
alt={APP.title}
|
||||||
|
className="h-3/4 w-auto sm:h-full"
|
||||||
|
/>
|
||||||
|
</Link>
|
||||||
|
<div>
|
||||||
|
<NotificationIcon
|
||||||
|
className="text-[#B0C3CC]"
|
||||||
|
showBadge={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +1,11 @@
|
|||||||
import { Link } from 'react-router'
|
import { NavLink } from 'react-router'
|
||||||
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
import { MENU } from './menu'
|
import { MENU } from './menu'
|
||||||
|
|
||||||
export const Sidebar = () => {
|
export const Sidebar = () => {
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-y-10 p-5">
|
<div className="flex min-h-[calc(100dvh-80px)] flex-col gap-y-10 overflow-y-auto bg-white p-5">
|
||||||
{MENU.map(({ group, items }) => (
|
{MENU.map(({ group, items }) => (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div
|
<div
|
||||||
@ -14,16 +15,35 @@ export const Sidebar = () => {
|
|||||||
{group}
|
{group}
|
||||||
</div>
|
</div>
|
||||||
{items.map(({ title, url, icon: Icon }) => (
|
{items.map(({ title, url, icon: Icon }) => (
|
||||||
<Link
|
<NavLink
|
||||||
to={url}
|
to={url}
|
||||||
key={`${group}-${title}`}
|
key={`${group}-${title}`}
|
||||||
className="group/menu hover:bg-opacity-10 flex h-[42px] w-[200px] items-center gap-x-3 rounded-md px-5 transition-all hover:bg-[#707FDD]/10 hover:font-bold hover:text-[#5363AB]"
|
className={({ isActive }) =>
|
||||||
|
twMerge(
|
||||||
|
isActive ? 'bg-[#707FDD]/10 font-bold' : '',
|
||||||
|
'group/menu flex h-[42px] w-[200px] items-center gap-x-3 rounded-md px-5 transition-all hover:bg-[#707FDD]/10',
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<Icon className="h-[18px] w-[18px] text-[#A6ABC8] transition-all group-hover/menu:text-[#5363AB]" />
|
{({ isActive }) => (
|
||||||
<span className="text-[#273240] transition-all group-hover/menu:text-[#5363AB]">
|
<>
|
||||||
{title}
|
<Icon
|
||||||
</span>
|
className={twMerge(
|
||||||
</Link>
|
isActive ? 'text-[#5363AB]' : 'text-[#A6ABC8]',
|
||||||
|
'h-[18px] w-[18px] transition-all group-hover/menu:text-[#5363AB]',
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className={twMerge(
|
||||||
|
isActive ? 'text-[#5363AB]' : 'text-[#273240]',
|
||||||
|
'transition-all group-hover/menu:text-[#5363AB]',
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{title}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</NavLink>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -1,10 +1,4 @@
|
|||||||
const DashboardIndexLayout = () => {
|
const DashboardIndexLayout = () => {
|
||||||
return (
|
return <div className="flex items-center justify-center">Dashboard Page</div>
|
||||||
<div className="relative">
|
|
||||||
<div className="flex min-h-screen items-center justify-center bg-gray-100">
|
|
||||||
Dashboard Page
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
export default DashboardIndexLayout
|
export default DashboardIndexLayout
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user