Mission Tab Refactor Big
This commit is contained in:
parent
2876806a3b
commit
75d4ace765
@ -2,7 +2,7 @@
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { FileIcon, Calendar, Eye, MapPin, Users, Clock, ThumbsUp, Languages, ArrowLeft } from "lucide-react";
|
||||
import { FileIcon, Calendar, Eye, MapPin, Users, Clock, ThumbsUp, Languages, ArrowLeft, FileText } from "lucide-react";
|
||||
import { useToast } from "@/components/ui/use-toast";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import Link from "next/link";
|
||||
@ -41,6 +41,10 @@ interface Mission {
|
||||
createdAt: string;
|
||||
creator: User;
|
||||
missionUsers: any[];
|
||||
rocketChatChannelId?: string | null;
|
||||
outlineCollectionId?: string | null;
|
||||
giteaRepositoryUrl?: string | null;
|
||||
leantimeProjectId?: string | null;
|
||||
}
|
||||
|
||||
export default function MissionTabDetailPage() {
|
||||
@ -135,6 +139,23 @@ export default function MissionTabDetailPage() {
|
||||
};
|
||||
};
|
||||
|
||||
// Function to sanitize mission name (same logic as N8N)
|
||||
const sanitizeMissionName = (name: string): string => {
|
||||
if (!name || typeof name !== "string") return "unnamed-mission";
|
||||
return name.toLowerCase()
|
||||
.split("")
|
||||
.map(c => {
|
||||
if (c >= "a" && c <= "z") return c;
|
||||
if (c >= "0" && c <= "9") return c;
|
||||
if (c === " " || c === "-") return c;
|
||||
return "";
|
||||
})
|
||||
.join("")
|
||||
.split(" ")
|
||||
.filter(Boolean)
|
||||
.join("-");
|
||||
};
|
||||
|
||||
// Loading state
|
||||
if (loading) {
|
||||
return (
|
||||
@ -361,6 +382,120 @@ export default function MissionTabDetailPage() {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Ressources Métiers */}
|
||||
{(mission.rocketChatChannelId || mission.outlineCollectionId || mission.giteaRepositoryUrl || mission.leantimeProjectId) && (
|
||||
<div className="bg-white rounded-lg shadow-sm border border-gray-100 p-6">
|
||||
<h2 className="text-lg font-semibold text-gray-900 mb-4">Ressources Métiers</h2>
|
||||
<div className="space-y-3">
|
||||
{mission.rocketChatChannelId && (() => {
|
||||
// Build RocketChat URL: parole.slm-lab.net/channel/[channelId]
|
||||
// If it's already a full URL, use it; otherwise build from ID
|
||||
const rocketChatUrl = mission.rocketChatChannelId.startsWith('http')
|
||||
? mission.rocketChatChannelId
|
||||
: `https://parole.slm-lab.net/channel/${mission.rocketChatChannelId}`;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={rocketChatUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-3 p-3 bg-blue-50 rounded-lg border border-blue-100 hover:bg-blue-100 transition-colors cursor-pointer"
|
||||
>
|
||||
<div className="w-10 h-10 bg-blue-100 rounded-full flex items-center justify-center">
|
||||
<Users className="h-5 w-5 text-blue-600" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="font-medium text-gray-900">Tenant de Parole</p>
|
||||
<p className="text-sm text-gray-500">Espace de discussion</p>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
})()}
|
||||
|
||||
{mission.outlineCollectionId && (() => {
|
||||
// Build Outline URL: chapitre.slm-lab.net/collection/[collectionId]
|
||||
// If it's already a full URL, use it; otherwise build from ID
|
||||
const outlineUrl = mission.outlineCollectionId.startsWith('http')
|
||||
? mission.outlineCollectionId
|
||||
: `https://chapitre.slm-lab.net/collection/${mission.outlineCollectionId}`;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={outlineUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-3 p-3 bg-purple-50 rounded-lg border border-purple-100 hover:bg-purple-100 transition-colors cursor-pointer"
|
||||
>
|
||||
<div className="w-10 h-10 bg-purple-100 rounded-full flex items-center justify-center">
|
||||
<FileText className="h-5 w-5 text-purple-600" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="font-medium text-gray-900">Tenant du Chapitre</p>
|
||||
<p className="text-sm text-gray-500">Espace de documentation</p>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
})()}
|
||||
|
||||
{mission.giteaRepositoryUrl && (() => {
|
||||
// Use mission name (sanitized) as repo name
|
||||
const repoName = sanitizeMissionName(mission.name);
|
||||
|
||||
// Get Gitea owner from environment variable (default: "alma")
|
||||
// Note: In Next.js client components, we need NEXT_PUBLIC_ prefix
|
||||
const giteaOwner = typeof window !== 'undefined'
|
||||
? (process.env.NEXT_PUBLIC_GITEA_OWNER || 'alma')
|
||||
: 'alma';
|
||||
|
||||
// Build the correct Gitea URL: gite.slm-lab.net/owner/repo-name
|
||||
const giteaUrl = `https://gite.slm-lab.net/${giteaOwner}/${repoName}`;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={giteaUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-3 p-3 bg-green-50 rounded-lg border border-green-100 hover:bg-green-100 transition-colors cursor-pointer"
|
||||
>
|
||||
<div className="w-10 h-10 bg-green-100 rounded-full flex items-center justify-center">
|
||||
<FileIcon className="h-5 w-5 text-green-600" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="font-medium text-gray-900">Tenant du Code</p>
|
||||
<p className="text-sm text-gray-500">Espace pour les codes sources</p>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
})()}
|
||||
|
||||
{mission.leantimeProjectId && (() => {
|
||||
// Build Leantime URL: agilite.slm-lab.net/projects/showProject/[projectId]
|
||||
// If it's already a full URL, use it; otherwise build from ID
|
||||
const leantimeUrl = mission.leantimeProjectId.startsWith('http')
|
||||
? mission.leantimeProjectId
|
||||
: `https://agilite.slm-lab.net/projects/showProject/${mission.leantimeProjectId}`;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={leantimeUrl}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-3 p-3 bg-amber-50 rounded-lg border border-amber-100 hover:bg-amber-100 transition-colors cursor-pointer"
|
||||
>
|
||||
<div className="w-10 h-10 bg-amber-100 rounded-full flex items-center justify-center">
|
||||
<Calendar className="h-5 w-5 text-amber-600" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<p className="font-medium text-gray-900">Tenant des Devoirs</p>
|
||||
<p className="text-sm text-gray-500">Espace d'organisation</p>
|
||||
</div>
|
||||
</a>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user