StickerAI-Front/src/screens/StickerPacks.tsx

288 lines
9.6 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import styles from './StickerPacks.module.css';
import { stickerService } from '../services/stickerService';
import { getCurrentUserId } from '../constants/user';
// Функция для удаления дописанной части из названия стикерпака
const cleanPackTitle = (title: string): string => {
// Ищем часть "| by @username" и удаляем её
const parts = title.split(' | by @');
return parts[0]; // Возвращаем только первую часть (оригинальное название)
};
interface StickerPack {
name: string;
title: string;
thumbnail_url?: string | null;
share_url?: string;
stickers: Array<{
id?: number;
file_id: string;
emoji: string;
position: number;
file_url?: string | null;
}>;
}
const StickerPacks: React.FC = () => {
const navigate = useNavigate();
const [stickerPacks, setStickerPacks] = useState<StickerPack[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [selectedPack, setSelectedPack] = useState<StickerPack | null>(null);
useEffect(() => {
const fetchStickerPacks = async () => {
try {
setLoading(true);
const stickerSets = await stickerService.getUserStickerPacks(getCurrentUserId().toString());
// Для каждого стикерпака получаем детальную информацию, обрабатывая ошибки отдельно
const packsDetails: StickerPack[] = [];
for (const stickerSet of stickerSets) {
try {
const packDetails = await stickerService.getStickerPack(stickerSet.set_name);
packsDetails.push(packDetails);
} catch (packError) {
console.warn(`Не удалось загрузить стикерпак ${stickerSet.set_name}:`, packError);
// Продолжаем загрузку других стикерпаков
}
}
setStickerPacks(packsDetails);
setError(null);
} catch (err) {
console.error('Ошибка при загрузке стикерпаков:', err);
setError('Не удалось загрузить список стикерпаков');
} finally {
setLoading(false);
}
};
fetchStickerPacks();
}, []);
const handleCreateStickerPack = () => {
navigate('/create-sticker-pack');
};
const handleSelectPack = (pack: StickerPack) => {
setSelectedPack(pack);
};
const handleCloseDetails = () => {
setSelectedPack(null);
};
const handleDeletePack = async (packName: string) => {
if (!confirm('Вы уверены, что хотите удалить этот стикерпак?')) {
return;
}
try {
await stickerService.deleteStickerPack(packName);
setStickerPacks(prevPacks => prevPacks.filter(pack => pack.name !== packName));
setSelectedPack(null);
} catch (err) {
console.error('Ошибка при удалении стикерпака:', err);
alert('Не удалось удалить стикерпак');
}
};
const handleOpenInTelegram = () => {
if (selectedPack && selectedPack.share_url) {
window.open(selectedPack.share_url, '_blank');
}
};
const handleDeleteSticker = async (fileId: string) => {
if (!fileId) {
alert('Не удалось определить ID стикера');
return;
}
if (!confirm('Вы уверены, что хотите удалить этот стикер?')) {
return;
}
try {
await stickerService.deleteStickerByFileId(fileId);
// Обновляем список стикеров в выбранном стикерпаке
if (selectedPack) {
const updatedPack = await stickerService.getStickerPack(selectedPack.name);
setSelectedPack(updatedPack);
// Также обновляем стикерпак в общем списке
setStickerPacks(prevPacks =>
prevPacks.map(pack =>
pack.name === selectedPack.name ? updatedPack : pack
)
);
}
} catch (err) {
console.error('Ошибка при удалении стикера:', err);
alert('Не удалось удалить стикер');
}
};
return (
<div className={styles.container}>
<div className={styles.header}>
<h1 className={styles.title}>
Мои стикерпаки
</h1>
<p className={styles.subtitle}>
Создавайте и публикуйте наборы стикеров в Telegram
</p>
</div>
{loading && (
<div className={styles.placeholder}>
<p>Загрузка стикерпаков...</p>
</div>
)}
{error && (
<div className={styles.error}>
<p>{error}</p>
<button
className={styles.retryButton}
onClick={() => window.location.reload()}
>
Повторить
</button>
</div>
)}
{!loading && !error && stickerPacks.length === 0 && (
<div className={styles.placeholder}>
<span className={styles.placeholderIcon}>📦</span>
<p className={styles.placeholderText}>
У вас пока нет стикерпаков
</p>
<button
className={styles.createButton}
onClick={handleCreateStickerPack}
>
Создать стикерпак
</button>
</div>
)}
{!loading && !error && stickerPacks.length > 0 && !selectedPack && (
<>
<div className={styles.packsList}>
{stickerPacks.map((pack, index) => (
<div
key={index}
className={styles.packItem}
onClick={() => handleSelectPack(pack)}
>
<div className={styles.packHeader}>
<h3 className={styles.packTitle}>
Стикерпак: <span className={styles.packTitleName}>{cleanPackTitle(pack.title)}</span>
</h3>
<p className={styles.packStats}>
{pack.stickers ? pack.stickers.length : 0} / 49 стикеров
</p>
</div>
<div className={styles.packStickers}>
{pack.stickers && pack.stickers.map((sticker, idx) => (
<div key={idx} className={styles.stickerPreview}>
{sticker.file_url ? (
<img
src={sticker.file_url}
alt={`Стикер ${idx + 1}`}
className={styles.stickerImage}
/>
) : (
<div className={styles.stickerPlaceholder}>🖼</div>
)}
</div>
))}
</div>
</div>
))}
</div>
<button
className={styles.createButtonFixed}
onClick={handleCreateStickerPack}
>
Создать стикерпак
</button>
</>
)}
{selectedPack && (
<div className={styles.packDetails}>
<div className={styles.detailsHeader}>
<button
className={styles.backButton}
onClick={handleCloseDetails}
>
Назад
</button>
<h2 className={styles.detailsTitle}>{cleanPackTitle(selectedPack.title)}</h2>
<button
className={styles.deleteButton}
onClick={() => handleDeletePack(selectedPack.name)}
>
Удалить
</button>
</div>
<div className={styles.stickersList}>
{selectedPack.stickers && selectedPack.stickers.map((sticker, index) => (
<div key={index} className={styles.stickerItem}>
{sticker.file_url ? (
<img
src={sticker.file_url}
alt={`Стикер ${index + 1}`}
className={styles.stickerImage}
/>
) : (
<div className={styles.stickerImagePlaceholder}>🖼</div>
)}
<div className={styles.stickerEmoji}>{sticker.emoji}</div>
{/* Кнопка удаления стикера */}
<button
className={styles.deleteStickerButton}
onClick={(e) => {
e.stopPropagation(); // Предотвращаем всплытие события
handleDeleteSticker(sticker.file_id);
}}
>
</button>
</div>
))}
</div>
<div className={styles.detailsActions}>
<button
className={styles.addStickerButton}
onClick={() => navigate(`/add-sticker/${selectedPack.name}`)}
>
Добавить стикер
</button>
<button
className={styles.openInTelegramButton}
onClick={handleOpenInTelegram}
>
Открыть в Telegram
</button>
</div>
</div>
)}
</div>
);
};
export default StickerPacks;