This commit is contained in:
skidoodle 2024-12-30 17:32:55 +01:00
parent bcfa0f92a6
commit dedb1c0628
Signed by: albert
GPG key ID: A06E3070D7D55BF2
16 changed files with 316 additions and 239 deletions

View file

@ -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;