Extract admin dashboard from ghabilee-frontend2 into a dedicated Next.js app for backoffice.ghabilee.ir (no SEO indexing / Clarity).
183 lines
4.5 KiB
TypeScript
183 lines
4.5 KiB
TypeScript
import type { ReactNode, SVGProps } from 'react'
|
|
|
|
type IconProps = SVGProps<SVGSVGElement>
|
|
|
|
const baseProps = (className?: string): IconProps => ({
|
|
className,
|
|
fill: 'none',
|
|
height: 24,
|
|
viewBox: '0 0 24 24',
|
|
width: 24,
|
|
xmlns: 'http://www.w3.org/2000/svg',
|
|
'aria-hidden': true,
|
|
})
|
|
|
|
const InstagramChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<rect
|
|
fill="currentColor"
|
|
height="18"
|
|
opacity="0.15"
|
|
rx="5"
|
|
width="18"
|
|
x="3"
|
|
y="3"
|
|
/>
|
|
<rect
|
|
height="14"
|
|
rx="4"
|
|
stroke="currentColor"
|
|
strokeWidth="1.75"
|
|
width="14"
|
|
x="5"
|
|
y="5"
|
|
/>
|
|
<circle
|
|
cx="12"
|
|
cy="12"
|
|
r="3.25"
|
|
stroke="currentColor"
|
|
strokeWidth="1.75"
|
|
/>
|
|
<circle
|
|
cx="16.35"
|
|
cy="7.65"
|
|
fill="currentColor"
|
|
r="1"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const TelegramChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<circle
|
|
cx="12"
|
|
cy="12"
|
|
fill="currentColor"
|
|
opacity="0.15"
|
|
r="9"
|
|
/>
|
|
<path
|
|
d="M7.2 11.9 16.4 7.8c.45-.2.9.12.74.74l-1.7 8.05c-.12.55-.55.68-.98.42l-2.45-1.8-1.18 1.14c-.13.13-.24.24-.49.24l.18-2.55 4.62-4.17c.2-.18-.04-.28-.3-.1l-5.7 3.6-2.46-.77c-.53-.16-.54-.53.12-.8Z"
|
|
fill="currentColor"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const TwitterChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<circle
|
|
cx="12"
|
|
cy="12"
|
|
fill="currentColor"
|
|
opacity="0.15"
|
|
r="9"
|
|
/>
|
|
<path
|
|
d="M7 7.5h2.35l2.3 3.2L14.3 7.5H17l-3.55 4.2L17 16.5h-2.35l-2.5-3.45L9.4 16.5H7l3.75-4.45L7 7.5Z"
|
|
fill="currentColor"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const LinkedinChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<rect
|
|
fill="currentColor"
|
|
height="18"
|
|
opacity="0.15"
|
|
rx="4"
|
|
width="18"
|
|
x="3"
|
|
y="3"
|
|
/>
|
|
<path
|
|
d="M8.2 10.2v6.1H6.1v-6.1h2.1Zm.15-2.15c0 .6-.5 1.1-1.2 1.1s-1.2-.5-1.2-1.1.5-1.1 1.2-1.1 1.2.5 1.2 1.1ZM17.9 16.3h-2.1v-3.2c0-.9-.35-1.5-1.2-1.5-.65 0-1.05.45-1.2.85-.07.15-.05.4-.05.6v3.25h-2.1s.03-5.3 0-5.85h2.1v.85c.3-.45.8-1.1 1.95-1.1 1.4 0 2.45.95 2.45 2.95v3.15Z"
|
|
fill="currentColor"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const YoutubeChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<rect
|
|
fill="currentColor"
|
|
height="14"
|
|
opacity="0.15"
|
|
rx="4"
|
|
width="18"
|
|
x="3"
|
|
y="5"
|
|
/>
|
|
<path
|
|
d="M17.6 8.2c.3.8.4 2.1.4 3.8s-.1 3-.4 3.8c-.2.55-.7.9-1.25 1.05-1.1.25-5.35.25-5.35.25s-4.25 0-5.35-.25A1.7 1.7 0 0 1 4.4 15.8C4.1 15 4 13.7 4 12s.1-3 .4-3.8c.2-.55.7-.9 1.25-1.05C6.75 6.9 11 6.9 11 6.9s4.25 0 5.35.25c.55.15 1.05.5 1.25 1.05ZM10.4 14.35 14.1 12l-3.7-2.35v4.7Z"
|
|
fill="currentColor"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const WebsiteChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<circle
|
|
cx="12"
|
|
cy="12"
|
|
fill="currentColor"
|
|
opacity="0.15"
|
|
r="9"
|
|
/>
|
|
<circle
|
|
cx="12"
|
|
cy="12"
|
|
r="7"
|
|
stroke="currentColor"
|
|
strokeWidth="1.75"
|
|
/>
|
|
<path
|
|
d="M5 12h14M12 5c1.8 2 2.7 4.3 2.7 7s-.9 5-2.7 7c-1.8-2-2.7-4.3-2.7-7s.9-5 2.7-7Z"
|
|
stroke="currentColor"
|
|
strokeWidth="1.75"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const SupportPhoneChannelIcon = ({ className }: { className?: string }) => (
|
|
<svg {...baseProps(className)}>
|
|
<rect
|
|
fill="currentColor"
|
|
height="18"
|
|
opacity="0.15"
|
|
rx="4"
|
|
width="14"
|
|
x="5"
|
|
y="3"
|
|
/>
|
|
<path
|
|
d="M15.2 3.8H8.8c-1.9 0-2.6.7-2.6 2.6v11.2c0 1.9.7 2.6 2.6 2.6h6.4c1.9 0 2.6-.7 2.6-2.6V6.4c0-1.9-.7-2.6-2.6-2.6Zm-3.2 14.3a1.05 1.05 0 1 1 0-2.1 1.05 1.05 0 0 1 0 2.1Zm2.2-11.6H9.8a.7.7 0 0 1 0-1.4h4.4a.7.7 0 0 1 0 1.4Z"
|
|
fill="currentColor"
|
|
/>
|
|
</svg>
|
|
)
|
|
|
|
const CHANNEL_ICONS: Record<string, (props: { className?: string }) => ReactNode> = {
|
|
instagram: InstagramChannelIcon,
|
|
telegram: TelegramChannelIcon,
|
|
twitter: TwitterChannelIcon,
|
|
linkedin: LinkedinChannelIcon,
|
|
youtube: YoutubeChannelIcon,
|
|
website: WebsiteChannelIcon,
|
|
support_phone: SupportPhoneChannelIcon,
|
|
}
|
|
|
|
interface ContactChannelIconProps {
|
|
channel: string
|
|
className?: string
|
|
}
|
|
|
|
const ContactChannelIcon = ({ channel, className = 'size-6 text-primary' }: ContactChannelIconProps) => {
|
|
const Icon = CHANNEL_ICONS[channel] ?? WebsiteChannelIcon
|
|
|
|
return <Icon className={className} />
|
|
}
|
|
|
|
export default ContactChannelIcon
|