feat(dimentorin): audit FE samakan dgn Figma design system

- FIX KRITIS: apps/dimentorin/src/index.css @theme nyimpang dari Figma (67 token beda: primary-500 #1a8ce6 vs #23a1eb, semua warna success/info/warning/danger + skala typography). Disamakan dgn libs/ui (source of truth Figma).
- Hapus hardcoded warna non-token di apps: blue-400, gray-5/6/700, amber/emerald/red-100, green-200/500 -> token primary/neutral/warning/success/danger
- libs/ui: gray-* -> neutral-*, blue-* -> primary-*, #1a8ce6 -> #23a1eb, bg-[#F0F8FF] -> primary-50, SVG fill hex -> fill-* token classes
- Typography: text-[27/26/22/11px] menyimpang dari skala Figma -> text-[29/23/19/12px]
- Radius: rounded-4xl (32px, tidak ada di Figma) -> rounded-3xl (24px)
This commit is contained in:
asepharyana
2026-08-05 19:28:02 +07:00
parent 94f80e4eda
commit 5b50680f14
33 changed files with 149 additions and 149 deletions
+3 -3
View File
@@ -26,10 +26,10 @@ type TButtonProps = DetailedHTMLProps<
const variantClasses: Record<TButtonVariant, string> = {
primary: 'bg-primary-500 hover:bg-primary-600 text-white shadow-md',
secondary:
'bg-white hover:text-primary-600 hover:bg-gray-50 text-primary-500 shadow-md',
text: 'bg-transparent hover:text-primary-600 hover:bg-gray-50 text-primary-500',
'bg-white hover:text-primary-600 hover:bg-neutral-50 text-primary-500 shadow-md',
text: 'bg-transparent hover:text-primary-600 hover:bg-neutral-50 text-primary-500',
bordered:
'border border-primary-500 hover:border-primary-600 bg-transparent hover:text-primary-600 hover:bg-gray-50 text-primary-500',
'border border-primary-500 hover:border-primary-600 bg-transparent hover:text-primary-600 hover:bg-neutral-50 text-primary-500',
success: 'bg-success-500 hover:bg-success-600 text-white shadow-md',
danger: 'bg-danger-100 hover:bg-danger-200 text-danger-500 shadow-md',
};
+1 -1
View File
@@ -49,7 +49,7 @@ export const Input: FC<TInputProps> = ({
};
const mergedClassName = cn(
`px-[12px] py-[8px] text-neutral-800 bg-white placeholder:text-neutral-300 border border-neutral-200 hover:border-blue-300 focus:outline-1 focus:outline-blue-500 rounded-md font-bai-jamjuree ${widthform === "standard" ? "min-w-70" : ""}`,
`px-[12px] py-[8px] text-neutral-800 bg-white placeholder:text-neutral-300 border border-neutral-200 hover:border-primary-300 focus:outline-1 focus:outline-primary-500 rounded-md font-bai-jamjuree ${widthform === "standard" ? "min-w-70" : ""}`,
sizeClasses[size].textSize,
disabled && disabledClass,
className
+1 -1
View File
@@ -35,7 +35,7 @@ export const Select: FC<TSelectProps> = ({
...rest
}): ReactElement => {
const mergedClassName = cn(
`appearance-none px-[12px] py-[8px] text-neutral-800 bg-white placeholder:text-neutral-300 border border-neutral-200 hover:border-blue-300 focus:outline-1 focus:outline-blue-500 rounded-md`,
`appearance-none px-[12px] py-[8px] text-neutral-800 bg-white placeholder:text-neutral-300 border border-neutral-200 hover:border-primary-300 focus:outline-1 focus:outline-primary-500 rounded-md`,
sizeClasses[size],
widthform === 'standard' && 'min-w-70',
disabled && disabledClass,
+1 -1
View File
@@ -38,7 +38,7 @@ export const Textarea: FC<TTextareaProps> = ({
...rest
}): ReactElement => {
const mergedClassName = cn(
'rounded-md border border-neutral-200 hover:border-blue-300 focus:outline-1 focus:outline-blue-500 px-[12px] py-[8px] invalid:border-danger-500 invalid:text-danger-500',
'rounded-md border border-neutral-200 hover:border-primary-300 focus:outline-1 focus:outline-primary-500 px-[12px] py-[8px] invalid:border-danger-500 invalid:text-danger-500',
sizeClasses[size],
disabled && disabledClass,
error && errorClass,
@@ -15,15 +15,15 @@ export const ForgotStep: FC<TForgotStepProps> = ({
<div className="w-full grid grid-cols-3 gap-3">
<div className="flex flex-col items-center justify-center gap-2">
<div className={`${step === 1 ? "bg-primary-500" : "bg-primary-200"} px-5 py-2 rounded-md w-full`}></div>
<h4 className={`${step === 1 ? "text-primary-500" : "text-gray-500"} text-xs`}>Masukkan Email</h4>
<h4 className={`${step === 1 ? "text-primary-500" : "text-neutral-500"} text-xs`}>Masukkan Email</h4>
</div>
<div className="flex flex-col items-center justify-center gap-2">
<div className={`${step === 2 ? "bg-primary-500" : "bg-primary-200"} px-5 py-2 rounded-md w-full`}></div>
<h4 className={`${step === 2 ? "text-primary-500" : "text-gray-500"} text-xs`}>Verifikasi OTP</h4>
<h4 className={`${step === 2 ? "text-primary-500" : "text-neutral-500"} text-xs`}>Verifikasi OTP</h4>
</div>
<div className="flex flex-col items-center justify-center gap-2">
<div className={`${step === 3 ? "bg-primary-500" : "bg-primary-200"} px-5 py-2 rounded-md w-full`}></div>
<h4 className={`${step === 3 ? "text-primary-500" : "text-gray-500"} text-xs`}>Summon Password ^^</h4>
<h4 className={`${step === 3 ? "text-primary-500" : "text-neutral-500"} text-xs`}>Summon Password ^^</h4>
</div>
</div>
)
+3 -3
View File
@@ -66,7 +66,7 @@ const Modal = ({
<div className="fixed inset-0 z-50">
<div
className={cn(
'fixed inset-0 bg-gray-900/80 transition-opacity duration-200',
'fixed inset-0 bg-neutral-900/80 transition-opacity duration-200',
isOpen ? 'opacity-100' : 'opacity-0',
overlayClassName
)}
@@ -90,7 +90,7 @@ const Modal = ({
<button
onClick={onClose}
className={cn(
'absolute right-4 top-4 rounded-sm p-1 text-gray-500 transition-colors hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-950 focus:ring-offset-2',
'absolute right-4 top-4 rounded-sm p-1 text-neutral-500 transition-colors hover:text-neutral-900 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2',
closeButtonClassName
)}
aria-label="Close modal"
@@ -168,7 +168,7 @@ const ModalDescription = ({
children,
id,
}: ModalDescriptionProps) => (
<p id={id} className={cn('text-sm text-gray-500', className)}>
<p id={id} className={cn('text-sm text-neutral-500', className)}>
{children}
</p>
);
@@ -40,7 +40,7 @@ export const Default: Story = {
<button className="px-4 py-2 bg-blue-500 text-white rounded">
Confirm
</button>
<button className="px-4 py-2 bg-gray-300 rounded">Cancel</button>
<button className="px-4 py-2 bg-neutral-300 rounded">Cancel</button>
</Modal.Footer>
</>
),
+4 -4
View File
@@ -66,7 +66,7 @@ const Modal = ({
<div className="fixed inset-0 z-50">
<div
className={cn(
'fixed inset-0 bg-gray-900/80 transition-opacity duration-200',
'fixed inset-0 bg-neutral-900/80 transition-opacity duration-200',
isOpen ? 'opacity-100' : 'opacity-0',
overlayClassName
)}
@@ -75,7 +75,7 @@ const Modal = ({
/>
<div
className={cn(
'fixed left-[50%] top-[50%] z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 bg-[#F0F8FF] rounded-lg p-6 shadow-xl transition-all duration-200',
'fixed left-[50%] top-[50%] z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2 bg-primary-50 rounded-lg p-6 shadow-xl transition-all duration-200',
'sm:rounded-lg sm:max-w-md',
isOpen ? 'opacity-100 scale-100' : 'opacity-0 scale-95',
className
@@ -90,7 +90,7 @@ const Modal = ({
<button
onClick={onClose}
className={cn(
'absolute right-4 top-4 rounded-sm p-1 text-gray-500 transition-colors hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-950 focus:ring-offset-2',
'absolute right-4 top-4 rounded-sm p-1 text-neutral-500 transition-colors hover:text-neutral-900 focus:outline-none focus:ring-2 focus:ring-neutral-950 focus:ring-offset-2',
closeButtonClassName
)}
aria-label="Close modal"
@@ -168,7 +168,7 @@ const ModalDescription = ({
children,
id,
}: ModalDescriptionProps) => (
<p id={id} className={cn('text-sm text-gray-500', className)}>
<p id={id} className={cn('text-sm text-neutral-500', className)}>
{children}
</p>
);
@@ -17,7 +17,7 @@ export const RegisterMentorStep: FC<TRegisterMentorStep> = ({ step }): ReactElem
return (
<div className="relative w-full px-8">
{/* Garis dasar (abu/biru muda) */}
<div className="absolute top-5 left-8 right-8 h-0.5 bg-blue-100 z-0" />
<div className="absolute top-5 left-8 right-8 h-0.5 bg-primary-100 z-0" />
{/* Garis progress biru (dinamis) */}
<div
@@ -37,7 +37,7 @@ export const RegisterMentorStep: FC<TRegisterMentorStep> = ({ step }): ReactElem
className={`w-10 h-10 rounded-full flex items-center justify-center border-2 ${
isActive
? "bg-gradient-to-b from-purple-600 to-blue-500 text-white border-transparent"
: "bg-white text-gray-700 border-blue-400"
: "bg-white text-neutral-700 border-blue-400"
}`}
>
<span className="font-bold">{currentStep}</span>
@@ -29,7 +29,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/dashboard')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<AppstoreOutlined className="text-[20px]" />
@@ -41,7 +41,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/gacha-roll')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<ReloadOutlined className="text-[20px]" />
@@ -53,7 +53,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/permissions')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<UserSwitchOutlined className="text-[20px]" />
@@ -65,7 +65,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/roles')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<UsergroupAddOutlined className="text-[20px]" />
@@ -77,7 +77,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/accounts')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<UserOutlined className="text-[20px]" />
@@ -89,7 +89,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/transactions')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<AuditOutlined className="text-[20px]" />
@@ -101,7 +101,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
className={`flex items-center justify-items-start gap-3 px-[8px] py-[10px] ${
isActive('/prizes')
? 'bg-primary-500 text-white rounded-md'
: 'text-gray-700 hover:bg-gray-100'
: 'text-neutral-700 hover:bg-neutral-100'
}`}
>
<InboxOutlined className="text-[20px]" />
@@ -115,7 +115,7 @@ export const BackofficeSidebar: FC = (): ReactElement => {
<Button
onClick={signOut}
variant="text"
className="items-start justify-start gap-3 px-[8px] py-[10px] text-gray-700 hover:text-red-500 transition-colors w-full"
className="items-start justify-start gap-3 px-[8px] py-[10px] text-neutral-700 hover:text-danger-500 transition-colors w-full"
>
<LogoutOutlined className="text-[20px]" />
<span className="text-p3 font-medium">Log Out</span>
+2 -2
View File
@@ -30,9 +30,9 @@ const Radio = ({
checked={checked}
onChange={onChange}
disabled={disabled}
className="peer col-start-1 row-start-1 appearance-none shrink-0 size-[10px] bg-primary-100 rounded-full disabled:border-gray-400"
className="peer col-start-1 row-start-1 appearance-none shrink-0 size-[10px] bg-primary-100 rounded-full disabled:border-neutral-400"
/>
<div className="pointer-events-none col-start-1 row-start-1 size-[6px] rounded-full peer-checked:bg-primary-500 peer-checked:peer-disabled:bg-gray-400" />
<div className="pointer-events-none col-start-1 row-start-1 size-[6px] rounded-full peer-checked:bg-primary-500 peer-checked:peer-disabled:bg-neutral-400" />
</div>
<label htmlFor={id} className="text-start text-neutral-400 text-label2">
{label || 'This is the radio label'}
@@ -9,7 +9,7 @@ const meta: Meta<typeof Navbar> = {
decorators: [
(Story) => (
<BrowserRouter>
<div className="min-h-screen bg-gray-100 p-4">
<div className="min-h-screen bg-neutral-100 p-4">
<Story />
</div>
</BrowserRouter>
+8 -8
View File
@@ -38,7 +38,7 @@ export const Navbar: FC = (): ReactElement => {
<Button
size="md"
variant="text"
className="lg:text-p2 lg:max-h-[44px] text-gray-600 hover:text-gray-700 transition-colors"
className="lg:text-p2 lg:max-h-[44px] text-neutral-600 hover:text-neutral-700 transition-colors"
>
<Link to="#">Merch Gacha</Link>
</Button>
@@ -56,7 +56,7 @@ export const Navbar: FC = (): ReactElement => {
onClick={signOut}
variant="text"
size="md"
className="lg:text-p2 text-red-500 font-bold hover:text-red-600"
className="lg:text-p2 text-danger-500 font-bold hover:text-danger-600"
>
Logout
</Button>
@@ -69,12 +69,12 @@ export const Navbar: FC = (): ReactElement => {
}`}
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
>
<MenuOutlined style={{ color: '#1a8ce6' }} />
<MenuOutlined style={{ color: '#23a1eb' }} />
</button>
<div className="relative">
{isDropdownOpen && (
<div className="absolute right-0 top-0 mt-5">
<ul className="mt-2 w-48 bg-white shadow-md border rounded-[16px] border-gray-200 px-5 py-3">
<ul className="mt-2 w-48 bg-white shadow-md border rounded-2xl border-neutral-200 px-5 py-3">
<li>
<Link
to="#"
@@ -86,7 +86,7 @@ export const Navbar: FC = (): ReactElement => {
<li>
<Link
to="#"
className="block text-gray-600 transition-colors px-4 py-2 text-center font-semibold"
className="block text-neutral-600 transition-colors px-4 py-2 text-center font-semibold"
>
Merch Gacha
</Link>
@@ -95,20 +95,20 @@ export const Navbar: FC = (): ReactElement => {
<li>
<Button
onClick={() => setShowModalLogin(true)}
className="block w-full text-gray-100 transition-colors px-4 py-2 text-center font-semibold"
className="block w-full text-neutral-100 transition-colors px-4 py-2 text-center font-semibold"
>
Login
</Button>
</li>
) : (
<>
<li className="px-4 py-2 text-center text-gray-600 font-semibold">
<li className="px-4 py-2 text-center text-neutral-600 font-semibold">
{session?.user?.fullname}
</li>
<li>
<div
onClick={signOut}
className="block text-red-500 font-bold transition-colors px-4 py-2 text-center cursor-pointer"
className="block text-danger-500 font-bold transition-colors px-4 py-2 text-center cursor-pointer"
>
Logout
</div>