feat: introduce agent network page with sidebar, invitation cards, and new icons, while refactoring dashboard components and updating profile links.
This commit is contained in:
3
public/assets/icons/chain-icon.svg
Normal file
3
public/assets/icons/chain-icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M7.5 12H4.5C3.70435 12 2.94129 11.6839 2.37868 11.1213C1.81607 10.5587 1.5 9.79565 1.5 9C1.5 8.20435 1.81607 7.44129 2.37868 6.87868C2.94129 6.31607 3.70435 6 4.5 6H7.5V7.5H4.5C4.10218 7.5 3.72064 7.65804 3.43934 7.93934C3.15804 8.22064 3 8.60218 3 9C3 9.39782 3.15804 9.77936 3.43934 10.0607C3.72064 10.342 4.10218 10.5 4.5 10.5H7.5V12ZM13.5 12H10.5V10.5H13.5C13.8978 10.5 14.2794 10.342 14.5607 10.0607C14.842 9.77936 15 9.39782 15 9C15 8.60218 14.842 8.22064 14.5607 7.93934C14.2794 7.65804 13.8978 7.5 13.5 7.5H10.5V6H13.5C14.2956 6 15.0587 6.31607 15.6213 6.87868C16.1839 7.44129 16.5 8.20435 16.5 9C16.5 9.79565 16.1839 10.5587 15.6213 11.1213C15.0587 11.6839 14.2956 12 13.5 12ZM12 9.75H6V8.25H12V9.75Z" fill="#00293D"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 840 B |
3
public/assets/icons/people-icon.svg
Normal file
3
public/assets/icons/people-icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="31" height="31" viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20.6667 13.9167C22.5283 13.9167 24.0258 12.4063 24.0258 10.5417C24.0258 8.67708 22.5283 7.16667 20.6667 7.16667C18.805 7.16667 17.2946 8.67708 17.2946 10.5417C17.2946 12.4063 18.805 13.9167 20.6667 13.9167ZM10.5417 13.9167C12.4033 13.9167 13.9008 12.4063 13.9008 10.5417C13.9008 8.67708 12.4033 7.16667 10.5417 7.16667C8.68 7.16667 7.1696 8.67708 7.1696 10.5417C7.1696 12.4063 8.68 13.9167 10.5417 13.9167ZM10.5417 16.5C7.53877 16.5 1.52085 18.0075 1.52085 21.0417V23.8333H19.5625V21.0417C19.5625 18.0075 13.5446 16.5 10.5417 16.5ZM20.6667 16.5C20.2892 16.5 19.8592 16.5258 19.4042 16.5646C21.0925 17.7692 22.2063 19.3929 22.2063 21.0417V23.8333H29.4792V21.0417C29.4792 18.0075 23.4613 16.5 20.6667 16.5Z" fill="#E58625"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 836 B |
3
public/assets/icons/phone-manager-icon.svg
Normal file
3
public/assets/icons/phone-manager-icon.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9 0C4.02944 0 0 4.02944 0 9C0 13.9706 4.02944 18 9 18C13.9706 18 18 13.9706 18 9C18 4.02944 13.9706 0 9 0ZM9 1.5C13.1421 1.5 16.5 4.85786 16.5 9C16.5 13.1421 13.1421 16.5 9 16.5C4.85786 16.5 1.5 13.1421 1.5 9C1.5 4.85786 4.85786 1.5 9 1.5ZM12.75 6L7.5 11.25L5.25 9L4.125 10.125L7.5 13.5L13.875 7.125L12.75 6Z" fill="#E58625"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 440 B |
4
public/assets/icons/shield-verified-icon.svg
Normal file
4
public/assets/icons/shield-verified-icon.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M9.30942 16.8689C12.8162 15.6602 15.3158 12.8503 15.7079 9.27257C15.8166 7.71948 15.8074 6.16038 15.6803 4.60868C15.6636 4.36407 15.5563 4.13448 15.3793 3.96481C15.2023 3.79513 14.9684 3.69756 14.7233 3.69118C13.1369 3.64232 11.2929 3.37785 9.86821 1.97446C9.71943 1.82752 9.51873 1.74512 9.30961 1.74512C9.10049 1.74512 8.89979 1.82752 8.75101 1.97446C7.3259 3.37785 5.48198 3.64232 3.89594 3.69118C3.65084 3.69756 3.41692 3.79513 3.23993 3.96481C3.06294 4.13448 2.9556 4.36407 2.93889 4.60868C2.81168 6.16037 2.80234 7.71947 2.91096 9.27257C3.30302 12.8503 5.80268 15.6602 9.30942 16.8689Z" stroke="#E58625" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M9.04859 12.0218L10.6637 9.30727H7.94922L9.56434 6.59277" stroke="#E58625" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 938 B |
@@ -95,7 +95,10 @@ export function ProfileCard({
|
||||
/>
|
||||
Message
|
||||
</button>
|
||||
<button className="flex items-center gap-2 px-4 py-1.5 bg-[#e58625] text-[#00293d] text-sm font-normal rounded-[15px] border border-[#00293d]/10 hover:bg-[#d47720] transition-colors font-serif">
|
||||
<Link
|
||||
href="/agent/network"
|
||||
className="flex items-center gap-2 px-4 py-1.5 bg-[#e58625] text-[#00293d] text-sm font-normal rounded-[15px] border border-[#00293d]/10 hover:bg-[#d47720] transition-colors font-serif cursor-pointer"
|
||||
>
|
||||
<Image
|
||||
src="/assets/icons/requests-dark-icon.svg"
|
||||
alt="Requests"
|
||||
@@ -103,7 +106,7 @@ export function ProfileCard({
|
||||
height={13}
|
||||
/>
|
||||
Requests
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { Tag } from './Tag';
|
||||
|
||||
interface ProfileHeaderProps {
|
||||
name: string;
|
||||
isVerified: boolean;
|
||||
title: string;
|
||||
location: string;
|
||||
memberSince: string;
|
||||
bio: string;
|
||||
expertise: string[];
|
||||
}
|
||||
|
||||
export function ProfileHeader({
|
||||
name,
|
||||
isVerified,
|
||||
title,
|
||||
location,
|
||||
memberSince,
|
||||
bio,
|
||||
expertise,
|
||||
}: ProfileHeaderProps) {
|
||||
const [firstName, lastName] = name.split(' ');
|
||||
|
||||
return (
|
||||
<div className="bg-white rounded-[20px] border border-gray-200 p-6">
|
||||
{/* Name and Actions Row */}
|
||||
<div className="flex flex-col lg:flex-row lg:items-start lg:justify-between gap-4 mb-4">
|
||||
<div>
|
||||
{/* Name and Verification */}
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<h1 className="text-[18px] text-[#00293d] font-[family-name:var(--font-fractul)]">
|
||||
<span className="font-bold">{firstName}</span>{' '}
|
||||
<span className="font-normal">{lastName}</span>
|
||||
</h1>
|
||||
{isVerified && (
|
||||
<>
|
||||
<Image
|
||||
src="/assets/icons/verified-icon.svg"
|
||||
alt="Verified"
|
||||
width={15}
|
||||
height={14}
|
||||
/>
|
||||
<span className="text-[14px] text-[#638559] font-medium font-serif">
|
||||
(Verified Expert)
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
<button className="p-1 hover:bg-gray-100 rounded transition-colors">
|
||||
<Image
|
||||
src="/assets/icons/edit-pencil-orange-icon.svg"
|
||||
alt="Edit name"
|
||||
width={19}
|
||||
height={19}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Title */}
|
||||
<p className="text-[#00293d] text-sm mb-2">{title}</p>
|
||||
|
||||
{/* Location and Member Since */}
|
||||
<div className="flex items-center gap-4 text-sm text-[#00293d]">
|
||||
<span className="flex items-center gap-1 text-[#e58625] font-medium">
|
||||
<Image
|
||||
src="/assets/icons/location-icon.svg"
|
||||
alt="Location"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
{location}
|
||||
</span>
|
||||
<span className="flex items-center gap-1">
|
||||
<Image
|
||||
src="/assets/icons/calendar-icon.svg"
|
||||
alt="Calendar"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
Member Since {memberSince}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="relative overflow-visible">
|
||||
<Button
|
||||
variant="action"
|
||||
size="sm"
|
||||
leftIcon={
|
||||
<Image
|
||||
src="/assets/icons/message-icon.svg"
|
||||
alt="Message"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
}
|
||||
>
|
||||
Message
|
||||
</Button>
|
||||
<span className="absolute -top-2 -right-2 w-3 h-3 bg-red-500 rounded-full border-2 border-white z-10"></span>
|
||||
</div>
|
||||
<div className="relative overflow-visible">
|
||||
<Button
|
||||
variant="action"
|
||||
size="sm"
|
||||
leftIcon={
|
||||
<Image
|
||||
src="/assets/icons/clipboard-icon.svg"
|
||||
alt="Requests"
|
||||
width={16}
|
||||
height={16}
|
||||
/>
|
||||
}
|
||||
>
|
||||
Requests
|
||||
</Button>
|
||||
<span className="absolute -top-2 -right-2 w-3 h-3 bg-red-500 rounded-full border-2 border-white z-10"></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bio */}
|
||||
<p className="text-[#00293d] text-sm leading-relaxed mb-4">{bio}</p>
|
||||
|
||||
{/* Expertise Tags */}
|
||||
<div>
|
||||
<p className="font-bold text-[#00293d] text-sm mb-2">Expertise:</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{expertise.map((tag, idx) => (
|
||||
<Tag key={idx}>{tag}</Tag>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -4,7 +4,6 @@ export { Tag } from './Tag';
|
||||
export { InfoCard } from './InfoCard';
|
||||
export { SpecializationCard } from './SpecializationCard';
|
||||
export { ProfileSidebar } from './ProfileSidebar';
|
||||
export { ProfileHeader } from './ProfileHeader';
|
||||
export { ProfileCard } from './ProfileCard';
|
||||
export { ExperienceSection } from './ExperienceSection';
|
||||
export { SpecializationSection } from './SpecializationSection';
|
||||
|
||||
90
src/app/(agent)/agent/network/component/InvitationCard.tsx
Normal file
90
src/app/(agent)/agent/network/component/InvitationCard.tsx
Normal file
@@ -0,0 +1,90 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
|
||||
interface InvitationCardProps {
|
||||
id: string;
|
||||
name: string;
|
||||
avatar: string;
|
||||
description: string;
|
||||
mutualConnection?: string;
|
||||
onAccept?: (id: string) => void;
|
||||
onIgnore?: (id: string) => void;
|
||||
}
|
||||
|
||||
export function InvitationCard({
|
||||
id,
|
||||
name,
|
||||
avatar,
|
||||
description,
|
||||
mutualConnection,
|
||||
onAccept,
|
||||
onIgnore,
|
||||
}: InvitationCardProps) {
|
||||
return (
|
||||
<div className="flex flex-col sm:flex-row items-start sm:items-center gap-4 py-4">
|
||||
{/* Avatar */}
|
||||
<div className="flex-shrink-0">
|
||||
<Image
|
||||
src={avatar}
|
||||
alt={name}
|
||||
width={80}
|
||||
height={80}
|
||||
className="rounded-full object-cover w-[80px] h-[80px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Content */}
|
||||
<div className="flex-1 min-w-0">
|
||||
{/* Name with verified icon */}
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<h3 className="font-serif font-bold text-[14px] leading-[19px] text-[#00293D]">
|
||||
{name}
|
||||
</h3>
|
||||
<Image
|
||||
src="/assets/icons/shield-verified-icon.svg"
|
||||
alt="Verified"
|
||||
width={19}
|
||||
height={19}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<p className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D] mb-1">
|
||||
{description}
|
||||
</p>
|
||||
|
||||
{/* Mutual Connection */}
|
||||
{mutualConnection && (
|
||||
<div className="flex items-center gap-2">
|
||||
<Image
|
||||
src="/assets/icons/chain-icon.svg"
|
||||
alt="Connection"
|
||||
width={18}
|
||||
height={18}
|
||||
/>
|
||||
<span className="font-serif font-normal text-[14px] leading-[19px] text-[#00293D]">
|
||||
Mutual Connection With {mutualConnection}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<div className="flex items-center gap-3 flex-shrink-0">
|
||||
<button
|
||||
onClick={() => onIgnore?.(id)}
|
||||
className="h-[27px] px-4 rounded-[15px] border border-[#00293d] font-serif font-light text-[14px] text-[#00293D] hover:bg-[#00293d]/5 transition-colors cursor-pointer"
|
||||
>
|
||||
Ignore
|
||||
</button>
|
||||
<button
|
||||
onClick={() => onAccept?.(id)}
|
||||
className="h-[27px] px-4 rounded-[15px] bg-[#e58625] font-fractul font-medium text-[14px] text-[#00293D] hover:bg-[#d47920] transition-colors cursor-pointer"
|
||||
>
|
||||
Accept
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
56
src/app/(agent)/agent/network/component/NetworkSidebar.tsx
Normal file
56
src/app/(agent)/agent/network/component/NetworkSidebar.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
'use client';
|
||||
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface NavItem {
|
||||
label: string;
|
||||
href: string;
|
||||
icon: string;
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
const navItems: NavItem[] = [
|
||||
{
|
||||
label: 'Connections',
|
||||
href: '/agent/network/connections',
|
||||
icon: '/assets/icons/people-icon.svg',
|
||||
isActive: true,
|
||||
},
|
||||
];
|
||||
|
||||
export function NetworkSidebar() {
|
||||
return (
|
||||
<div className="border border-[#00293d] rounded-[7px] p-4 w-full lg:w-[280px] bg-white h-fit">
|
||||
<h2 className="font-fractul font-medium text-[20px] leading-[24px] text-[#00293D] mb-4">
|
||||
Manage my network
|
||||
</h2>
|
||||
|
||||
<div className="w-full h-0 border-t border-[#00293d]/30 mb-4" />
|
||||
|
||||
<nav className="space-y-3">
|
||||
{navItems.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className={`flex items-center gap-3 py-2 px-1 rounded transition-colors cursor-pointer ${
|
||||
item.isActive
|
||||
? 'text-[#00293D]'
|
||||
: 'text-[#00293D]/70 hover:text-[#00293D]'
|
||||
}`}
|
||||
>
|
||||
<Image
|
||||
src={item.icon}
|
||||
alt={item.label}
|
||||
width={31}
|
||||
height={31}
|
||||
/>
|
||||
<span className="font-serif font-normal text-[14px] leading-[19px]">
|
||||
{item.label}
|
||||
</span>
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
81
src/app/(agent)/agent/network/page.tsx
Normal file
81
src/app/(agent)/agent/network/page.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
'use client';
|
||||
|
||||
import { NetworkSidebar } from './component/NetworkSidebar';
|
||||
import { InvitationCard } from './component/InvitationCard';
|
||||
|
||||
// Mock data for invitations
|
||||
const invitations = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Sathish R',
|
||||
avatar: '/assets/icons/user-placeholder-icon.svg',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
mutualConnection: 'Anvar',
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Ragunath',
|
||||
avatar: '/assets/icons/user-placeholder-icon.svg',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
mutualConnection: 'Anvar',
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: 'Sabari',
|
||||
avatar: '/assets/icons/user-placeholder-icon.svg',
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.',
|
||||
mutualConnection: 'Anvar',
|
||||
},
|
||||
];
|
||||
|
||||
export default function NetworkPage() {
|
||||
const handleAccept = (id: string) => {
|
||||
console.log('Accepted invitation:', id);
|
||||
};
|
||||
|
||||
const handleIgnore = (id: string) => {
|
||||
console.log('Ignored invitation:', id);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col lg:flex-row gap-6">
|
||||
{/* Left Sidebar */}
|
||||
<NetworkSidebar />
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="flex-1">
|
||||
{/* Header Card */}
|
||||
<div className="border border-[#00293d]/10 rounded-[15px] px-6 py-4 mb-4 bg-white">
|
||||
<h1 className="font-fractul font-bold text-[15px] leading-[18px] text-[#00293D]">
|
||||
Manage my network
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Invitations Card */}
|
||||
<div className="border border-[#00293d]/10 rounded-[15px] bg-white">
|
||||
{/* Invitations Header */}
|
||||
<div className="flex items-center justify-between px-6 py-4 border-b border-[#00293d]/10">
|
||||
<h2 className="font-fractul font-bold text-[14px] leading-[17px] text-[#00293D]">
|
||||
Invitations ({invitations.length})
|
||||
</h2>
|
||||
<button className="font-fractul font-bold text-[14px] leading-[17px] text-[#00293D] hover:text-[#e58625] transition-colors cursor-pointer">
|
||||
Show All
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Invitations List */}
|
||||
<div className="px-6 divide-y divide-[#00293d]/10">
|
||||
{invitations.map((invitation) => (
|
||||
<InvitationCard
|
||||
key={invitation.id}
|
||||
{...invitation}
|
||||
onAccept={handleAccept}
|
||||
onIgnore={handleIgnore}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export function Button({
|
||||
className = '',
|
||||
...props
|
||||
}: ButtonProps) {
|
||||
const baseStyles = 'font-medium transition-all duration-200 inline-flex items-center justify-center';
|
||||
const baseStyles = 'font-medium transition-all duration-200 inline-flex items-center justify-center cursor-pointer';
|
||||
|
||||
const variants = {
|
||||
primary: 'bg-[#f5a623] text-white hover:bg-[#e09620] active:bg-[#c98a1c] rounded-lg',
|
||||
|
||||
Reference in New Issue
Block a user