revamp template

This commit is contained in:
fro1991
2025-02-01 16:44:51 +07:00
parent c432df568a
commit 276a289580
1212 changed files with 112762 additions and 0 deletions

View File

@ -0,0 +1,43 @@
import clsx from 'clsx';
import { KeenIcon } from '@/components';
import { toAbsoluteUrl } from '@/utils/Assets';
interface IAvatarProps {
image?: string;
fallback?: string;
icon?: string;
iconClass?: string;
badgeClass?: string;
className?: string;
imageClass?: string;
}
const CommonAvatar = ({
image,
fallback,
icon,
iconClass,
badgeClass,
className,
imageClass
}: IAvatarProps) => {
return (
<div className={clsx(className && className)}>
{image && (
<img
src={toAbsoluteUrl(`/media/avatars/${image}`)}
className={clsx(imageClass && imageClass)}
alt=""
/>
)}
{!image && fallback && fallback}
{!image && !fallback && icon && (
<KeenIcon icon={icon} className={clsx(iconClass && iconClass)} />
)}
{badgeClass && <div className={clsx(badgeClass && badgeClass)}></div>}
</div>
);
};
export { CommonAvatar, type IAvatarProps };

View File

@ -0,0 +1,70 @@
import clsx from 'clsx';
import { toAbsoluteUrl } from '@/utils/Assets';
interface IAvatarsItem {
path?: string;
filename?: string;
fallback?: string;
variant?: string;
}
interface IAvatarsItems extends Array<IAvatarsItem> {}
interface IAvatarsProps {
size?: string;
group: IAvatarsItem[];
more?: { variant?: string; number?: number | string; label?: string };
className?: string;
}
const CommonAvatars = ({ size, group, more, className }: IAvatarsProps) => {
const avatarSize = size ? size : 'size-6';
const renderItem = (each: IAvatarsItem, index: number) => {
return (
<div key={index} className="flex">
{each.filename || each.path ? (
<img
src={toAbsoluteUrl(each.path || `/media/avatars/${each.filename}`)}
className={clsx(
`hover:z-5 relative shrink-0 rounded-full ring-1 ring-light-light ${avatarSize}`
)}
alt=""
/>
) : each.fallback ? (
<span
className={clsx(
`hover:z-5 relative inline-flex items-center justify-center shrink-0 rounded-full ring-1 font-semibold leading-none text-3xs ${avatarSize}`,
each.variant
)}
>
{each.fallback}
</span>
) : null}
</div>
);
};
return (
<div className={clsx('flex -space-x-2', className && className)}>
{group.map((each, index) => {
return renderItem(each, index);
})}
{more && (
<div className="flex">
<span
className={clsx(
`relative inline-flex items-center justify-center shrink-0 rounded-full ring-1 font-semibold leading-none text-3xs ${size} size-6`,
more.variant
)}
>
+{more.number || more.label}
</span>
</div>
)}
</div>
);
};
export { CommonAvatars, type IAvatarsItem, type IAvatarsItems, type IAvatarsProps };

View File

@ -0,0 +1,42 @@
import { ReactNode } from 'react';
interface IHexagonBadgeProps {
size?: string;
stroke?: string;
fill?: string;
badge?: ReactNode;
}
const CommonHexagonBadge = ({ size, stroke, fill, badge }: IHexagonBadgeProps) => {
return (
<div className={`relative ${size} shrink-0`}>
<svg
className={`w-full h-full ${stroke} ${fill}`}
width="44"
height="48"
viewBox="0 0 44 48"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 2.4641C19.7128 0.320509 24.2872 0.320508 28 2.4641L37.6506 8.0359C41.3634 10.1795 43.6506 14.141 43.6506
18.4282V29.5718C43.6506 33.859 41.3634 37.8205 37.6506 39.9641L28 45.5359C24.2872 47.6795 19.7128 47.6795 16 45.5359L6.34937
39.9641C2.63655 37.8205 0.349365 33.859 0.349365 29.5718V18.4282C0.349365 14.141 2.63655 10.1795 6.34937 8.0359L16 2.4641Z"
fill=""
/>
<path
d="M16.25 2.89711C19.8081 0.842838 24.1919 0.842837 27.75 2.89711L37.4006 8.46891C40.9587 10.5232 43.1506 14.3196 43.1506
18.4282V29.5718C43.1506 33.6804 40.9587 37.4768 37.4006 39.5311L27.75 45.1029C24.1919 47.1572 19.8081 47.1572 16.25 45.1029L6.59937
39.5311C3.04125 37.4768 0.849365 33.6803 0.849365 29.5718V18.4282C0.849365 14.3196 3.04125 10.5232 6.59937 8.46891L16.25 2.89711Z"
stroke=""
/>
</svg>
<div className="absolute leading-none start-2/4 top-2/4 -translate-y-2/4 -translate-x-2/4 rtl:translate-x-2/4">
{badge}
</div>
</div>
);
};
export { CommonHexagonBadge, type IHexagonBadgeProps };

View File

@ -0,0 +1,36 @@
import clsx from 'clsx';
interface IRatingProps {
className?: string;
rating: number;
round?: number;
}
const CommonRating = ({ className, rating, round }: IRatingProps) => {
return (
<div className={clsx('rating', className && className)}>
{[...Array(5)].map((_, index) => (
<div
key={index}
className={clsx(
'rating-label',
index < rating ? 'checked' : '',
index === rating && round ? 'indeterminate' : ''
)}
>
{index === rating && round ? (
<i
className="rating-on ki-solid ki-star text-base leading-none"
style={{ width: `${round * 100}%` }}
></i>
) : (
<i className="rating-on ki-solid ki-star text-base leading-none"></i>
)}
<i className="rating-off ki-outline ki-star text-base leading-none"></i>
</div>
))}
</div>
);
};
export { CommonRating, type IRatingProps };

View File

@ -0,0 +1,4 @@
export * from './CommonAvatar';
export * from './CommonAvatars';
export * from './CommonRating';
export * from './CommonHexagonBadge';