109 lines
3.3 KiB
JavaScript
109 lines
3.3 KiB
JavaScript
import React, { useState, useEffect } from 'react';
|
|
import { Box, RefreshCw, Plus } from 'lucide-react';
|
|
import AppCard from '../components/AppCard';
|
|
import AddAppModal from '../components/AddAppModal';
|
|
import { getApps, getGiteaCommits } from '../utils/api';
|
|
|
|
export default function AppsPage({ apps, onRefresh }) {
|
|
const [commitsMap, setCommitsMap] = useState({});
|
|
const [showAddModal, setShowAddModal] = useState(false);
|
|
|
|
useEffect(() => {
|
|
// Charger les commits pour chaque app
|
|
apps.forEach((app) => {
|
|
const owner = app.giteaOwner || 'manus-admin';
|
|
const repo = app.giteaRepo || app.id;
|
|
getGiteaCommits(owner, repo)
|
|
.then((res) => {
|
|
setCommitsMap((prev) => ({
|
|
...prev,
|
|
[app.id]: res.data,
|
|
}));
|
|
})
|
|
.catch(() => {
|
|
// Ignorer les erreurs Gitea pour les apps sans dépôt
|
|
});
|
|
});
|
|
}, [apps]);
|
|
|
|
const handleAddSuccess = () => {
|
|
setShowAddModal(false);
|
|
// Rafraîchir la liste après un délai pour laisser le temps au health check
|
|
setTimeout(() => {
|
|
if (onRefresh) onRefresh();
|
|
}, 5000);
|
|
// Rafraîchir encore après 15s
|
|
setTimeout(() => {
|
|
if (onRefresh) onRefresh();
|
|
}, 15000);
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-6">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between">
|
|
<div>
|
|
<h2 className="text-2xl font-bold text-white flex items-center gap-3">
|
|
<Box className="w-7 h-7 text-primary-400" />
|
|
Applications
|
|
</h2>
|
|
<p className="text-gray-400 mt-1">
|
|
Gérez et surveillez vos applications déployées
|
|
</p>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<button onClick={onRefresh} className="btn-secondary flex items-center gap-2">
|
|
<RefreshCw className="w-4 h-4" />
|
|
Rafraîchir
|
|
</button>
|
|
<button
|
|
onClick={() => setShowAddModal(true)}
|
|
className="btn-primary flex items-center gap-2"
|
|
>
|
|
<Plus className="w-4 h-4" />
|
|
Ajouter une application
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Apps List */}
|
|
{apps.length === 0 ? (
|
|
<div className="card p-12 text-center">
|
|
<Box className="w-12 h-12 text-gray-600 mx-auto mb-4" />
|
|
<h3 className="text-lg font-medium text-gray-400">
|
|
Aucune application
|
|
</h3>
|
|
<p className="text-gray-600 mt-2">
|
|
Les applications déployées apparaîtront ici
|
|
</p>
|
|
<button
|
|
onClick={() => setShowAddModal(true)}
|
|
className="btn-primary mt-4 inline-flex items-center gap-2"
|
|
>
|
|
<Plus className="w-4 h-4" />
|
|
Ajouter votre première application
|
|
</button>
|
|
</div>
|
|
) : (
|
|
<div className="space-y-4">
|
|
{apps.map((app) => (
|
|
<AppCard
|
|
key={app.id}
|
|
app={app}
|
|
commits={commitsMap[app.id] || []}
|
|
onRefresh={onRefresh}
|
|
/>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{/* Add App Modal */}
|
|
<AddAppModal
|
|
isOpen={showAddModal}
|
|
onClose={() => setShowAddModal(false)}
|
|
onSuccess={handleAddSuccess}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|