153 lines
5.8 KiB
TypeScript
153 lines
5.8 KiB
TypeScript
import styles from './Dateien.module.css'
|
|
import { IoAddCircleOutline } from "react-icons/io5";
|
|
import DateienUpload from '../../components/Dateien/DateienHinzufügen/DateienUploadTool';
|
|
import DateienAll from '../../components/Dateien/DateienAll';
|
|
import DateienUploads from '../../components/Dateien/DateienUploads';
|
|
import DateienCreated from '../../components/Dateien/DateienCreated';
|
|
import DateienShared from '../../components/Dateien/DateienShared';
|
|
import { useState } from 'react';
|
|
import { useUserFiles, useFileOperations } from '../../hooks/useFiles';
|
|
import { motion, AnimatePresence } from "framer-motion";
|
|
|
|
// Tab types
|
|
type TabType = 'alle' | 'uploads' | 'erstellt' | 'geteilt';
|
|
|
|
function Dateien() {
|
|
const { files, loading, error, refetch, removeFileOptimistically } = useUserFiles();
|
|
const [isUploadOpen, setIsUploadOpen] = useState(false);
|
|
const { uploadError, downloadError, deleteError } = useFileOperations();
|
|
const [activeTab, setActiveTab] = useState<TabType>('alle');
|
|
|
|
// Tab configuration
|
|
const tabs = [
|
|
{ key: 'alle' as TabType, label: 'Alle Dateien' },
|
|
{ key: 'uploads' as TabType, label: 'Meine Uploads' },
|
|
{ key: 'erstellt' as TabType, label: 'Erstellte Dateien' },
|
|
{ key: 'geteilt' as TabType, label: 'Geteilte Dateien' }
|
|
];
|
|
|
|
// Single function to handle file refresh
|
|
const refreshFiles = () => {
|
|
console.log('Refreshing files list');
|
|
refetch();
|
|
};
|
|
|
|
const handleFileUpload = async (file: File) => {
|
|
console.log('File upload completed:', file.name);
|
|
};
|
|
|
|
const handleUploadClose = () => {
|
|
setIsUploadOpen(false);
|
|
// Refresh files when upload modal is closed
|
|
setTimeout(() => {
|
|
refreshFiles();
|
|
}, 300);
|
|
};
|
|
|
|
const handleFileDeleted = () => {
|
|
refreshFiles();
|
|
};
|
|
|
|
// Render the appropriate component based on active tab
|
|
const renderActiveTabContent = () => {
|
|
const commonProps = {
|
|
files,
|
|
onFileDeleted: handleFileDeleted,
|
|
onOptimisticDelete: removeFileOptimistically
|
|
};
|
|
|
|
switch (activeTab) {
|
|
case 'alle':
|
|
return <DateienAll {...commonProps} />;
|
|
case 'uploads':
|
|
return <DateienUploads {...commonProps} />;
|
|
case 'erstellt':
|
|
return <DateienCreated {...commonProps} />;
|
|
case 'geteilt':
|
|
return <DateienShared {...commonProps} />;
|
|
default:
|
|
return <DateienAll {...commonProps} />;
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className={styles.dateienContainer}>
|
|
{/* Combined Header with Tabs and Add Button */}
|
|
<motion.div
|
|
className={styles.combinedHeader}
|
|
initial={{ opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
transition={{ duration: 0.3 }}
|
|
>
|
|
<div className={styles.tabButtonDiv}>
|
|
{tabs.map((tab) => (
|
|
<div key={tab.key} className={styles.tabButtonWrapper}>
|
|
<motion.button
|
|
className={`${styles.tabButton} ${
|
|
activeTab === tab.key ? styles.tabButtonActive : styles.tabButtonInactive
|
|
}`}
|
|
onClick={() => setActiveTab(tab.key)}
|
|
whileHover={{ scale: 1.02 }}
|
|
whileTap={{ scale: 0.98 }}
|
|
>
|
|
{tab.label}
|
|
</motion.button>
|
|
<AnimatePresence>
|
|
{activeTab === tab.key && (
|
|
<motion.div
|
|
className={styles.tabUnderline}
|
|
initial={{ opacity: 0, width: "0%" }}
|
|
animate={{ opacity: 1, width: "100%" }}
|
|
exit={{ opacity: 0, width: "0%" }}
|
|
transition={{ duration: 0.3, ease: "easeOut" }}
|
|
/>
|
|
)}
|
|
</AnimatePresence>
|
|
</div>
|
|
))}
|
|
</div>
|
|
|
|
<button
|
|
className={styles.datei_hinzufügen_button}
|
|
onClick={() => setIsUploadOpen(true)}
|
|
>
|
|
<IoAddCircleOutline className={styles.add_icon}/>
|
|
Datei hinzufügen
|
|
</button>
|
|
</motion.div>
|
|
<div className={styles.horizontalLineLight}></div>
|
|
|
|
<div className={styles.contentArea}>
|
|
<DateienUpload
|
|
isOpen={isUploadOpen}
|
|
onClose={handleUploadClose}
|
|
onFileUpload={handleFileUpload}
|
|
/>
|
|
|
|
{(uploadError || downloadError || deleteError) && (
|
|
<p className={styles.error}>
|
|
{uploadError || downloadError || deleteError}
|
|
</p>
|
|
)}
|
|
|
|
{loading && <p>Loading files...</p>}
|
|
{error && <p>Error: {error}</p>}
|
|
|
|
{!loading && !error && (
|
|
<motion.div
|
|
key={activeTab} // Force re-render when tab changes
|
|
initial={{ opacity: 0}}
|
|
animate={{ opacity: 1 }}
|
|
exit={{ opacity: 0 }}
|
|
transition={{ duration: 0.3 }}
|
|
>
|
|
{renderActiveTabContent()}
|
|
</motion.div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default Dateien;
|
|
|