![]() Server : Apache/2 System : Linux server-15-235-50-60 5.15.0-164-generic #174-Ubuntu SMP Fri Nov 14 20:25:16 UTC 2025 x86_64 User : gositeme ( 1004) PHP Version : 8.2.29 Disable Function : exec,system,passthru,shell_exec,proc_close,proc_open,dl,popen,show_source,posix_kill,posix_mkfifo,posix_getpwuid,posix_setpgid,posix_setsid,posix_setuid,posix_setgid,posix_seteuid,posix_setegid,posix_uname Directory : /home/gositeme/domains/lavocat.ca/public_html/src/components/ |
import React from 'react';
import { format } from 'date-fns';
import { FiAward, FiEyeOff, FiTrendingUp, FiUnlock } from 'react-icons/fi';
interface DegreeInfo {
degreeNumber: number;
name: string;
title?: string;
description: string;
symbol?: string;
color?: string;
lodgeLevel: string;
isSecret: boolean;
achievedAt?: string;
ceremonyCompleted?: boolean;
privileges?: string[];
}
interface SocietyDegreeCardProps {
currentDegree?: DegreeInfo;
nextDegree?: DegreeInfo & { progressPercentage: number };
userXP: number;
className?: string;
}
const SocietyDegreeCard: React.FC<SocietyDegreeCardProps> = ({
currentDegree,
nextDegree,
userXP,
className = ""
}) => {
const getLodgeLevelColor = (level: string) => {
switch (level) {
case 'BLUE': return 'text-blue-600 bg-blue-100';
case 'RED': return 'text-red-600 bg-red-100';
case 'BLACK': return 'text-gray-800 bg-gray-200';
default: return 'text-gray-600 bg-gray-100';
}
};
const getLodgeLevelGradient = (level: string) => {
switch (level) {
case 'BLUE': return 'from-blue-50 to-indigo-50';
case 'RED': return 'from-red-50 to-pink-50';
case 'BLACK': return 'from-gray-50 to-gray-100';
default: return 'from-gray-50 to-gray-100';
}
};
if (!currentDegree) {
return (
<div className={`bg-gray-50 rounded-lg border-2 border-dashed border-gray-300 p-6 text-center ${className}`}>
<div className="text-4xl mb-2">🌟</div>
<h3 className="text-lg font-semibold text-gray-900 mb-2">Join the Society of Brothers</h3>
<p className="text-gray-600 text-sm">Begin your journey through the 33 degrees of legal mastery</p>
</div>
);
}
return (
<div className={`bg-gradient-to-br ${getLodgeLevelGradient(currentDegree.lodgeLevel)} rounded-lg border border-gray-200 overflow-hidden ${className}`}>
{/* Current Degree Section */}
<div className="p-6">
<div className="flex items-start justify-between mb-4">
<div className="flex items-center space-x-3">
<div className="text-3xl">{currentDegree.symbol || '🎖️'}</div>
<div>
<h3 className="text-xl font-bold text-gray-900">
{currentDegree.degreeNumber}° {currentDegree.name}
</h3>
{currentDegree.title && (
<p className="text-sm font-medium" style={{ color: currentDegree.color || '#6B7280' }}>
{currentDegree.title}
</p>
)}
</div>
</div>
<div className="text-right">
<span className={`inline-flex items-center px-2 py-1 rounded-full text-xs font-medium ${getLodgeLevelColor(currentDegree.lodgeLevel)}`}>
{currentDegree.lodgeLevel} Lodge
{currentDegree.isSecret && <FiEyeOff className="ml-1 w-3 h-3" />}
</span>
{currentDegree.achievedAt && (
<p className="text-xs text-gray-600 mt-1">
Achieved {format(new Date(currentDegree.achievedAt), 'MMM yyyy')}
</p>
)}
</div>
</div>
<p className="text-gray-700 text-sm mb-4">{currentDegree.description}</p>
{/* Ceremony Status */}
{currentDegree.ceremonyCompleted !== undefined && (
<div className="flex items-center space-x-2 mb-4">
<FiAward className={`w-4 h-4 ${currentDegree.ceremonyCompleted ? 'text-green-600' : 'text-orange-600'}`} />
<span className={`text-sm font-medium ${currentDegree.ceremonyCompleted ? 'text-green-600' : 'text-orange-600'}`}>
{currentDegree.ceremonyCompleted ? 'Ceremony Complete' : 'Ceremony Pending'}
</span>
</div>
)}
{/* Privileges */}
{currentDegree.privileges && currentDegree.privileges.length > 0 && (
<div>
<h4 className="text-sm font-medium text-gray-900 mb-2">Privileges Unlocked:</h4>
<div className="grid grid-cols-1 gap-1">
{currentDegree.privileges.slice(0, 3).map((privilege, index) => (
<div key={index} className="flex items-center text-xs text-green-700">
<FiUnlock className="w-3 h-3 mr-2 flex-shrink-0" />
<span className="truncate">{privilege}</span>
</div>
))}
{currentDegree.privileges.length > 3 && (
<p className="text-xs text-gray-600 ml-5">
+{currentDegree.privileges.length - 3} more privileges
</p>
)}
</div>
</div>
)}
</div>
{/* Next Degree Progress */}
{nextDegree && (
<div className="bg-white bg-opacity-50 border-t border-gray-200 px-6 py-4">
<div className="flex items-center justify-between mb-3">
<div className="flex items-center space-x-2">
<div className="text-lg opacity-60">{nextDegree.symbol || '🔒'}</div>
<div>
<h4 className="text-sm font-semibold text-gray-900">
Next: {nextDegree.degreeNumber}° {nextDegree.name}
</h4>
{nextDegree.title && (
<p className="text-xs text-gray-600">{nextDegree.title}</p>
)}
</div>
</div>
<div className="text-right">
<div className="text-sm font-bold text-blue-600">
{nextDegree.progressPercentage.toFixed(0)}%
</div>
<p className="text-xs text-gray-600">Complete</p>
</div>
</div>
{/* Progress Bar */}
<div className="mb-2">
<div className="flex justify-between text-xs text-gray-600 mb-1">
<span>Progress to next degree</span>
<span>{userXP.toLocaleString()} XP</span>
</div>
<div className="w-full bg-gray-200 rounded-full h-2">
<div
className={`h-2 rounded-full transition-all duration-300 ${
nextDegree.progressPercentage >= 100 ? 'bg-green-500' : 'bg-blue-500'
}`}
style={{ width: `${Math.min(nextDegree.progressPercentage, 100)}%` }}
></div>
</div>
</div>
{nextDegree.progressPercentage >= 100 && (
<div className="flex items-center text-green-600 text-xs">
<FiTrendingUp className="w-3 h-3 mr-1" />
Ready for advancement!
</div>
)}
</div>
)}
{/* XP Display */}
<div className="bg-black bg-opacity-5 px-6 py-3 text-center">
<div className="text-lg font-bold text-gray-900">{userXP.toLocaleString()}</div>
<div className="text-xs text-gray-600">Total XP Points</div>
</div>
</div>
);
};
export default SocietyDegreeCard;