chore: auto-commit (23 archivos)

- app.md
- backend/auth.go
- backend/db.go
- backend/dist/assets/index-CPqSy0gZ.js
- backend/dist/index.html
- backend/handlers.go
- backend/main.go
- frontend/src/App.tsx
- frontend/src/api.ts
- frontend/src/components/KanbanCard.tsx
- ...

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-13 18:40:22 +02:00
parent f1ee116d3b
commit a34a8142cc
23 changed files with 2034 additions and 1184 deletions
+87
View File
@@ -0,0 +1,87 @@
import { Box, Divider, Group, Tabs, Text } from "@mantine/core";
import { IconLink, IconMessage, IconPaperclip } from "@tabler/icons-react";
import { useState } from "react";
import type { Card, CardMessage, User } from "../types";
import { CardChatPanel } from "./CardChatPanel";
import { CardLinksPanel } from "./CardLinksPanel";
import { CardForm, CardFormValues } from "./CardForm";
interface Props {
card: Card;
users: User[];
currentUserId?: string;
requesterOptions: string[];
tagOptions: string[];
onSubmit: (v: CardFormValues) => Promise<void> | void;
onCancel: () => void;
}
export function CardEditPanel({
card,
users,
currentUserId,
requesterOptions,
tagOptions,
onSubmit,
onCancel,
}: Props) {
const [messages, setMessages] = useState<CardMessage[]>([]);
const [liveCard, setLiveCard] = useState(card);
const wrappedSubmit = async (v: CardFormValues) => {
setLiveCard((c) => ({ ...c, title: v.title, description: v.description, requester: v.requester, tags: v.tags, assignee_id: v.assignee_id }));
await onSubmit(v);
};
return (
<Group align="stretch" gap="md" wrap="nowrap" style={{ minHeight: 460 }}>
<Box style={{ flex: "1 1 0", minWidth: 320 }}>
<CardForm
users={users}
requesterOptions={requesterOptions}
tagOptions={tagOptions}
initial={{
requester: liveCard.requester,
title: liveCard.title,
description: liveCard.description,
assignee_id: liveCard.assignee_id,
tags: liveCard.tags || [],
}}
submitLabel="Guardar"
onSubmit={wrappedSubmit}
onCancel={onCancel}
/>
</Box>
<Divider orientation="vertical" />
<Box style={{ flex: "1 1 0", minWidth: 320, display: "flex", flexDirection: "column" }}>
<Tabs defaultValue="chat" keepMounted={false} style={{ display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }}>
<Tabs.List>
<Tabs.Tab value="chat" leftSection={<IconMessage size={14} />}>Chat</Tabs.Tab>
<Tabs.Tab value="links" leftSection={<IconLink size={14} />}>Enlaces</Tabs.Tab>
<Tabs.Tab value="files" leftSection={<IconPaperclip size={14} />} disabled>Archivos</Tabs.Tab>
</Tabs.List>
<Box pt="xs" style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column" }}>
<Tabs.Panel value="chat" style={{ flex: 1, minHeight: 0, display: "flex" }}>
<Box style={{ flex: 1, minHeight: 0, display: "flex", flexDirection: "column", width: "100%" }}>
<CardChatPanel
cardId={liveCard.id}
users={users}
currentUserId={currentUserId}
onMessagesChange={setMessages}
/>
</Box>
</Tabs.Panel>
<Tabs.Panel value="links">
<CardLinksPanel card={liveCard} messages={messages} />
</Tabs.Panel>
<Tabs.Panel value="files">
<Text size="sm" c="dimmed" ta="center" p="md">
Proximamente: adjuntos de archivos.
</Text>
</Tabs.Panel>
</Box>
</Tabs>
</Box>
</Group>
);
}