147 lines
5.8 KiB
TypeScript
147 lines
5.8 KiB
TypeScript
|
|
import React, { useState } from "react";
|
|
import { User, Mail, Phone, Calendar, MapPin, CreditCard, Globe, Lock } from "lucide-react";
|
|
import { useSelector } from "react-redux";
|
|
import { RootState } from "../../store";
|
|
import ChangePasswordModal from "./ChangePasswordModal";
|
|
|
|
const Settings: React.FC = () => {
|
|
const { profile } = useSelector((state: RootState) => state.profile);
|
|
const [modalOpen, setModalOpen] = useState(false);
|
|
|
|
const fullName = `${profile?.firstName || ""} ${profile?.lastName || ""}`.trim();
|
|
|
|
const maskLast5 = (value: string) => {
|
|
if (!value) return "N/A";
|
|
const str = value.toString();
|
|
const last5 = str.slice(-5);
|
|
const masked = "X".repeat(str.length - 5) + last5;
|
|
return masked;
|
|
};
|
|
|
|
|
|
return (
|
|
<div className="flex flex-col gap-3">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between">
|
|
<h2 className="text-md font-bold flex items-center gap-2">
|
|
<User size={18} /> Profile Settings
|
|
</h2>
|
|
<button
|
|
onClick={() => setModalOpen(true)}
|
|
className="btn btn-sm btn-outline btn-primary flex items-center gap-2"
|
|
>
|
|
<Lock size={14} /> Change Password
|
|
</button>
|
|
</div>
|
|
|
|
{/* Profile Card */}
|
|
<div className="card bg-base-100 border border-base-300 shadow-sm p-4">
|
|
<div className="flex flex-col md:flex-row gap-4">
|
|
{/* Compact Avatar Section */}
|
|
<div className="flex flex-col items-center md:items-start md:w-48 shrink-0">
|
|
<div className="avatar">
|
|
<div className="w-20 rounded-full ring ring-primary ring-offset-base-100 ring-offset-1 flex justify-center items-center bg-base-200">
|
|
<User size={40} className="text-base-content/50" />
|
|
</div>
|
|
</div>
|
|
<div className="mt-2 text-center md:text-left">
|
|
<h3 className="text-sm font-semibold">{fullName || "N/A"}</h3>
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 justify-center md:justify-start mt-0.5">
|
|
<Mail size={10} /> {profile?.email || "No Email"}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="divider md:divider-horizontal my-0 md:mx-2" />
|
|
|
|
{/* Compact Details Grid */}
|
|
<div className="flex-1 grid grid-cols-2 sm:grid-cols-3 gap-2.5">
|
|
{/* Basic Info */}
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
<Calendar size={11} /> DOB
|
|
</p>
|
|
<p className="text-xs font-medium">{profile?.dob || "N/A"}</p>
|
|
</div>
|
|
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
🎂 Age
|
|
</p>
|
|
<p className="text-xs font-medium">{profile?.age || "N/A"}</p>
|
|
</div>
|
|
|
|
{/* Contact Info */}
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
<Phone size={11} /> Phone
|
|
</p>
|
|
<p className="text-xs font-medium truncate" title={profile?.phone || "N/A"}>
|
|
{profile?.phone || "N/A"}
|
|
</p>
|
|
</div>
|
|
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
💬 Skype
|
|
</p>
|
|
<p className="text-xs font-medium truncate" title={profile?.skype || "Not Linked"}>
|
|
{profile?.skype || "Not Linked"}
|
|
</p>
|
|
</div>
|
|
|
|
{/* Payment Info */}
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
<CreditCard size={11} /> Payment
|
|
</p>
|
|
<p className="text-xs font-medium capitalize truncate">
|
|
{profile?.paymentMethod || "N/A"}
|
|
</p>
|
|
</div>
|
|
|
|
{profile?.paymentMethod === "payoneer" && (
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
💳 Payoneer
|
|
</p>
|
|
<p className="text-xs font-medium truncate" title={profile?.payoneerAccount || "N/A"}>
|
|
{maskLast5(profile?.payoneerAccount)}
|
|
</p>
|
|
</div>
|
|
)}
|
|
|
|
{profile?.paymentMethod === "veem" && (
|
|
<div className="p-2 rounded bg-base-200/40">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
🏦 Veem
|
|
</p>
|
|
<p className="text-xs font-medium truncate" title={profile?.veemAccount || "N/A"}>
|
|
{profile?.veemAccount || "N/A"}
|
|
</p>
|
|
</div>
|
|
)}
|
|
|
|
{/* Location - Full Width */}
|
|
<div className="p-2 rounded bg-base-200/40 col-span-2 sm:col-span-3">
|
|
<p className="text-xs text-base-content/60 flex items-center gap-1 mb-0.5">
|
|
<MapPin size={11} /> Address
|
|
</p>
|
|
<p className="text-xs font-medium line-clamp-2">
|
|
{[profile?.address, profile?.city, profile?.state, profile?.country]
|
|
.filter(Boolean)
|
|
.join(", ") || "N/A"}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/* Change Password Modal */}
|
|
<ChangePasswordModal isOpen={modalOpen} onClose={() => setModalOpen(false)} />
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Settings;
|