feat(web): standardize loading on shared skeleton recipes; retire '…' + empty status divs (#53)

This commit is contained in:
2026-06-08 06:50:57 +02:00
parent d0da77a004
commit 0d4026a968
8 changed files with 59 additions and 66 deletions
+15 -13
View File
@@ -7,6 +7,7 @@ import { DeleteConfirmDialog } from "../components/delete-confirm-dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ListSkeleton } from "@/components/ui/skeletons";
export function VocabularyList() {
const { t } = useTranslation();
@@ -50,17 +51,17 @@ export function VocabularyList() {
</p>
)}
</form>
<ul className="flex-1 overflow-auto">
{isLoading && (
<li className="p-3 text-sm text-muted-foreground"></li>
)}
{isError && (
<li className="p-3 text-sm text-destructive">{t("vocab.loadError")}</li>
)}
{data?.length === 0 && (
<li className="p-3 text-sm text-muted-foreground">{t("vocab.empty")}</li>
)}
{data?.map((v) => (
{isLoading ? (
<ListSkeleton className="flex-1 overflow-auto" />
) : (
<ul className="flex-1 overflow-auto">
{isError && (
<li className="p-3 text-sm text-destructive">{t("vocab.loadError")}</li>
)}
{data?.length === 0 && (
<li className="p-3 text-sm text-muted-foreground">{t("vocab.empty")}</li>
)}
{data?.map((v) => (
<li key={v.id} className="flex items-center gap-1 border-b pr-2">
{editingId === v.id ? (
<form
@@ -115,8 +116,9 @@ export function VocabularyList() {
</>
)}
</li>
))}
</ul>
))}
</ul>
)}
</div>
);
}
+16 -14
View File
@@ -10,6 +10,7 @@ import { TermRow } from "./term-row";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { ListSkeleton } from "@/components/ui/skeletons";
type LabelInput = components["schemas"]["LabelInput"];
@@ -62,20 +63,21 @@ export function VocabularyTerms() {
<div className="mb-2 label-caption">
{t("vocab.terms")}
</div>
<ul className="mb-4">
{isLoading && (
<li className="text-sm text-muted-foreground"></li>
)}
{isError && (
<li className="text-sm text-destructive">{t("vocab.loadError")}</li>
)}
{!isLoading && !isError && terms?.length === 0 && (
<li className="text-sm text-muted-foreground">{t("vocab.noTerms")}</li>
)}
{terms?.map((term) => (
<TermRow key={term.id} vocabularyId={id} term={term} lang={lang} />
))}
</ul>
{isLoading ? (
<ListSkeleton className="mb-4" rows={5} />
) : (
<ul className="mb-4">
{isError && (
<li className="text-sm text-destructive">{t("vocab.loadError")}</li>
)}
{!isError && terms?.length === 0 && (
<li className="text-sm text-muted-foreground">{t("vocab.noTerms")}</li>
)}
{terms?.map((term) => (
<TermRow key={term.id} vocabularyId={id} term={term} lang={lang} />
))}
</ul>
)}
<form onSubmit={onAdd} className="space-y-2 border-t pt-3">
<div className="text-sm font-medium">{t("vocab.addTerm")}</div>
<LabelEditor value={labels} onChange={setLabels} />