remove core from pages

This commit is contained in:
2025-12-18 19:14:50 +01:00
parent 9814d9682c
commit 4a3087ae35
35 changed files with 552 additions and 354 deletions

View File

@@ -7,12 +7,12 @@ import Button from '@/components/ui/Button';
import Card from '@/components/ui/Card';
import Heading from '@/components/ui/Heading';
import { useEffectiveDriverId } from '@/hooks/useEffectiveDriverId';
import type { DriverDTO } from '@core/racing/application/dto/DriverDTO';
import { useServices } from '@/lib/services/ServiceProvider';
import type {
ProfileOverviewAchievementViewModel,
ProfileOverviewSocialHandleViewModel,
ProfileOverviewViewModel
} from '@/lib/view-models/ProfileOverviewViewModel';
DriverProfileAchievementViewModel,
DriverProfileSocialHandleViewModel,
DriverProfileViewModel
} from '@/lib/view-models/DriverProfileViewModel';
import {
Activity,
Award,
@@ -67,7 +67,7 @@ function getCountryFlag(countryCode: string): string {
return '🏁';
}
function getRarityColor(rarity: ProfileOverviewAchievementViewModel['rarity']) {
function getRarityColor(rarity: DriverProfileAchievementViewModel['rarity']) {
switch (rarity) {
case 'common':
return 'text-gray-400 bg-gray-400/10 border-gray-400/30';
@@ -80,7 +80,7 @@ function getRarityColor(rarity: ProfileOverviewAchievementViewModel['rarity']) {
}
}
function getAchievementIcon(icon: ProfileOverviewAchievementViewModel['icon']) {
function getAchievementIcon(icon: DriverProfileAchievementViewModel['icon']) {
switch (icon) {
case 'trophy':
return Trophy;
@@ -97,7 +97,7 @@ function getAchievementIcon(icon: ProfileOverviewAchievementViewModel['icon']) {
}
}
function getSocialIcon(platform: ProfileOverviewSocialHandleViewModel['platform']) {
function getSocialIcon(platform: DriverProfileSocialHandleViewModel['platform']) {
switch (platform) {
case 'twitter':
return Twitter;
@@ -110,7 +110,7 @@ function getSocialIcon(platform: ProfileOverviewSocialHandleViewModel['platform'
}
}
function getSocialColor(platform: ProfileOverviewSocialHandleViewModel['platform']) {
function getSocialColor(platform: DriverProfileSocialHandleViewModel['platform']) {
switch (platform) {
case 'twitter':
return 'hover:text-sky-400 hover:bg-sky-400/10';
@@ -256,12 +256,13 @@ export default function ProfilePage() {
const router = useRouter();
const searchParams = useSearchParams();
const tabParam = searchParams.get('tab') as ProfileTab | null;
const [driver, setDriver] = useState<DriverDTO | null>(null);
const { driverService, mediaService } = useServices();
const [profileData, setProfileData] = useState<DriverProfileViewModel | null>(null);
const [loading, setLoading] = useState(true);
const [editMode, setEditMode] = useState(false);
const [activeTab, setActiveTab] = useState<ProfileTab>(tabParam || 'overview');
const [profileData, setProfileData] = useState<ProfileOverviewViewModel | null>(null);
const [friendRequestSent, setFriendRequestSent] = useState(false);
const effectiveDriverId = useEffectiveDriverId();
@@ -271,24 +272,8 @@ export default function ProfilePage() {
const loadData = async () => {
try {
const currentDriverId = effectiveDriverId;
// Use GetProfileOverviewUseCase to load all profile data
const profileUseCase = getGetProfileOverviewUseCase();
const profileViewModel = await profileUseCase.execute({ driverId: currentDriverId });
if (profileViewModel && profileViewModel.currentDriver) {
// Set driver from ViewModel instead of direct repository access
const driverData: DriverDTO = {
id: profileViewModel.currentDriver.id,
name: profileViewModel.currentDriver.name,
iracingId: profileViewModel.currentDriver.iracingId ?? '',
country: profileViewModel.currentDriver.country,
bio: profileViewModel.currentDriver.bio || '',
joinedAt: profileViewModel.currentDriver.joinedAt,
};
setDriver(driverData);
setProfileData(profileViewModel);
}
const profileViewModel = await driverService.getDriverProfile(currentDriverId);
setProfileData(profileViewModel);
} catch (error) {
console.error('Failed to load profile:', error);
} finally {
@@ -296,7 +281,7 @@ export default function ProfilePage() {
}
};
void loadData();
}, [effectiveDriverId]);
}, [effectiveDriverId, driverService]);
// Update URL when tab changes
useEffect(() => {
@@ -319,24 +304,13 @@ export default function ProfilePage() {
}
}, [tabParam]);
const handleSaveSettings = async (updates: Partial<DriverDTO>) => {
if (!driver) return;
const handleSaveSettings = async (updates: { bio?: string; country?: string }) => {
if (!profileData?.currentDriver) return;
try {
const updateProfileUseCase = getUpdateDriverProfileUseCase();
const input: { driverId: string; bio?: string; country?: string } = { driverId: driver.id };
if (typeof updates.bio === 'string') {
input.bio = updates.bio;
}
if (typeof updates.country === 'string') {
input.country = updates.country;
}
const updatedDto = await updateProfileUseCase.execute(input);
if (updatedDto) {
setDriver(updatedDto);
setEditMode(false);
}
const updatedProfile = await driverService.updateProfile(updates);
setProfileData(updatedProfile);
setEditMode(false);
} catch (error) {
console.error('Failed to update profile:', error);
}
@@ -360,7 +334,7 @@ export default function ProfilePage() {
);
}
if (!driver) {
if (!profileData?.currentDriver) {
return (
<div className="max-w-4xl mx-auto px-4">
<div className="text-center mb-8">
@@ -387,12 +361,12 @@ export default function ProfilePage() {
}
// Extract data from profileData ViewModel
const currentDriver = profileData?.currentDriver || null;
const stats = profileData?.stats || null;
const finishDistribution = profileData?.finishDistribution || null;
const teamMemberships = profileData?.teamMemberships || [];
const socialSummary = profileData?.socialSummary || { friendsCount: 0, friends: [] };
const extendedProfile = profileData?.extendedProfile;
const currentDriver = profileData.currentDriver;
const stats = profileData.stats;
const finishDistribution = profileData.finishDistribution;
const teamMemberships = profileData.teamMemberships;
const socialSummary = profileData.socialSummary;
const extendedProfile = profileData.extendedProfile;
const globalRank = currentDriver?.globalRank || null;
// Show edit mode
@@ -405,7 +379,7 @@ export default function ProfilePage() {
Cancel
</Button>
</div>
<ProfileSettings driver={driver} onSave={handleSaveSettings} />
<ProfileSettings driver={profileData.currentDriver} onSave={handleSaveSettings} />
</div>
);
}
@@ -428,8 +402,8 @@ export default function ProfilePage() {
<div className="w-28 h-28 md:w-36 md:h-36 rounded-2xl bg-gradient-to-br from-primary-blue to-purple-600 p-1 shadow-xl shadow-primary-blue/20">
<div className="w-full h-full rounded-xl overflow-hidden bg-iron-gray">
<Image
src={getImageService().getDriverAvatar(driver.id)}
alt={driver.name}
src={mediaService.getDriverAvatar(currentDriver.id)}
alt={currentDriver.name}
width={144}
height={144}
className="w-full h-full object-cover"
@@ -443,9 +417,9 @@ export default function ProfilePage() {
{/* Driver Info */}
<div className="flex-1 min-w-0">
<div className="flex flex-wrap items-center gap-3 mb-2">
<h1 className="text-3xl md:text-4xl font-bold text-white">{driver.name}</h1>
<span className="text-4xl" aria-label={`Country: ${driver.country}`}>
{getCountryFlag(driver.country)}
<h1 className="text-3xl md:text-4xl font-bold text-white">{currentDriver.name}</h1>
<span className="text-4xl" aria-label={`Country: ${currentDriver.country}`}>
{getCountryFlag(currentDriver.country)}
</span>
{teamMemberships.length > 0 && teamMemberships[0] && (
<span className="px-3 py-1 bg-purple-600/20 text-purple-400 rounded-full text-sm font-semibold border border-purple-600/30">
@@ -488,11 +462,11 @@ export default function ProfilePage() {
<div className="flex flex-wrap items-center gap-4 text-sm text-gray-400">
<span className="flex items-center gap-1.5">
<Globe className="w-4 h-4" />
iRacing: {driver.iracingId}
iRacing: {currentDriver.iracingId}
</span>
<span className="flex items-center gap-1.5">
<Calendar className="w-4 h-4" />
Joined {new Date(driver.joinedAt).toLocaleDateString('en-US', { month: 'short', year: 'numeric' })}
Joined {new Date(currentDriver.joinedAt).toLocaleDateString('en-US', { month: 'short', year: 'numeric' })}
</span>
{extendedProfile && (
<span className="flex items-center gap-1.5">
@@ -564,13 +538,13 @@ export default function ProfilePage() {
</div>
{/* Bio Section */}
{driver.bio && (
{currentDriver.bio && (
<Card>
<h2 className="text-lg font-semibold text-white mb-3 flex items-center gap-2">
<User className="w-5 h-5 text-primary-blue" />
About
</h2>
<p className="text-gray-300 leading-relaxed">{driver.bio}</p>
<p className="text-gray-300 leading-relaxed">{currentDriver.bio}</p>
</Card>
)}
@@ -910,7 +884,7 @@ export default function ProfilePage() {
>
<div className="w-8 h-8 rounded-full overflow-hidden bg-gradient-to-br from-primary-blue to-purple-600">
<Image
src={getImageService().getDriverAvatar(friend.id)}
src={mediaService.getDriverAvatar(friend.id)}
alt={friend.name}
width={32}
height={32}
@@ -932,13 +906,13 @@ export default function ProfilePage() {
</>
)}
{activeTab === 'history' && driver && (
{activeTab === 'history' && currentDriver && (
<Card>
<h2 className="text-lg font-semibold text-white mb-4 flex items-center gap-2">
<History className="w-5 h-5 text-red-400" />
Race History
</h2>
<ProfileRaceHistory driverId={driver.id} />
<ProfileRaceHistory driverId={currentDriver.id} />
</Card>
)}