ooooeee
This commit is contained in:
@@ -3,7 +3,7 @@ import { notFound } from "next/navigation";
|
||||
import type { Metadata } from "next";
|
||||
import { getPlantWithDiseases } from "@/lib/api/diseases-db";
|
||||
import { getEmojiForCategory, getPlantDescription } from "@/lib/display-helpers";
|
||||
import type { Disease, CausalAgentType, Severity } from "@/lib/types";
|
||||
import DiseaseCards from "./DiseaseCards";
|
||||
|
||||
interface Props {
|
||||
params: Promise<{ plantId: string }>;
|
||||
@@ -33,171 +33,6 @@ export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||||
};
|
||||
}
|
||||
|
||||
// ─── Severity badge ───
|
||||
|
||||
function SeverityBadge({ severity }: { severity: Severity }) {
|
||||
const colors: Record<Severity, string> = {
|
||||
low: "bg-leaf-green-100 text-leaf-green-800 dark:bg-leaf-green-900/40 dark:text-leaf-green-300",
|
||||
moderate:
|
||||
"bg-warning-amber-100 text-warning-amber-800 dark:bg-warning-amber-900/40 dark:text-warning-amber-300",
|
||||
high: "bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-300",
|
||||
critical: "bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-300",
|
||||
};
|
||||
|
||||
const labels: Record<Severity, string> = {
|
||||
low: "Low",
|
||||
moderate: "Moderate",
|
||||
high: "High",
|
||||
critical: "Critical",
|
||||
};
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${colors[severity]}`}
|
||||
>
|
||||
{severity === "critical" ? "🚨 " : ""}
|
||||
{labels[severity]} Severity
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Disease type badge ───
|
||||
|
||||
function TypeBadge({ type }: { type: CausalAgentType }) {
|
||||
const colors: Record<CausalAgentType, string> = {
|
||||
fungal: "bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-300",
|
||||
bacterial: "bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-300",
|
||||
viral: "bg-pink-100 text-pink-800 dark:bg-pink-900/40 dark:text-pink-300",
|
||||
environmental: "bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-300",
|
||||
};
|
||||
|
||||
return (
|
||||
<span
|
||||
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${colors[type]}`}
|
||||
>
|
||||
{type === "environmental" ? "Environmental" : type.charAt(0).toUpperCase() + type.slice(1)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Disease card ───
|
||||
|
||||
function DiseaseCard({ disease }: { disease: Disease }) {
|
||||
return (
|
||||
<div
|
||||
id={`disease-${disease.id}`}
|
||||
className="rounded-xl border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 overflow-hidden shadow-sm hover:shadow-md transition-shadow"
|
||||
>
|
||||
{/* Card header */}
|
||||
<div className="p-5 sm:p-6">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3 mb-3">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-zinc-900 dark:text-zinc-100">
|
||||
{disease.name}
|
||||
</h3>
|
||||
{disease.scientificName && (
|
||||
<p className="text-sm text-zinc-500 dark:text-zinc-400 italic mt-0.5">
|
||||
{disease.scientificName}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<TypeBadge type={disease.causalAgentType} />
|
||||
<SeverityBadge severity={disease.severity} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Disease image */}
|
||||
{disease.imageUrl && (
|
||||
<div className="mb-4 rounded-lg overflow-hidden border border-zinc-200 dark:border-zinc-700">
|
||||
<img
|
||||
src={disease.imageUrl}
|
||||
alt={`${disease.name} symptoms on ${disease.plantId}`}
|
||||
className="w-full h-48 sm:h-64 object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<p className="text-sm text-zinc-600 dark:text-zinc-300 leading-relaxed mb-4">
|
||||
{disease.description}
|
||||
</p>
|
||||
|
||||
{/* Details grid */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
{/* Symptoms */}
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold uppercase tracking-wider text-red-600 dark:text-red-400 mb-2 flex items-center gap-1">
|
||||
<span aria-hidden="true">⚠️</span> Symptoms
|
||||
</h4>
|
||||
<ul className="space-y-1.5">
|
||||
{disease.symptoms.map((symptom, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="flex items-start gap-2 text-sm text-zinc-600 dark:text-zinc-300"
|
||||
>
|
||||
<span className="mt-1 shrink-0 h-1.5 w-1.5 rounded-full bg-red-400 dark:bg-red-500" />
|
||||
{symptom}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Causes */}
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold uppercase tracking-wider text-orange-600 dark:text-orange-400 mb-2 flex items-center gap-1">
|
||||
<span aria-hidden="true">🔍</span> Causes
|
||||
</h4>
|
||||
<ul className="space-y-1.5">
|
||||
{disease.causes.map((cause, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="flex items-start gap-2 text-sm text-zinc-600 dark:text-zinc-300"
|
||||
>
|
||||
<span className="mt-1 shrink-0 h-1.5 w-1.5 rounded-full bg-orange-400 dark:bg-orange-500" />
|
||||
{cause}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Treatment Steps */}
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold uppercase tracking-wider text-leaf-green-600 dark:text-leaf-green-400 mb-2 flex items-center gap-1">
|
||||
<span aria-hidden="true">💊</span> Treatment Steps
|
||||
</h4>
|
||||
<ol className="space-y-1.5 list-decimal list-inside">
|
||||
{disease.treatment.map((step, i) => (
|
||||
<li key={i} className="text-sm text-zinc-600 dark:text-zinc-300">
|
||||
{step}
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
{/* Prevention Tips */}
|
||||
<div>
|
||||
<h4 className="text-xs font-semibold uppercase tracking-wider text-leaf-green-600 dark:text-leaf-green-400 mb-2 flex items-center gap-1">
|
||||
<span aria-hidden="true">🛡️</span> Prevention Tips
|
||||
</h4>
|
||||
<ul className="space-y-1.5">
|
||||
{disease.prevention.map((tip, i) => (
|
||||
<li
|
||||
key={i}
|
||||
className="flex items-start gap-2 text-sm text-zinc-600 dark:text-zinc-300"
|
||||
>
|
||||
<span className="mt-1 shrink-0 h-1.5 w-1.5 rounded-full bg-leaf-green-400 dark:bg-leaf-green-500" />
|
||||
{tip}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── Plant Detail Page ───
|
||||
|
||||
export default async function PlantDetailPage({ params }: Props) {
|
||||
@@ -307,11 +142,7 @@ export default async function PlantDetailPage({ params }: Props) {
|
||||
</p>
|
||||
|
||||
{diseases.length > 0 ? (
|
||||
<div className="space-y-6">
|
||||
{diseases.map((disease) => (
|
||||
<DiseaseCard key={disease.id} disease={disease} />
|
||||
))}
|
||||
</div>
|
||||
<DiseaseCards diseases={diseases} />
|
||||
) : (
|
||||
<div className="rounded-xl border border-dashed border-zinc-300 dark:border-zinc-700 p-10 text-center">
|
||||
<span className="text-4xl block mb-3" aria-hidden="true">
|
||||
|
||||
Reference in New Issue
Block a user