refactor: migrate from hardcoded hex colors to Tailwind CSS color tokens
Replace all hardcoded hex color values with semantic Tailwind design tokens: - `#bb5b3e` → `accent` - `#a34a31` → `accent-content` / `primary-dark` - `#4a3f3b`, `#89726c` → `zinc-800`, `zinc-500` - `#e5ded7`, `#faf6f3` → `zinc-300`, `zinc-50` - `#8
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="space-y-6 max-w-lg">
|
||||
<div class="p-6 bg-white rounded-2xl border border-[#e5ded7] space-y-5">
|
||||
<h2 class="text-lg font-black text-[#4a3f3b]">Appearance</h2>
|
||||
<p class="text-sm text-[#89726c]">Choose how FuelAlert looks to you.</p>
|
||||
<div class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-5">
|
||||
<h2 class="text-lg font-black text-zinc-800">Appearance</h2>
|
||||
<p class="text-sm text-zinc-500">Choose how FuelAlert looks to you.</p>
|
||||
|
||||
<div class="grid grid-cols-3 gap-3">
|
||||
<button
|
||||
@@ -11,15 +11,15 @@
|
||||
@click="setTheme(option.value)"
|
||||
class="flex flex-col items-center gap-3 p-4 rounded-2xl border-2 transition-all"
|
||||
:class="selectedTheme === option.value
|
||||
? 'border-[#bb5b3e] bg-[#faf6f3]'
|
||||
: 'border-[#e5ded7] hover:border-[#89726c]'"
|
||||
? 'border-accent bg-zinc-50'
|
||||
: 'border-zinc-300 hover:border-zinc-500'"
|
||||
>
|
||||
<iconify-icon :icon="option.icon" class="text-2xl text-[#bb5b3e]"></iconify-icon>
|
||||
<span class="text-sm font-bold text-[#4a3f3b]">{{ option.label }}</span>
|
||||
<iconify-icon :icon="option.icon" class="text-2xl text-accent"></iconify-icon>
|
||||
<span class="text-sm font-bold text-zinc-800">{{ option.label }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<p class="text-xs text-[#89726c]">
|
||||
<p class="text-xs text-zinc-500">
|
||||
Current: <span class="font-bold capitalize">{{ selectedTheme }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
<template>
|
||||
<div class="space-y-6 max-w-lg">
|
||||
<!-- Profile form -->
|
||||
<form @submit.prevent="saveProfile" class="p-6 bg-white rounded-2xl border border-[#e5ded7] space-y-5">
|
||||
<h2 class="text-lg font-black text-[#4a3f3b]">Profile information</h2>
|
||||
<form class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-5" @submit.prevent="saveProfile">
|
||||
<h2 class="text-lg font-black text-zinc-800">Profile information</h2>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">Full name</label>
|
||||
<label class="text-sm font-bold text-zinc-800">Full name</label>
|
||||
<input
|
||||
v-model="profileForm.name"
|
||||
type="text"
|
||||
class="w-full h-12 px-4 bg-[#faf6f3] border rounded-xl font-medium text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e]"
|
||||
:class="profileErrors.name ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="profileErrors.name ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
<p v-if="profileErrors.name" class="text-xs text-red-600">{{ profileErrors.name[0] }}</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">Email address</label>
|
||||
<label class="text-sm font-bold text-zinc-800">Email address</label>
|
||||
<input
|
||||
v-model="profileForm.email"
|
||||
type="email"
|
||||
class="w-full h-12 px-4 bg-[#faf6f3] border rounded-xl font-medium text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e]"
|
||||
:class="profileErrors.email ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="profileErrors.email ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
<p v-if="profileErrors.email" class="text-xs text-red-600">{{ profileErrors.email[0] }}</p>
|
||||
</div>
|
||||
@@ -32,7 +32,7 @@
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="profileSaving"
|
||||
class="px-8 py-3 bg-[#bb5b3e] text-white rounded-xl font-bold hover:bg-[#a34a31] transition-all disabled:opacity-50"
|
||||
class="px-8 py-3 bg-accent text-white rounded-xl font-bold hover:bg-accent-content transition-all disabled:opacity-50"
|
||||
>
|
||||
{{ profileSaving ? 'Saving…' : 'Save changes' }}
|
||||
</button>
|
||||
@@ -41,9 +41,9 @@
|
||||
</form>
|
||||
|
||||
<!-- Delete account -->
|
||||
<div class="p-6 bg-white rounded-2xl border border-[#e5ded7] space-y-4">
|
||||
<h2 class="text-lg font-black text-[#4a3f3b]">Delete account</h2>
|
||||
<p class="text-sm text-[#89726c]">Permanently delete your account and all associated data. This cannot be undone.</p>
|
||||
<div class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-4">
|
||||
<h2 class="text-lg font-black text-zinc-800">Delete account</h2>
|
||||
<p class="text-sm text-zinc-500">Permanently delete your account and all associated data. This cannot be undone.</p>
|
||||
<button
|
||||
@click="deleteModalOpen = true"
|
||||
class="px-6 py-2.5 bg-red-600 text-white rounded-xl text-sm font-bold hover:bg-red-700 transition-colors"
|
||||
@@ -59,16 +59,16 @@
|
||||
@click.self="closeDeleteModal"
|
||||
>
|
||||
<div class="bg-white rounded-2xl p-6 w-full max-w-md mx-4 space-y-5">
|
||||
<h3 class="text-lg font-black text-[#4a3f3b]">Are you sure?</h3>
|
||||
<p class="text-sm text-[#89726c]">Enter your password to confirm account deletion.</p>
|
||||
<h3 class="text-lg font-black text-zinc-800">Are you sure?</h3>
|
||||
<p class="text-sm text-zinc-500">Enter your password to confirm account deletion.</p>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">Password</label>
|
||||
<label class="text-sm font-bold text-zinc-800">Password</label>
|
||||
<input
|
||||
v-model="deletePassword"
|
||||
type="password"
|
||||
class="w-full h-12 px-4 bg-[#faf6f3] border rounded-xl font-medium text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-red-400"
|
||||
:class="deleteError ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="deleteError ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-red-400"
|
||||
/>
|
||||
<p v-if="deleteError" class="text-xs text-red-600">{{ deleteError }}</p>
|
||||
</div>
|
||||
@@ -76,7 +76,7 @@
|
||||
<div class="flex gap-3">
|
||||
<button
|
||||
@click="closeDeleteModal"
|
||||
class="flex-1 py-3 border border-[#e5ded7] rounded-xl text-sm font-bold text-[#89726c] hover:bg-[#faf6f3] transition-colors"
|
||||
class="flex-1 py-3 border border-zinc-300 rounded-xl text-sm font-bold text-zinc-500 hover:bg-zinc-50 transition-colors"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
<template>
|
||||
<div class="space-y-6 max-w-lg">
|
||||
<!-- Password change -->
|
||||
<form @submit.prevent="savePassword" class="p-6 bg-white rounded-2xl border border-[#e5ded7] space-y-5">
|
||||
<h2 class="text-lg font-black text-[#4a3f3b]">Change password</h2>
|
||||
<form class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-5" @submit.prevent="savePassword">
|
||||
<h2 class="text-lg font-black text-zinc-800">Change password</h2>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">Current password</label>
|
||||
<label class="text-sm font-bold text-zinc-800">Current password</label>
|
||||
<input
|
||||
v-model="passwordForm.current_password"
|
||||
type="password"
|
||||
class="w-full h-12 px-4 bg-[#faf6f3] border rounded-xl font-medium text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e]"
|
||||
:class="passwordErrors.current_password ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="passwordErrors.current_password ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
<p v-if="passwordErrors.current_password" class="text-xs text-red-600">{{ passwordErrors.current_password[0] }}</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">New password</label>
|
||||
<label class="text-sm font-bold text-zinc-800">New password</label>
|
||||
<input
|
||||
v-model="passwordForm.password"
|
||||
type="password"
|
||||
class="w-full h-12 px-4 bg-[#faf6f3] border rounded-xl font-medium text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e]"
|
||||
:class="passwordErrors.password ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="passwordErrors.password ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
<p v-if="passwordErrors.password" class="text-xs text-red-600">{{ passwordErrors.password[0] }}</p>
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">Confirm new password</label>
|
||||
<label class="text-sm font-bold text-zinc-800">Confirm new password</label>
|
||||
<input
|
||||
v-model="passwordForm.password_confirmation"
|
||||
type="password"
|
||||
class="w-full h-12 px-4 bg-[#faf6f3] border rounded-xl font-medium text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e]"
|
||||
:class="passwordErrors.password_confirmation ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="passwordErrors.password_confirmation ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-full h-12 px-4 bg-zinc-50 border rounded-xl font-medium text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
<p v-if="passwordErrors.password_confirmation" class="text-xs text-red-600">{{ passwordErrors.password_confirmation[0] }}</p>
|
||||
</div>
|
||||
@@ -43,7 +43,7 @@
|
||||
<button
|
||||
type="submit"
|
||||
:disabled="passwordSaving"
|
||||
class="px-8 py-3 bg-[#bb5b3e] text-white rounded-xl font-bold hover:bg-[#a34a31] transition-all disabled:opacity-50"
|
||||
class="px-8 py-3 bg-accent text-white rounded-xl font-bold hover:bg-accent-content transition-all disabled:opacity-50"
|
||||
>
|
||||
{{ passwordSaving ? 'Updating…' : 'Update password' }}
|
||||
</button>
|
||||
@@ -52,37 +52,37 @@
|
||||
</form>
|
||||
|
||||
<!-- Two-factor authentication -->
|
||||
<div class="p-6 bg-white rounded-2xl border border-[#e5ded7] space-y-4">
|
||||
<div class="p-6 bg-white rounded-2xl border border-zinc-300 space-y-4">
|
||||
<div class="flex items-center justify-between">
|
||||
<div>
|
||||
<h2 class="text-lg font-black text-[#4a3f3b]">Two-factor authentication</h2>
|
||||
<p class="text-sm text-[#89726c] mt-0.5">
|
||||
<h2 class="text-lg font-black text-zinc-800">Two-factor authentication</h2>
|
||||
<p class="text-sm text-zinc-500 mt-0.5">
|
||||
{{ twoFactorEnabled ? 'Enabled — your account is extra secure.' : 'Add extra security to your account.' }}
|
||||
</p>
|
||||
</div>
|
||||
<span
|
||||
class="px-3 py-1 rounded-full text-xs font-black"
|
||||
:class="twoFactorEnabled ? 'bg-green-100 text-green-700' : 'bg-[#faf6f3] text-[#89726c]'"
|
||||
:class="twoFactorEnabled ? 'bg-green-100 text-green-700' : 'bg-zinc-50 text-zinc-500'"
|
||||
>
|
||||
{{ twoFactorEnabled ? 'ON' : 'OFF' }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 2FA enabling flow -->
|
||||
<div v-if="enablingTwoFactor" class="space-y-4 border-t border-[#e5ded7] pt-4">
|
||||
<p class="text-sm font-bold text-[#4a3f3b]">Scan this QR code in your authenticator app:</p>
|
||||
<div v-if="enablingTwoFactor" class="space-y-4 border-t border-zinc-300 pt-4">
|
||||
<p class="text-sm font-bold text-zinc-800">Scan this QR code in your authenticator app:</p>
|
||||
|
||||
<div v-if="setupData" class="flex flex-col items-start gap-4">
|
||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||
<div v-html="setupData.svg" class="[&_svg]:w-40 [&_svg]:h-40"></div>
|
||||
<div class="space-y-1">
|
||||
<p class="text-xs font-bold text-[#89726c] uppercase tracking-widest">Or enter setup key manually</p>
|
||||
<code class="text-xs bg-[#faf6f3] px-3 py-2 rounded-lg font-mono text-[#4a3f3b] break-all block">{{ setupData.secretKey }}</code>
|
||||
<p class="text-xs font-bold text-zinc-500 uppercase tracking-widest">Or enter setup key manually</p>
|
||||
<code class="text-xs bg-zinc-50 px-3 py-2 rounded-lg font-mono text-zinc-800 break-all block">{{ setupData.secretKey }}</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="!twoFactorEnabled" class="space-y-2">
|
||||
<label class="text-sm font-bold text-[#4a3f3b]">Enter the 6-digit code to confirm</label>
|
||||
<label class="text-sm font-bold text-zinc-800">Enter the 6-digit code to confirm</label>
|
||||
<div class="flex gap-3">
|
||||
<input
|
||||
v-model="confirmCode"
|
||||
@@ -90,13 +90,13 @@
|
||||
maxlength="6"
|
||||
inputmode="numeric"
|
||||
placeholder="000000"
|
||||
class="w-36 h-12 px-4 bg-[#faf6f3] border rounded-xl font-mono text-center text-[#4a3f3b] focus:outline-none focus:ring-2 focus:ring-[#bb5b3e]"
|
||||
:class="confirmError ? 'border-red-400' : 'border-[#e5ded7]'"
|
||||
:class="confirmError ? 'border-red-400' : 'border-zinc-300'"
|
||||
class="w-36 h-12 px-4 bg-zinc-50 border rounded-xl font-mono text-center text-zinc-800 focus:outline-none focus:ring-2 focus:ring-accent"
|
||||
/>
|
||||
<button
|
||||
@click="confirmTwoFactor"
|
||||
:disabled="confirmCode.length !== 6 || confirming"
|
||||
class="px-6 py-3 bg-[#bb5b3e] text-white rounded-xl text-sm font-bold hover:bg-[#a34a31] transition-all disabled:opacity-50"
|
||||
class="px-6 py-3 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent-content transition-all disabled:opacity-50"
|
||||
>
|
||||
{{ confirming ? 'Verifying…' : 'Confirm' }}
|
||||
</button>
|
||||
@@ -111,35 +111,35 @@
|
||||
<button
|
||||
v-if="!twoFactorEnabled"
|
||||
@click="cancelEnable"
|
||||
class="text-sm text-[#89726c] hover:text-[#4a3f3b]"
|
||||
class="text-sm text-zinc-500 hover:text-zinc-800"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Recovery codes (when 2FA enabled and not mid-setup) -->
|
||||
<div v-if="twoFactorEnabled && !enablingTwoFactor" class="border-t border-[#e5ded7] pt-4 space-y-3">
|
||||
<div v-if="twoFactorEnabled && !enablingTwoFactor" class="border-t border-zinc-300 pt-4 space-y-3">
|
||||
<div class="flex items-center justify-between">
|
||||
<p class="text-sm font-bold text-[#4a3f3b]">Recovery codes</p>
|
||||
<p class="text-sm font-bold text-zinc-800">Recovery codes</p>
|
||||
<button
|
||||
@click="toggleRecoveryCodes"
|
||||
class="text-xs font-bold text-[#bb5b3e] hover:underline"
|
||||
class="text-xs font-bold text-accent hover:underline"
|
||||
>
|
||||
{{ showRecoveryCodes ? 'Hide' : 'Show' }}
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="showRecoveryCodes" class="space-y-2">
|
||||
<div class="grid grid-cols-2 gap-1 bg-[#faf6f3] rounded-xl p-4">
|
||||
<div class="grid grid-cols-2 gap-1 bg-zinc-50 rounded-xl p-4">
|
||||
<code
|
||||
v-for="code in recoveryCodes"
|
||||
:key="code"
|
||||
class="text-xs font-mono text-[#4a3f3b]"
|
||||
class="text-xs font-mono text-zinc-800"
|
||||
>{{ code }}</code>
|
||||
</div>
|
||||
<button
|
||||
@click="regenRecoveryCodes"
|
||||
:disabled="regenLoading"
|
||||
class="text-xs font-bold text-[#89726c] hover:text-[#4a3f3b]"
|
||||
class="text-xs font-bold text-zinc-500 hover:text-zinc-800"
|
||||
>
|
||||
{{ regenLoading ? 'Regenerating…' : 'Regenerate codes' }}
|
||||
</button>
|
||||
@@ -147,12 +147,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Action buttons -->
|
||||
<div class="flex gap-3 border-t border-[#e5ded7] pt-4">
|
||||
<div class="flex gap-3 border-t border-zinc-300 pt-4">
|
||||
<button
|
||||
v-if="!twoFactorEnabled && !enablingTwoFactor"
|
||||
@click="enableTwoFactor"
|
||||
:disabled="tfaActionLoading"
|
||||
class="px-6 py-2.5 bg-[#bb5b3e] text-white rounded-xl text-sm font-bold hover:bg-[#a34a31] transition-colors disabled:opacity-50"
|
||||
class="px-6 py-2.5 bg-accent text-white rounded-xl text-sm font-bold hover:bg-accent-content transition-colors disabled:opacity-50"
|
||||
>
|
||||
{{ tfaActionLoading ? 'Enabling…' : 'Enable 2FA' }}
|
||||
</button>
|
||||
@@ -160,7 +160,7 @@
|
||||
v-if="twoFactorEnabled && !enablingTwoFactor"
|
||||
@click="disableTwoFactor"
|
||||
:disabled="tfaActionLoading"
|
||||
class="px-6 py-2.5 bg-white border border-[#e5ded7] rounded-xl text-sm font-bold text-[#89726c] hover:border-red-300 hover:text-red-600 transition-colors disabled:opacity-50"
|
||||
class="px-6 py-2.5 bg-white border border-zinc-300 rounded-xl text-sm font-bold text-zinc-500 hover:border-red-300 hover:text-red-600 transition-colors disabled:opacity-50"
|
||||
>
|
||||
{{ tfaActionLoading ? 'Disabling…' : 'Disable 2FA' }}
|
||||
</button>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<h1 class="text-2xl font-black text-[#4a3f3b]">Settings</h1>
|
||||
<p class="text-[#89726c] mt-1">Manage your account and preferences.</p>
|
||||
<h1 class="text-2xl font-black text-zinc-800">Settings</h1>
|
||||
<p class="text-zinc-500 mt-1">Manage your account and preferences.</p>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-6">
|
||||
<!-- Settings sub-nav -->
|
||||
<aside class="w-44 flex-shrink-0">
|
||||
<aside class="w-44 shrink-0">
|
||||
<nav class="space-y-1">
|
||||
<RouterLink
|
||||
v-for="item in settingsNav"
|
||||
@@ -15,8 +15,8 @@
|
||||
:to="item.to"
|
||||
class="flex items-center gap-3 px-3 py-2 rounded-xl text-sm font-bold transition-colors"
|
||||
:class="$route.path === item.to
|
||||
? 'bg-[#bb5b3e] text-white'
|
||||
: 'text-[#89726c] hover:bg-white hover:text-[#4a3f3b]'"
|
||||
? 'bg-accent text-white'
|
||||
: 'text-zinc-500 hover:bg-white hover:text-zinc-800'"
|
||||
>
|
||||
<iconify-icon :icon="item.icon"></iconify-icon>
|
||||
{{ item.label }}
|
||||
|
||||
Reference in New Issue
Block a user