feat: implement Project Management with Gantt Chart, Milestones, and CRM enhancements

This commit is contained in:
2026-03-01 00:26:59 +01:00
parent 4b5609a75e
commit 6444cf1e81
47 changed files with 15312 additions and 7373 deletions

View File

@@ -41,9 +41,11 @@ export const AiAnalyzeButton: React.FC = () => {
throw new Error(result.error || "Analysis failed");
}
toast.success(result.message || "AI analysis completed successfully!");
// Refresh the page to show the new media items in the relationship field
router.refresh();
toast.success(
result.message ||
"Analysis started in background. The page will update when finished.",
);
// Removed router.refresh() here because the background task takes ~60s
} catch (error) {
console.error("Analysis error:", error);
toast.error(
@@ -59,23 +61,41 @@ export const AiAnalyzeButton: React.FC = () => {
if (!id) return null; // Only show on existing documents, not when creating new
return (
<div style={{ marginBottom: "1rem", marginTop: "1rem" }}>
<div style={{ marginBottom: "2rem", marginTop: "1rem" }}>
<button
onClick={handleAnalyze}
disabled={isAnalyzing || !hasWebsite}
className="btn btn--style-primary btn--icon-style-none btn--size-medium"
type="button"
style={{
background: "var(--theme-elevation-150)",
border: "1px solid var(--theme-elevation-200)",
color: "var(--theme-text)",
padding: "8px 16px",
borderRadius: "4px",
fontSize: "14px",
cursor: isAnalyzing || !hasWebsite ? "not-allowed" : "pointer",
display: "inline-flex",
alignItems: "center",
gap: "8px",
opacity: isAnalyzing || !hasWebsite ? 0.6 : 1,
fontWeight: "500",
}}
>
{isAnalyzing ? "Analyzing Website..." : "Trigger AI Website Analysis"}
{isAnalyzing ? "✨ AI analysiert..." : " AI Website Analyse starten"}
</button>
<p
style={{
fontSize: "0.8rem",
color: "var(--theme-elevation-400)",
marginTop: "0.5rem",
fontSize: "0.85rem",
color: "var(--theme-elevation-600)",
marginTop: "0.75rem",
maxWidth: "400px",
lineHeight: "1.4",
}}
>
Requires a valid website URL saved on this account.
<strong>Note:</strong> This will crawl the website, generate a strategy
concept, and create a budget estimation. The resulting PDFs will be
attached to the "AI Reports" field below.
</p>
</div>
);

View File

@@ -0,0 +1,88 @@
"use client";
import React, { useState } from "react";
import { useDocumentInfo } from "@payloadcms/ui";
import { toast } from "@payloadcms/ui";
import { useRouter } from "next/navigation";
export const ConvertInquiryButton: React.FC = () => {
const { id } = useDocumentInfo();
const router = useRouter();
const [isConverting, setIsConverting] = useState(false);
const handleConvert = async (e: React.MouseEvent) => {
e.preventDefault();
if (!id) return;
setIsConverting(true);
try {
const response = await fetch(`/api/inquiries/${id}/convert-to-lead`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.error || "Conversion failed");
}
toast.success(result.message || "Successfully converted to Lead!");
// Redirect to the new account
router.push(`/admin/collections/crm-accounts/${result.accountId}`);
} catch (error) {
console.error("Conversion error:", error);
toast.error(
error instanceof Error
? error.message
: "An error occurred during conversion",
);
} finally {
setIsConverting(false);
}
};
if (!id) return null; // Only show on existing documents
return (
<div style={{ marginBottom: "2rem", marginTop: "1rem" }}>
<button
onClick={handleConvert}
disabled={isConverting}
className="btn btn--style-primary btn--icon-style-none btn--size-medium"
type="button"
style={{
background: "var(--theme-elevation-150)",
border: "1px solid var(--theme-elevation-200)",
color: "var(--theme-text)",
padding: "8px 16px",
borderRadius: "4px",
fontSize: "14px",
cursor: isConverting ? "not-allowed" : "pointer",
display: "inline-flex",
alignItems: "center",
gap: "8px",
opacity: isConverting ? 0.6 : 1,
fontWeight: "500",
}}
>
{isConverting ? "🔄 Konvertiere..." : "🎯 Lead in CRM anlegen"}
</button>
<p
style={{
fontSize: "0.85rem",
color: "var(--theme-elevation-600)",
marginTop: "0.75rem",
maxWidth: "400px",
lineHeight: "1.4",
}}
>
<strong>Info:</strong> Creates a new CRM Account, Contact, and logs the
inquiry message in the CRM Journal.
</p>
</div>
);
};