Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 43 additions & 3 deletions src/components/Dashboard/listings/ListingCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

import React, { useState, useEffect } from 'react';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { SkillListing } from '@/types/skillListing';
import { BadgeCheck, Edit, Trash2, Eye, Users, Shield, CheckCircle, Clock, XCircle } from 'lucide-react';
import { BadgeCheck, Edit, Trash2, Eye, Users, Shield, CheckCircle, Clock, XCircle, AlertCircle } from 'lucide-react';
import { useAuth } from '@/lib/context/AuthContext';
import { processAvatarUrl } from '@/utils/avatarUtils';

Expand All @@ -19,15 +20,33 @@ interface ListingCardProps {

const ListingCard: React.FC<ListingCardProps> = ({ listing, onDelete, onEdit }) => {
const { user } = useAuth();
const router = useRouter();
const [isOwner, setIsOwner] = useState(false);
const [showDetailsModal, setShowDetailsModal] = useState(false);
const [kycStatus, setKycStatus] = useState<string | null>(null);

useEffect(() => {
// Check if the current user is the owner of this listing
if (user && listing) {
setIsOwner(user._id === listing.userId);
}
}, [user, listing]);

// Fetch KYC status for the listing user
useEffect(() => {
async function fetchKycStatus() {
try {
const res = await fetch(`/api/kyc/status?userId=${listing.userId}`);
const data = await res.json();
setKycStatus(data.success ? data.status : null);
} catch (err) {
setKycStatus(null);
}
}
if (listing.userId) {
fetchKycStatus();
}
}, [listing.userId]);

const formatDate = (dateString: string) => {
const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' };
Expand Down Expand Up @@ -89,7 +108,17 @@ const ListingCard: React.FC<ListingCardProps> = ({ listing, onDelete, onEdit })
<div className="flex-1 min-w-0">
<h3 className="font-medium text-gray-800 flex items-center truncate">
<span className="truncate">{listing.userDetails.firstName} {listing.userDetails.lastName}</span>
<BadgeCheck className="w-4 h-4 ml-1 text-blue-500 flex-shrink-0" />
{(kycStatus === 'Accepted' || kycStatus === 'Approved') ? (
<BadgeCheck className="w-4 h-4 ml-1 text-blue-500 flex-shrink-0" />
) : (
<button
onClick={() => router.push('/dashboard?component=setting')}
title="Click to verify your account"
className="inline-flex"
>
<AlertCircle className="w-4 h-4 ml-1 text-orange-500 flex-shrink-0 hover:text-orange-600 transition-colors cursor-pointer" />
</button>
)}
</h3>
<p className="text-xs text-gray-500 truncate">
{formatDate(listing.createdAt)}
Expand Down Expand Up @@ -226,7 +255,18 @@ const ListingCard: React.FC<ListingCardProps> = ({ listing, onDelete, onEdit })
<div className="flex-1">
<h3 className="font-semibold text-gray-800 flex items-center">
{listing.userDetails.firstName} {listing.userDetails.lastName}
<BadgeCheck className="w-5 h-5 ml-2 text-blue-500" />
{(kycStatus === 'Accepted' || kycStatus === 'Approved') ? (
<BadgeCheck className="w-5 h-5 ml-2 text-blue-500" />
) : (
<button
onClick={() => router.push('/dashboard?component=setting')}
className="ml-2 px-3 py-1 text-sm bg-orange-100 text-orange-600 rounded-full flex items-center hover:bg-orange-200 transition-colors"
title="Click to verify your account"
>
<AlertCircle className="w-4 h-4 mr-1" />
Verify
</button>
)}
</h3>
<p className="text-sm text-gray-500">
Posted on {formatDate(listing.createdAt)}
Expand Down
28 changes: 25 additions & 3 deletions src/components/Dashboard/matches/MatchCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use client';

import React from 'react';
import React, { useState, useEffect } from 'react';
import Image from 'next/image';
import { SkillMatch } from '@/types/skillMatch';
import { BadgeCheck, ArrowRightLeft, Eye, MessageCircle, Clock, CheckCircle, XCircle, Award, Calendar } from 'lucide-react';
import { BadgeCheck, ArrowRightLeft, Eye, MessageCircle, Clock, CheckCircle, XCircle, Award, Calendar, AlertCircle } from 'lucide-react';
import { processAvatarUrl } from '@/utils/avatarUtils';

interface MatchCardProps {
Expand All @@ -12,6 +12,24 @@ interface MatchCardProps {
}

const MatchCard: React.FC<MatchCardProps> = ({ match, onClick }) => {
const [otherUserKycStatus, setOtherUserKycStatus] = useState<string | null>(null);

// Fetch KYC status for the other user
useEffect(() => {
async function fetchKycStatus() {
try {
const res = await fetch(`/api/kyc/status?userId=${match.otherUser.userId}`);
const data = await res.json();
setOtherUserKycStatus(data.success ? data.status : null);
} catch (err) {
setOtherUserKycStatus(null);
}
}
if (match.otherUser.userId) {
fetchKycStatus();
}
}, [match.otherUser.userId]);

// Format date
const formatDate = (dateString: string) => {
const options: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' };
Expand Down Expand Up @@ -222,7 +240,11 @@ const MatchCard: React.FC<MatchCardProps> = ({ match, onClick }) => {
>
{match.otherUser.firstName} {match.otherUser.lastName}
</span>
<BadgeCheck className="w-4 h-4 ml-1 text-blue-500 flex-shrink-0" />
{(otherUserKycStatus === 'Accepted' || otherUserKycStatus === 'Approved') ? (
<BadgeCheck className="w-4 h-4 ml-1 text-blue-500 flex-shrink-0" />
) : (
<AlertCircle className="w-4 h-4 ml-1 text-orange-500 flex-shrink-0" title="Not Verified" />
)}
</h3>
</div>

Expand Down
27 changes: 24 additions & 3 deletions src/components/Dashboard/matches/MatchDetailsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
'use client';

import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';
import Image from 'next/image';
import { useRouter } from 'next/navigation';
import { SkillMatch } from '@/types/skillMatch';
import { useToast } from '@/lib/context/ToastContext';
import { updateMatchStatus, acceptMatchAndCreateChatRoom } from '@/services/matchService';
import { fetchUserChatRooms } from '@/services/chatApiServices';
import { useAuth } from '@/lib/context/AuthContext';
import { BadgeCheck, ArrowRight, MessageCircle, Calendar, XCircle, CheckCircle, Clock, Award, BarChart3, Target } from 'lucide-react';
import { BadgeCheck, ArrowRight, MessageCircle, Calendar, XCircle, CheckCircle, Clock, Award, BarChart3, Target, AlertCircle } from 'lucide-react';
import { processAvatarUrl } from '@/utils/avatarUtils';

interface MatchDetailsModalProps {
Expand Down Expand Up @@ -92,6 +92,23 @@ const MatchDetailsModal: React.FC<MatchDetailsModalProps> = ({ match, currentUse
const [showAcceptConfirmation, setShowAcceptConfirmation] = useState(false);
const [showRejectConfirmation, setShowRejectConfirmation] = useState(false);
const [openingChat, setOpeningChat] = useState(false);
const [otherUserKycStatus, setOtherUserKycStatus] = useState<string | null>(null);

// Fetch KYC status for the other user
useEffect(() => {
async function fetchKycStatus() {
try {
const res = await fetch(`/api/kyc/status?userId=${match.otherUser.userId}`);
const data = await res.json();
setOtherUserKycStatus(data.success ? data.status : null);
} catch (err) {
setOtherUserKycStatus(null);
}
}
if (match.otherUser.userId) {
fetchKycStatus();
}
}, [match.otherUser.userId]);

// Format date
const formatDate = (dateString: string) => {
Expand Down Expand Up @@ -411,7 +428,11 @@ const MatchDetailsModal: React.FC<MatchDetailsModalProps> = ({ match, currentUse
<div>
<h3 className="font-semibold text-gray-800 flex items-center">
{match.otherUser.firstName} {match.otherUser.lastName}
<BadgeCheck className="w-4 h-4 ml-1 text-blue-500" />
{(otherUserKycStatus === 'Accepted' || otherUserKycStatus === 'Approved') ? (
<BadgeCheck className="w-4 h-4 ml-1 text-blue-500" />
) : (
<AlertCircle className="w-4 h-4 ml-1 text-orange-500" title="Not Verified" />
)}
</h3>
<p className="text-xs text-gray-600">Partner Profile</p>
</div>
Expand Down
Loading