= {
@@ -80,18 +79,6 @@ export function ProjectRow({ project }: { project: ProjectWithPayments }) {
)}
- |
-
-
-
- |
-
{eurPerHour === null ? (
—
diff --git a/src/components/admin/tabs/CommentsTab.tsx b/src/components/admin/tabs/CommentsTab.tsx
deleted file mode 100644
index 41666f5..0000000
--- a/src/components/admin/tabs/CommentsTab.tsx
+++ /dev/null
@@ -1,109 +0,0 @@
-import { postAdminComment } from "@/app/admin/clients/[id]/actions";
-import { Button } from "@/components/ui/button";
-import { Textarea } from "@/components/ui/textarea";
-import type { Comment } from "@/db/schema";
-import type { ClientFullDetail } from "@/lib/admin-queries";
-
-type Props = {
- comments: Comment[];
- phases: ClientFullDetail["phases"];
- clientId: string;
-};
-
-export async function CommentsTab({ comments, phases, clientId }: Props) {
- // Build entity label map for display (phases, tasks, deliverables, and general)
- const entityLabels: Record = {
- [clientId]: "Messaggio generale",
- };
- for (const phase of phases) {
- entityLabels[phase.id] = `Fase: ${phase.title}`;
- for (const task of phase.tasks) {
- entityLabels[task.id] = `Task: ${task.title}`;
- for (const d of task.deliverables) {
- entityLabels[d.id] = `Deliverable: ${d.title}`;
- }
- }
- }
-
- // Build list of entities the admin can reply on
- const entities: Array<{ id: string; type: string; label: string }> = [
- { id: clientId, type: "general", label: "Messaggio generale" },
- ];
- for (const phase of phases) {
- entities.push({ id: phase.id, type: "phase", label: `Fase: ${phase.title}` });
- for (const task of phase.tasks) {
- entities.push({ id: task.id, type: "task", label: `Task: ${task.title}` });
- for (const d of task.deliverables) {
- entities.push({
- id: d.id,
- type: "deliverable",
- label: `Deliverable: ${d.title}`,
- });
- }
- }
- }
-
- return (
-
- {/* Comment list */}
- {comments.length === 0 && (
- Nessun commento ancora.
- )}
-
- {comments.map((c) => (
-
-
-
- {c.author === "admin" ? "iamcavalli" : "Cliente"} —{" "}
- {entityLabels[c.entity_id] ?? c.entity_id}
-
- {c.body}
-
-
- ))}
-
-
- {/* Admin reply form */}
-
-
- );
-}
diff --git a/src/lib/admin-queries.ts b/src/lib/admin-queries.ts
index 02fb457..e4fcde0 100644
--- a/src/lib/admin-queries.ts
+++ b/src/lib/admin-queries.ts
@@ -477,8 +477,8 @@ export type ProjectWithPayments = {
archived: boolean;
created_at: Date;
payments: Array<{ id: string; label: string; status: string; amount: string }>;
- activeTimerEntryId: string | null;
- activeTimerStartedAt: Date | null;
+ // Niente timer attivo qui: la lista non lo mostra più, si avvia e si ferma
+ // dentro il progetto. `totalTrackedSeconds` resta perché serve al €/h.
totalTrackedSeconds: number;
};
@@ -506,21 +506,12 @@ export async function getAllProjectsWithPayments(
const projectIds = visible.map((p) => p.id);
const clientIds = [...new Set(visible.map((p) => p.client_id))];
- const [allPayments, activeEntries, totals, parentClients] = await Promise.all([
+ const [allPayments, totals, parentClients] = await Promise.all([
db
.select()
.from(payments)
.where(inArray(payments.project_id, projectIds)),
- db
- .select({
- id: time_entries.id,
- project_id: time_entries.project_id,
- started_at: time_entries.started_at,
- })
- .from(time_entries)
- .where(isNull(time_entries.ended_at)),
-
db
.select({
project_id: time_entries.project_id,
@@ -538,7 +529,6 @@ export async function getAllProjectsWithPayments(
return visible.map((project) => {
const projectPayments = allPayments.filter((p) => p.project_id === project.id);
- const activeEntry = activeEntries.find((e) => e.project_id === project.id);
const totalRow = totals.find((t) => t.project_id === project.id);
const parentClient = parentClients.find((c) => c.id === project.client_id);
@@ -555,8 +545,6 @@ export async function getAllProjectsWithPayments(
status: p.status,
amount: String(p.amount),
})),
- activeTimerEntryId: activeEntry?.id ?? null,
- activeTimerStartedAt: activeEntry?.started_at ?? null,
totalTrackedSeconds: totalRow ? parseInt(totalRow.total) : 0,
};
});
@@ -570,7 +558,8 @@ export type ProjectFullDetail = {
payments: Payment[];
documents: Document[];
notes: Note[];
- comments: Comment[];
+ // I commenti NON stanno qui: si leggono e si risponde da /admin/conversazioni,
+ // che li aggrega per cliente con l'etichetta dell'entità di origine.
quoteItems: QuoteItemWithLabel[];
activeServices: Service[];
activeTimerEntryId: string | null;
@@ -734,16 +723,6 @@ export async function getProjectFullDetail(id: string): Promise d.id)];
- const commentsRows =
- allEntityIds.length === 0
- ? []
- : await db
- .select()
- .from(comments)
- .where(inArray(comments.entity_id, allEntityIds))
- .orderBy(asc(comments.created_at));
-
const phasesWithTasks = phasesRows.map((phase) => ({
...phase,
tasks: tasksRows
@@ -780,7 +759,6 @@ export async function getProjectFullDetail(id: string): Promise |