updates
This commit is contained in:
@@ -379,7 +379,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* Header */}
|
||||
<div className="mb-6 sm:mb-8 animate-fade-in">
|
||||
<div className="flex items-center gap-2 sm:gap-3 mb-2 sm:mb-3">
|
||||
<div className="h-1 w-12 sm:w-16 md:w-20 bg-gradient-to-r from-[#d4af37] via-amber-400 to-[#d4af37] rounded-full"></div>
|
||||
<div className="h-1 w-12 sm:w-16 md:w-20 bg-gradient-to-r from-[var(--luxury-gold)] via-amber-400 to-[var(--luxury-gold)] rounded-full"></div>
|
||||
<h1 className="text-2xl sm:text-3xl lg:text-4xl font-serif font-bold bg-gradient-to-r from-gray-900 via-amber-900/90 to-gray-900 bg-clip-text text-transparent tracking-tight">
|
||||
Housekeeping Profile
|
||||
</h1>
|
||||
@@ -390,50 +390,50 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* Tabs */}
|
||||
<div className="mb-4 sm:mb-6 border-b border-[#d4af37]/20 overflow-x-auto bg-white/50 backdrop-blur-sm rounded-t-lg sm:rounded-t-xl px-4 sm:px-6">
|
||||
<div className="mb-4 sm:mb-6 border-b border-[var(--luxury-gold)]/20 overflow-x-auto bg-white/50 backdrop-blur-sm rounded-t-lg sm:rounded-t-xl px-4 sm:px-6">
|
||||
<div className="flex space-x-4 sm:space-x-8 min-w-max">
|
||||
<button
|
||||
onClick={() => setActiveTab('profile')}
|
||||
className={`py-3 sm:py-4 px-2 sm:px-1 border-b-2 font-semibold text-xs sm:text-sm transition-all duration-300 whitespace-nowrap ${
|
||||
activeTab === 'profile'
|
||||
? 'border-[#d4af37] text-[#d4af37] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[#d4af37] hover:border-[#d4af37]/30'
|
||||
? 'border-[var(--luxury-gold)] text-[var(--luxury-gold)] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[var(--luxury-gold)] hover:border-[var(--luxury-gold)]/30'
|
||||
}`}
|
||||
>
|
||||
<User className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'profile' ? 'text-[#d4af37]' : ''}`} />
|
||||
<User className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'profile' ? 'text-[var(--luxury-gold)]' : ''}`} />
|
||||
Profile
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('password')}
|
||||
className={`py-3 sm:py-4 px-2 sm:px-1 border-b-2 font-semibold text-xs sm:text-sm transition-all duration-300 whitespace-nowrap ${
|
||||
activeTab === 'password'
|
||||
? 'border-[#d4af37] text-[#d4af37] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[#d4af37] hover:border-[#d4af37]/30'
|
||||
? 'border-[var(--luxury-gold)] text-[var(--luxury-gold)] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[var(--luxury-gold)] hover:border-[var(--luxury-gold)]/30'
|
||||
}`}
|
||||
>
|
||||
<KeyRound className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'password' ? 'text-[#d4af37]' : ''}`} />
|
||||
<KeyRound className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'password' ? 'text-[var(--luxury-gold)]' : ''}`} />
|
||||
Password
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('mfa')}
|
||||
className={`py-3 sm:py-4 px-2 sm:px-1 border-b-2 font-semibold text-xs sm:text-sm transition-all duration-300 whitespace-nowrap ${
|
||||
activeTab === 'mfa'
|
||||
? 'border-[#d4af37] text-[#d4af37] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[#d4af37] hover:border-[#d4af37]/30'
|
||||
? 'border-[var(--luxury-gold)] text-[var(--luxury-gold)] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[var(--luxury-gold)] hover:border-[var(--luxury-gold)]/30'
|
||||
}`}
|
||||
>
|
||||
<Shield className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'mfa' ? 'text-[#d4af37]' : ''}`} />
|
||||
<Shield className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'mfa' ? 'text-[var(--luxury-gold)]' : ''}`} />
|
||||
Two-Factor Auth
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setActiveTab('sessions')}
|
||||
className={`py-3 sm:py-4 px-2 sm:px-1 border-b-2 font-semibold text-xs sm:text-sm transition-all duration-300 whitespace-nowrap ${
|
||||
activeTab === 'sessions'
|
||||
? 'border-[#d4af37] text-[#d4af37] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[#d4af37] hover:border-[#d4af37]/30'
|
||||
? 'border-[var(--luxury-gold)] text-[var(--luxury-gold)] shadow-sm'
|
||||
: 'border-transparent text-gray-500 hover:text-[var(--luxury-gold)] hover:border-[var(--luxury-gold)]/30'
|
||||
}`}
|
||||
>
|
||||
<Monitor className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'sessions' ? 'text-[#d4af37]' : ''}`} />
|
||||
<Monitor className={`w-4 h-4 sm:w-5 sm:h-5 inline mr-2 ${activeTab === 'sessions' ? 'text-[var(--luxury-gold)]' : ''}`} />
|
||||
Sessions
|
||||
</button>
|
||||
</div>
|
||||
@@ -441,7 +441,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
|
||||
{/* Profile Tab */}
|
||||
{activeTab === 'profile' && (
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[#d4af37]/20 shadow-2xl animate-slide-up">
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[var(--luxury-gold)]/20 shadow-2xl animate-slide-up">
|
||||
<form onSubmit={handleSubmitProfile(onSubmitProfile)} className="space-y-5 sm:space-y-6">
|
||||
{/* Avatar Section */}
|
||||
<div className="flex flex-col sm:flex-row items-center sm:items-start gap-4 sm:gap-6 pb-5 sm:pb-6 border-b border-gray-200">
|
||||
@@ -450,17 +450,17 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
<img
|
||||
src={avatarPreview || normalizeImageUrl(userInfo?.avatar)}
|
||||
alt="Profile"
|
||||
className="w-20 h-20 sm:w-24 sm:h-24 rounded-full object-cover ring-4 ring-[#d4af37]/20 shadow-lg"
|
||||
className="w-20 h-20 sm:w-24 sm:h-24 rounded-full object-cover ring-4 ring-[var(--luxury-gold)]/20 shadow-lg"
|
||||
onError={() => setAvatarError(true)}
|
||||
/>
|
||||
) : (
|
||||
<div className="w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-gradient-to-br from-[#d4af37] to-[#c9a227] flex items-center justify-center ring-4 ring-[#d4af37]/20 shadow-lg">
|
||||
<div className="w-20 h-20 sm:w-24 sm:h-24 rounded-full bg-gradient-to-br from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] flex items-center justify-center ring-4 ring-[var(--luxury-gold)]/20 shadow-lg">
|
||||
<User className="w-10 h-10 sm:w-12 sm:h-12 text-white" />
|
||||
</div>
|
||||
)}
|
||||
<label
|
||||
htmlFor="avatar-upload"
|
||||
className="absolute bottom-0 right-0 p-2 bg-gradient-to-br from-[#d4af37] to-[#c9a227] rounded-full cursor-pointer hover:from-[#f5d76e] hover:to-[#d4af37] transition-all duration-300 shadow-lg"
|
||||
className="absolute bottom-0 right-0 p-2 bg-gradient-to-br from-[var(--luxury-gold)] to-[var(--luxury-gold-dark)] rounded-full cursor-pointer hover:from-[var(--luxury-gold-light)] hover:to-[var(--luxury-gold)] transition-all duration-300 shadow-lg"
|
||||
>
|
||||
<Camera className="w-3.5 h-3.5 sm:w-4 sm:h-4 text-white" />
|
||||
<input
|
||||
@@ -477,7 +477,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* Name Field */}
|
||||
<div>
|
||||
<label className="block text-sm sm:text-base font-medium text-gray-700 mb-2">
|
||||
<User className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[#d4af37]" />
|
||||
<User className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[var(--luxury-gold)]" />
|
||||
Full Name <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -499,7 +499,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* Email Field */}
|
||||
<div>
|
||||
<label className="block text-sm sm:text-base font-medium text-gray-700 mb-2">
|
||||
<Mail className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[#d4af37]" />
|
||||
<Mail className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[var(--luxury-gold)]" />
|
||||
Email Address <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -521,7 +521,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* Phone Field */}
|
||||
<div>
|
||||
<label className="block text-sm sm:text-base font-medium text-gray-700 mb-2">
|
||||
<Phone className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[#d4af37]" />
|
||||
<Phone className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[var(--luxury-gold)]" />
|
||||
Phone Number <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<input
|
||||
@@ -556,7 +556,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
|
||||
{/* Password Tab */}
|
||||
{activeTab === 'password' && (
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[#d4af37]/20 shadow-2xl animate-slide-up">
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[var(--luxury-gold)]/20 shadow-2xl animate-slide-up">
|
||||
<form onSubmit={handleSubmitPassword(onSubmitPassword)} className="space-y-5 sm:space-y-6">
|
||||
{/* Password Requirements */}
|
||||
<div className="bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200/60 rounded-sm p-4 sm:p-5">
|
||||
@@ -579,7 +579,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* Current Password */}
|
||||
<div>
|
||||
<label className="block text-sm sm:text-base font-medium text-gray-700 mb-2">
|
||||
<Lock className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[#d4af37]" />
|
||||
<Lock className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[var(--luxury-gold)]" />
|
||||
Current Password <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -594,7 +594,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword({ ...showPassword, current: !showPassword.current })}
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-[#d4af37] transition-colors"
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-[var(--luxury-gold)] transition-colors"
|
||||
>
|
||||
{showPassword.current ? <EyeOff className="w-4 h-4 sm:w-5 sm:h-5" /> : <Eye className="w-4 h-4 sm:w-5 sm:h-5" />}
|
||||
</button>
|
||||
@@ -610,7 +610,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* New Password */}
|
||||
<div>
|
||||
<label className="block text-sm sm:text-base font-medium text-gray-700 mb-2">
|
||||
<Lock className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[#d4af37]" />
|
||||
<Lock className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[var(--luxury-gold)]" />
|
||||
New Password <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -625,7 +625,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword({ ...showPassword, new: !showPassword.new })}
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-[#d4af37] transition-colors"
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-[var(--luxury-gold)] transition-colors"
|
||||
>
|
||||
{showPassword.new ? <EyeOff className="w-4 h-4 sm:w-5 sm:h-5" /> : <Eye className="w-4 h-4 sm:w-5 sm:h-5" />}
|
||||
</button>
|
||||
@@ -641,7 +641,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
{/* Confirm Password */}
|
||||
<div>
|
||||
<label className="block text-sm sm:text-base font-medium text-gray-700 mb-2">
|
||||
<Lock className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[#d4af37]" />
|
||||
<Lock className="w-4 h-4 sm:w-5 sm:h-5 inline mr-2 text-[var(--luxury-gold)]" />
|
||||
Confirm Password <span className="text-red-500">*</span>
|
||||
</label>
|
||||
<div className="relative">
|
||||
@@ -656,7 +656,7 @@ const HousekeepingProfilePage: React.FC = () => {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setShowPassword({ ...showPassword, confirm: !showPassword.confirm })}
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-[#d4af37] transition-colors"
|
||||
className="absolute inset-y-0 right-0 pr-3 flex items-center text-gray-400 hover:text-[var(--luxury-gold)] transition-colors"
|
||||
>
|
||||
{showPassword.confirm ? <EyeOff className="w-4 h-4 sm:w-5 sm:h-5" /> : <Eye className="w-4 h-4 sm:w-5 sm:h-5" />}
|
||||
</button>
|
||||
@@ -742,10 +742,10 @@ const MFATab: React.FC<MFATabProps> = ({
|
||||
setLoading,
|
||||
}) => {
|
||||
return (
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[#d4af37]/20 shadow-2xl animate-slide-up space-y-5 sm:space-y-6">
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[var(--luxury-gold)]/20 shadow-2xl animate-slide-up space-y-5 sm:space-y-6">
|
||||
<div>
|
||||
<h2 className="text-xl sm:text-2xl font-serif font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
||||
<Shield className="w-5 h-5 sm:w-6 sm:h-6 text-[#d4af37]" />
|
||||
<Shield className="w-5 h-5 sm:w-6 sm:h-6 text-[var(--luxury-gold)]" />
|
||||
Two-Factor Authentication
|
||||
</h2>
|
||||
<p className="text-xs sm:text-sm text-gray-600 font-light">
|
||||
@@ -894,7 +894,7 @@ const MFATab: React.FC<MFATabProps> = ({
|
||||
|
||||
<div className="bg-white border border-gray-200 rounded-sm p-4">
|
||||
<h3 className="font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
||||
<KeyRound className="w-4 h-4 text-[#d4af37]" />
|
||||
<KeyRound className="w-4 h-4 text-[var(--luxury-gold)]" />
|
||||
Step 2: Verify Setup
|
||||
</h3>
|
||||
<p className="text-sm text-gray-600 mb-4">Enter the 6-digit code from your authenticator app.</p>
|
||||
@@ -992,10 +992,10 @@ const SessionsTab: React.FC = () => {
|
||||
};
|
||||
|
||||
const getDeviceIcon = (userAgent?: string) => {
|
||||
if (!userAgent) return <Monitor className="w-5 h-5 text-[#d4af37]" />;
|
||||
if (!userAgent) return <Monitor className="w-5 h-5 text-[var(--luxury-gold)]" />;
|
||||
if (userAgent.includes('Mobile')) return <Smartphone className="w-5 h-5 text-blue-500" />;
|
||||
if (userAgent.includes('Tablet')) return <Tablet className="w-5 h-5 text-purple-500" />;
|
||||
return <Monitor className="w-5 h-5 text-[#d4af37]" />;
|
||||
return <Monitor className="w-5 h-5 text-[var(--luxury-gold)]" />;
|
||||
};
|
||||
|
||||
const getDeviceName = (userAgent?: string) => {
|
||||
@@ -1053,17 +1053,17 @@ const SessionsTab: React.FC = () => {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[#d4af37]/20 shadow-2xl">
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[var(--luxury-gold)]/20 shadow-2xl">
|
||||
<Loading text="Loading sessions..." />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[#d4af37]/20 shadow-2xl animate-slide-up space-y-5 sm:space-y-6">
|
||||
<div className="luxury-glass rounded-sm p-4 sm:p-6 lg:p-8 border border-[var(--luxury-gold)]/20 shadow-2xl animate-slide-up space-y-5 sm:space-y-6">
|
||||
<div>
|
||||
<h2 className="text-xl sm:text-2xl font-serif font-semibold text-gray-900 mb-2 flex items-center gap-2">
|
||||
<Monitor className="w-5 h-5 sm:w-6 sm:h-6 text-[#d4af37]" />
|
||||
<Monitor className="w-5 h-5 sm:w-6 sm:h-6 text-[var(--luxury-gold)]" />
|
||||
Active Sessions
|
||||
</h2>
|
||||
<p className="text-xs sm:text-sm text-gray-600 font-light">
|
||||
@@ -1092,11 +1092,11 @@ const SessionsTab: React.FC = () => {
|
||||
{sessions.map((session) => (
|
||||
<div
|
||||
key={session.id}
|
||||
className="bg-gradient-to-r from-slate-50 to-white border border-[#d4af37]/20 rounded-sm p-4 sm:p-5 hover:shadow-lg transition-all"
|
||||
className="bg-gradient-to-r from-slate-50 to-white border border-[var(--luxury-gold)]/20 rounded-sm p-4 sm:p-5 hover:shadow-lg transition-all"
|
||||
>
|
||||
<div className="flex items-start justify-between gap-4">
|
||||
<div className="flex items-start gap-4 flex-1">
|
||||
<div className="p-2 sm:p-3 bg-gradient-to-br from-[#d4af37]/10 to-[#c9a227]/10 rounded-sm flex-shrink-0">
|
||||
<div className="p-2 sm:p-3 bg-gradient-to-br from-[var(--luxury-gold)]/10 to-[var(--luxury-gold-dark)]/10 rounded-sm flex-shrink-0">
|
||||
{getDeviceIcon(session.user_agent)}
|
||||
</div>
|
||||
<div className="flex-1 min-w-0">
|
||||
|
||||
Reference in New Issue
Block a user