loading indicator for editor
This commit is contained in:
parent
47a79cd171
commit
bccd089c7f
@ -117,85 +117,97 @@ export default ({ server_article }: { server_article: Article }) => {
|
|||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"sticky top-4 h-max w-full max-w-md space-y-4 rounded-md border-t-2 bg-muted p-4",
|
"sticky top-4 h-max w-full max-w-md",
|
||||||
loading && "border-t-blue-600",
|
// loading && "border-t-blue-600",
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="relative w-full space-y-4 overflow-hidden rounded-md border-t-2 bg-muted p-4">
|
||||||
<div className="flex items-center gap-2">
|
<div
|
||||||
<Badge variant={"outline"} className="flex items-center gap-1">
|
className={cn(
|
||||||
{!form.formState.isDirty && !loading ? (
|
"saving absolute left-0 right-0 top-0 h-0.5 rounded-full bg-primary",
|
||||||
<>
|
!loading && "hidden",
|
||||||
<CheckCircle className="size-4 text-emerald-600" />
|
)}
|
||||||
<span>Gespeichert</span>
|
/>
|
||||||
</>
|
|
||||||
) : (
|
<div className="flex w-full items-center justify-between">
|
||||||
<>
|
<div className="flex items-center gap-2">
|
||||||
<XCircle className="size-4 text-destructive" />
|
<Badge
|
||||||
<span>Nicht Gespeichert</span>
|
variant={"outline"}
|
||||||
</>
|
className="flex items-center gap-1"
|
||||||
)}
|
>
|
||||||
</Badge>
|
{!form.formState.isDirty && !loading ? (
|
||||||
<span
|
<>
|
||||||
className={cn(
|
<CheckCircle className="size-4 text-emerald-600" />
|
||||||
"text-xs",
|
<span>Gespeichert</span>
|
||||||
published ? "text-emerald-700" : "text-muted-foreground",
|
</>
|
||||||
)}
|
) : (
|
||||||
|
<>
|
||||||
|
<XCircle className="size-4 text-destructive" />
|
||||||
|
<span>Nicht Gespeichert</span>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Badge>
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
"text-xs",
|
||||||
|
published ? "text-emerald-700" : "text-muted-foreground",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{published
|
||||||
|
? "Veröffentlicht"
|
||||||
|
: "Draft (nicht veröffentlicht)"}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Link
|
||||||
|
href={"/editoren-hilfe"}
|
||||||
|
target="_blank"
|
||||||
|
className="size-max scale-90 p-0 text-xs text-muted-foreground"
|
||||||
>
|
>
|
||||||
{published
|
<span>? Hilfe</span>
|
||||||
? "Veröffentlicht"
|
</Link>
|
||||||
: "Draft (nicht veröffentlicht)"}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<Link
|
<FormField
|
||||||
href={"/editoren-hilfe"}
|
control={form.control}
|
||||||
target="_blank"
|
name="published"
|
||||||
className="size-max scale-90 p-0 text-xs text-muted-foreground"
|
render={({ field }) => (
|
||||||
>
|
<FormItem className="rounded-md border bg-background px-4 py-2">
|
||||||
<span>? Hilfe</span>
|
<FormControl>
|
||||||
</Link>
|
<div className="flex items-center gap-2">
|
||||||
</div>
|
<Label>Veröffentlicht </Label>
|
||||||
<FormField
|
<PublishArticleAlertDialog
|
||||||
control={form.control}
|
published={field.value}
|
||||||
name="published"
|
setPublished={(value) => {
|
||||||
render={({ field }) => (
|
field.onChange(value);
|
||||||
<FormItem className="rounded-md border bg-background px-4 py-2">
|
form.handleSubmit(onSubmit)();
|
||||||
<FormControl>
|
}}
|
||||||
<div className="flex items-center gap-2">
|
/>
|
||||||
<Label>Veröffentlicht </Label>
|
</div>
|
||||||
<PublishArticleAlertDialog
|
</FormControl>
|
||||||
published={field.value}
|
|
||||||
setPublished={(value) => {
|
<FormMessage />
|
||||||
field.onChange(value);
|
</FormItem>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<FormField
|
||||||
|
control={form.control}
|
||||||
|
name="categoryId"
|
||||||
|
render={({ field }) => (
|
||||||
|
<FormItem className="w-full">
|
||||||
|
<FormControl>
|
||||||
|
<CategorySelect
|
||||||
|
initialValue={field.value}
|
||||||
|
onSelect={(categoryId) => {
|
||||||
|
field.onChange(categoryId);
|
||||||
form.handleSubmit(onSubmit)();
|
form.handleSubmit(onSubmit)();
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</FormControl>
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
</FormItem>
|
</FormItem>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<FormField
|
</div>
|
||||||
control={form.control}
|
|
||||||
name="categoryId"
|
|
||||||
render={({ field }) => (
|
|
||||||
<FormItem className="w-full">
|
|
||||||
<FormControl>
|
|
||||||
<CategorySelect
|
|
||||||
initialValue={field.value}
|
|
||||||
onSelect={(categoryId) => {
|
|
||||||
field.onChange(categoryId);
|
|
||||||
form.handleSubmit(onSubmit)();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</FormControl>
|
|
||||||
|
|
||||||
<FormMessage />
|
|
||||||
</FormItem>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@ -86,3 +86,19 @@
|
|||||||
width: var(--radix-popover-trigger-width);
|
width: var(--radix-popover-trigger-width);
|
||||||
max-height: var(--radix-popover-content-available-height);
|
max-height: var(--radix-popover-content-available-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes loadingBar {
|
||||||
|
0% {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
transform: scaleX(1); /* Slight overshoot for bounce effect */
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleX(0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.saving {
|
||||||
|
animation: loadingBar 0.8s cubic-bezier(0.3, 0.8, 0.4, 1) infinite alternate;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user