mirror of
https://github.com/skidoodle/budgetable.git
synced 2025-02-15 03:39:14 +01:00
i forgor
This commit is contained in:
parent
bcfa0f92a6
commit
dedb1c0628
16 changed files with 316 additions and 239 deletions
|
@ -3,15 +3,8 @@ import { TableRow, TableCell } from "@/components/ui/table";
|
|||
import Link from "next/link";
|
||||
import StatusBadge from "@/components/status-badge";
|
||||
import DeleteDialog from "@/components/delete-dialog";
|
||||
|
||||
interface Budgetable {
|
||||
id: string;
|
||||
title: string;
|
||||
price: number;
|
||||
link: string;
|
||||
note?: string;
|
||||
status: "Paid" | "Unpaid";
|
||||
}
|
||||
import { useState } from 'react';
|
||||
import { Budgetable } from '@/lib/utils';
|
||||
|
||||
interface TRowProps {
|
||||
row: Budgetable;
|
||||
|
@ -26,7 +19,7 @@ interface TRowProps {
|
|||
toggleStatus: (row: Budgetable) => Promise<void>;
|
||||
}
|
||||
|
||||
const TRow: React.FC<TRowProps> = ({
|
||||
const TRow = ({
|
||||
row,
|
||||
isEditing,
|
||||
setData,
|
||||
|
@ -34,101 +27,113 @@ const TRow: React.FC<TRowProps> = ({
|
|||
handleSave,
|
||||
handleDeleteRow,
|
||||
toggleStatus,
|
||||
}) => (
|
||||
<TableRow
|
||||
className={`transition-opacity ${
|
||||
recentlyUpdatedRowId === row.id ? "blur-sm opacity-50" : ""
|
||||
}`}
|
||||
>
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
value={row.title}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id ? { ...item, title: e.target.value } : item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, { ...row })}
|
||||
/>
|
||||
) : (
|
||||
<span>{row.title}</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
type="number"
|
||||
value={row.price}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id
|
||||
? { ...item, price: Number.parseFloat(e.target.value) || 0 }
|
||||
: item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, { ...row })}
|
||||
/>
|
||||
) : (
|
||||
<span>{row.price.toLocaleString()} HUF</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
value={row.link}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id ? { ...item, link: e.target.value } : item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, { ...row })}
|
||||
/>
|
||||
) : row.link ? (
|
||||
<Link
|
||||
href={row.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-500 underline"
|
||||
>
|
||||
Visit
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-gray-400 italic">No link</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
value={row.note || ""}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id ? { ...item, note: e.target.value } : item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, { ...row })}
|
||||
/>
|
||||
) : (
|
||||
<span>{row.note || "-"}</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<StatusBadge status={row.status} toggleStatus={() => toggleStatus(row)} />
|
||||
</TableCell>
|
||||
{isEditing && (
|
||||
}: TRowProps) => {
|
||||
const [originalRow, setOriginalRow] = useState<Budgetable>(row);
|
||||
|
||||
const handleInputFocus = () => {
|
||||
setOriginalRow({...row});
|
||||
};
|
||||
|
||||
return (
|
||||
<TableRow
|
||||
className={`transition-opacity ${
|
||||
recentlyUpdatedRowId === row.id ? "blur-sm opacity-50" : ""
|
||||
}`}
|
||||
>
|
||||
<TableCell>
|
||||
<DeleteDialog onConfirm={() => handleDeleteRow(row.id)} />
|
||||
{isEditing ? (
|
||||
<Input
|
||||
value={row.title}
|
||||
onFocus={handleInputFocus}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id ? { ...item, title: e.target.value } : item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, originalRow)}
|
||||
/>
|
||||
) : (
|
||||
<span>{row.title}</span>
|
||||
)}
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
);
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
type="number"
|
||||
value={row.price}
|
||||
onFocus={handleInputFocus}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id
|
||||
? { ...item, price: Number.parseFloat(e.target.value) || 0 }
|
||||
: item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, originalRow)}
|
||||
/>
|
||||
) : (
|
||||
<span>{row.price.toLocaleString()} HUF</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
value={row.link}
|
||||
onFocus={handleInputFocus}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id ? { ...item, link: e.target.value } : item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, originalRow)}
|
||||
/>
|
||||
) : row.link ? (
|
||||
<Link
|
||||
href={row.link}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-blue-500 underline"
|
||||
>
|
||||
Visit
|
||||
</Link>
|
||||
) : (
|
||||
<span className="text-gray-400 italic">No link</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
{isEditing ? (
|
||||
<Input
|
||||
value={row.note || ""}
|
||||
onFocus={handleInputFocus}
|
||||
onChange={(e) =>
|
||||
setData((prev) =>
|
||||
prev.map((item) =>
|
||||
item.id === row.id ? { ...item, note: e.target.value } : item,
|
||||
),
|
||||
)
|
||||
}
|
||||
onBlur={() => handleSave(row, originalRow)}
|
||||
/>
|
||||
) : (
|
||||
<span>{row.note || "-"}</span>
|
||||
)}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<StatusBadge status={row.status} toggleStatus={() => toggleStatus(row)} />
|
||||
</TableCell>
|
||||
{isEditing && (
|
||||
<TableCell>
|
||||
<DeleteDialog onConfirm={() => handleDeleteRow(row.id)} />
|
||||
</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
);
|
||||
};
|
||||
|
||||
export default TRow;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue