add: shop capes and refactor cape card
This commit is contained in:
@ -20,13 +20,10 @@ import {
|
||||
MenuItem,
|
||||
Alert,
|
||||
CircularProgress,
|
||||
Card,
|
||||
CardContent,
|
||||
CardMedia,
|
||||
Tooltip,
|
||||
CardActions,
|
||||
} from '@mui/material';
|
||||
|
||||
import CapeCard from '../components/CapeCard';
|
||||
|
||||
export default function Profile() {
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const [walkingSpeed, setWalkingSpeed] = useState<number>(0.5);
|
||||
@ -317,63 +314,24 @@ export default function Profile() {
|
||||
}}
|
||||
>
|
||||
<Typography>Ваши плащи</Typography>
|
||||
<Box sx={{ display: 'flex', flexDirection: 'row', gap: 2 }}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: 2,
|
||||
flexWrap: 'wrap',
|
||||
}}
|
||||
>
|
||||
{capes.map((cape) => (
|
||||
<Tooltip arrow title={cape.cape_description}>
|
||||
<Card
|
||||
key={cape.cape_id}
|
||||
sx={{
|
||||
bgcolor: 'rgba(255, 255, 255, 0.05)',
|
||||
width: 200, // фиксированная ширина карточки
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<CardMedia
|
||||
component="img"
|
||||
image={cape.image_url}
|
||||
alt={cape.cape_name}
|
||||
sx={{
|
||||
display: 'block',
|
||||
width: '100%',
|
||||
transform:
|
||||
'scale(2.9) translateX(66px) translateY(32px)',
|
||||
imageRendering: 'pixelated',
|
||||
}}
|
||||
/>
|
||||
<CardContent
|
||||
sx={{ bgcolor: 'rgba(255, 255, 255, 0.05)', pt: '9vh' }}
|
||||
>
|
||||
<Typography sx={{ color: 'white' }}>
|
||||
{cape.cape_name}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
{cape.is_active ? (
|
||||
<CardActions
|
||||
sx={{ display: 'flex', justifyContent: 'center' }}
|
||||
>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ bgcolor: 'red' }}
|
||||
onClick={() => handleDeactivateCape(cape.cape_id)}
|
||||
>
|
||||
Снять
|
||||
</Button>
|
||||
</CardActions>
|
||||
) : (
|
||||
<CardActions
|
||||
sx={{ display: 'flex', justifyContent: 'center' }}
|
||||
>
|
||||
<Button
|
||||
variant="contained"
|
||||
sx={{ bgcolor: 'green' }}
|
||||
onClick={() => handleActivateCape(cape.cape_id)}
|
||||
>
|
||||
Надеть
|
||||
</Button>
|
||||
</CardActions>
|
||||
)}
|
||||
</Card>
|
||||
</Tooltip>
|
||||
<CapeCard
|
||||
key={cape.cape_id}
|
||||
cape={cape}
|
||||
mode="profile"
|
||||
onAction={
|
||||
cape.is_active ? handleDeactivateCape : handleActivateCape
|
||||
}
|
||||
actionDisabled={loading}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</Box>
|
||||
|
@ -1,3 +1,127 @@
|
||||
import { Box } from '@mui/material';
|
||||
import { Typography } from '@mui/material';
|
||||
import CapeCard from '../components/CapeCard';
|
||||
import {
|
||||
Cape,
|
||||
fetchCapes,
|
||||
fetchCapesStore,
|
||||
purchaseCape,
|
||||
StoreCape,
|
||||
} from '../api';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
export default function Shop() {
|
||||
return <div>Shop</div>;
|
||||
const [storeCapes, setStoreCapes] = useState<StoreCape[]>([]);
|
||||
const [userCapes, setUserCapes] = useState<Cape[]>([]);
|
||||
const [username, setUsername] = useState<string>('');
|
||||
const [uuid, setUuid] = useState<string>('');
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
|
||||
// Функция для загрузки плащей из магазина
|
||||
const loadStoreCapes = async () => {
|
||||
try {
|
||||
const capes = await fetchCapesStore();
|
||||
setStoreCapes(capes);
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении плащей магазина:', error);
|
||||
setStoreCapes([]);
|
||||
}
|
||||
};
|
||||
|
||||
// Функция для загрузки плащей пользователя
|
||||
const loadUserCapes = async (username: string) => {
|
||||
try {
|
||||
const userCapes = await fetchCapes(username);
|
||||
setUserCapes(userCapes);
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении плащей пользователя:', error);
|
||||
setUserCapes([]);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePurchaseCape = async (cape_id: string) => {
|
||||
try {
|
||||
await purchaseCape(username, cape_id);
|
||||
await loadUserCapes(username);
|
||||
} catch (error) {
|
||||
console.error('Ошибка при покупке плаща:', error);
|
||||
}
|
||||
};
|
||||
|
||||
// Загружаем данные при монтировании
|
||||
useEffect(() => {
|
||||
const savedConfig = localStorage.getItem('launcher_config');
|
||||
if (savedConfig) {
|
||||
const config = JSON.parse(savedConfig);
|
||||
if (config.uuid && config.username) {
|
||||
setUsername(config.username);
|
||||
setUuid(config.uuid);
|
||||
|
||||
setLoading(true);
|
||||
|
||||
// Загружаем оба списка плащей
|
||||
Promise.all([loadStoreCapes(), loadUserCapes(config.username)]).finally(
|
||||
() => {
|
||||
setLoading(false);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Фильтруем плащи, которые уже куплены пользователем
|
||||
const availableCapes = storeCapes.filter(
|
||||
(storeCape) =>
|
||||
!userCapes.some((userCape) => userCape.cape_id === storeCape.id),
|
||||
);
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2vw',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Typography variant="h4">Shop</Typography>
|
||||
{loading ? (
|
||||
<Typography>Загрузка...</Typography>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '2vw',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
}}
|
||||
>
|
||||
<Typography variant="h6">Доступные плащи</Typography>
|
||||
{availableCapes.length > 0 ? (
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
gap: '2vw',
|
||||
flexWrap: 'wrap',
|
||||
}}
|
||||
>
|
||||
{availableCapes.map((cape) => (
|
||||
<CapeCard
|
||||
key={cape.id}
|
||||
cape={cape}
|
||||
mode="shop"
|
||||
onAction={handlePurchaseCape}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
) : (
|
||||
<Typography>У вас уже есть все доступные плащи!</Typography>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user