continued UI consolidation
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { createSignal, createEffect, For, Show } from "solid-js";
|
||||
import Dropzone from "./Dropzone";
|
||||
import XCircle from "~/components/icons/XCircle";
|
||||
import AttachmentThumbnail from "~/components/ui/AttachmentThumbnail";
|
||||
import AddImageToS3 from "~/lib/s3upload";
|
||||
import { env } from "~/env/client";
|
||||
import { api } from "~/lib/api";
|
||||
@@ -147,42 +147,13 @@ export default function AddAttachmentSection(props: AddAttachmentSectionProps) {
|
||||
<div class="-mx-24 grid grid-cols-6 gap-4">
|
||||
<For each={s3Files()}>
|
||||
{(file) => (
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
class="hover:bg-crust hover:bg-opacity-80 absolute z-10 ml-4 pb-[120px]"
|
||||
onClick={() => removeImage(file.key)}
|
||||
>
|
||||
<XCircle
|
||||
height={24}
|
||||
width={24}
|
||||
stroke={"currentColor"}
|
||||
strokeWidth={1}
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => copyToClipboard(file.key)}
|
||||
class="relative"
|
||||
>
|
||||
<Show
|
||||
when={isVideoFile(file.key)}
|
||||
fallback={
|
||||
<img
|
||||
src={getFileUrl(file.key)}
|
||||
class="mx-4 my-auto h-36 w-36 object-cover"
|
||||
alt="attachment"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<video
|
||||
src={getFileUrl(file.key)}
|
||||
class="mx-4 my-auto h-36 w-36 object-cover"
|
||||
controls
|
||||
/>
|
||||
</Show>
|
||||
</button>
|
||||
</div>
|
||||
<AttachmentThumbnail
|
||||
fileUrl={getFileUrl(file.key)}
|
||||
isVideo={isVideoFile(file.key)}
|
||||
onCopy={() => copyToClipboard(file.key)}
|
||||
onRemove={() => removeImage(file.key)}
|
||||
alt="attachment"
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
<Show when={newFileHolder().length > 0}>
|
||||
@@ -190,45 +161,17 @@ export default function AddAttachmentSection(props: AddAttachmentSectionProps) {
|
||||
</Show>
|
||||
<For each={newFileHolder()}>
|
||||
{(file, index) => (
|
||||
<div>
|
||||
<button
|
||||
type="button"
|
||||
class="hover:bg-crust hover:bg-opacity-80 absolute z-10 ml-4 pb-[120px]"
|
||||
onClick={() =>
|
||||
removeNewImage(index(), newFileHolderKeys()[index()])
|
||||
}
|
||||
>
|
||||
<XCircle
|
||||
height={24}
|
||||
width={24}
|
||||
stroke={"currentColor"}
|
||||
strokeWidth={1}
|
||||
/>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() =>
|
||||
copyToClipboard(newFileHolderKeys()[index()] as string)
|
||||
}
|
||||
>
|
||||
<Show
|
||||
when={fileTypes()[index()]?.startsWith("video/")}
|
||||
fallback={
|
||||
<img
|
||||
src={file}
|
||||
class="mx-4 my-auto h-36 w-36 object-cover"
|
||||
alt="new attachment"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<video
|
||||
src={file}
|
||||
class="mx-4 my-auto h-36 w-36 object-cover"
|
||||
controls
|
||||
/>
|
||||
</Show>
|
||||
</button>
|
||||
</div>
|
||||
<AttachmentThumbnail
|
||||
fileUrl={file}
|
||||
isVideo={fileTypes()[index()]?.startsWith("video/") || false}
|
||||
onCopy={() =>
|
||||
copyToClipboard(newFileHolderKeys()[index()] as string)
|
||||
}
|
||||
onRemove={() =>
|
||||
removeNewImage(index(), newFileHolderKeys()[index()])
|
||||
}
|
||||
alt="new attachment"
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,8 @@ import ReplyIcon from "~/components/icons/ReplyIcon";
|
||||
import TrashIcon from "~/components/icons/TrashIcon";
|
||||
import EditIcon from "~/components/icons/EditIcon";
|
||||
import ThumbsUpEmoji from "~/components/icons/emojis/ThumbsUp";
|
||||
import LoadingSpinner from "~/components/LoadingSpinner";
|
||||
import Button from "~/components/ui/Button";
|
||||
import IconButton from "~/components/ui/IconButton";
|
||||
import CommentInputBlock from "./CommentInputBlock";
|
||||
import ReactionBar from "./ReactionBar";
|
||||
|
||||
@@ -254,32 +255,46 @@ export default function CommentBlock(props: CommentBlockProps) {
|
||||
|
||||
{/* Delete button */}
|
||||
<Show when={canDelete()}>
|
||||
<button class="z-100" onClick={deleteCommentTrigger}>
|
||||
<Show
|
||||
when={!deletionLoading()}
|
||||
fallback={<LoadingSpinner height={24} width={24} />}
|
||||
>
|
||||
<IconButton
|
||||
icon={
|
||||
<TrashIcon
|
||||
height={24}
|
||||
width={24}
|
||||
stroke="var(--color-red)"
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
</Show>
|
||||
</button>
|
||||
}
|
||||
variant="danger"
|
||||
loading={deletionLoading()}
|
||||
onClick={deleteCommentTrigger}
|
||||
aria-label="Delete comment"
|
||||
class="z-100"
|
||||
/>
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
{/* Edit and Reply buttons */}
|
||||
<div class="absolute flex">
|
||||
<Show when={canEdit()}>
|
||||
<button onClick={editCommentTrigger} class="px-2">
|
||||
<EditIcon strokeWidth={1} height={24} width={24} />
|
||||
</button>
|
||||
<IconButton
|
||||
icon={<EditIcon strokeWidth={1} height={24} width={24} />}
|
||||
onClick={editCommentTrigger}
|
||||
aria-label="Edit comment"
|
||||
class="px-2"
|
||||
/>
|
||||
</Show>
|
||||
<button onClick={toggleCommentReplyBox} class="z-30">
|
||||
<ReplyIcon color={replyIconColor()} height={24} width={24} />
|
||||
</button>
|
||||
<IconButton
|
||||
icon={
|
||||
<ReplyIcon
|
||||
color={replyIconColor()}
|
||||
height={24}
|
||||
width={24}
|
||||
/>
|
||||
}
|
||||
onClick={toggleCommentReplyBox}
|
||||
aria-label="Reply to comment"
|
||||
class="z-30"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Reaction bar */}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { createEffect } from "solid-js";
|
||||
import type { CommentInputBlockProps } from "~/types/comment";
|
||||
import Button from "~/components/ui/Button";
|
||||
|
||||
export default function CommentInputBlock(props: CommentInputBlockProps) {
|
||||
let bodyRef: HTMLTextAreaElement | undefined;
|
||||
@@ -37,17 +38,13 @@ export default function CommentInputBlock(props: CommentInputBlockProps) {
|
||||
</label>
|
||||
</div>
|
||||
<div class="flex justify-end pt-2">
|
||||
<button
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={props.commentSubmitLoading}
|
||||
class={`${
|
||||
props.commentSubmitLoading
|
||||
? "bg-surface2 opacity-50"
|
||||
: "border-sapphire bg-blue hover:brightness-125"
|
||||
} rounded border px-4 py-2 text-base font-light shadow-md transition-all duration-300 ease-in-out active:scale-90`}
|
||||
loading={props.commentSubmitLoading}
|
||||
variant="primary"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createSignal, Show } from "solid-js";
|
||||
import { createSignal } from "solid-js";
|
||||
import { api } from "~/lib/api";
|
||||
import TrashIcon from "~/components/icons/TrashIcon";
|
||||
import LoadingSpinner from "~/components/LoadingSpinner";
|
||||
import Button from "~/components/ui/Button";
|
||||
|
||||
export interface DeletePostButtonProps {
|
||||
type: string;
|
||||
@@ -28,14 +28,14 @@ export default function DeletePostButton(props: DeletePostButtonProps) {
|
||||
|
||||
return (
|
||||
<form onSubmit={deletePostTrigger} class="flex w-full justify-end">
|
||||
<button type="submit" class="hover:cursor-pointer">
|
||||
<Show
|
||||
when={!loading()}
|
||||
fallback={<LoadingSpinner height={24} width={24} />}
|
||||
>
|
||||
<TrashIcon height={24} width={24} strokeWidth={1.5} />
|
||||
</Show>
|
||||
</button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="ghost"
|
||||
loading={loading()}
|
||||
class="hover:cursor-pointer"
|
||||
>
|
||||
<TrashIcon height={24} width={24} strokeWidth={1.5} />
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createSignal, Show } from "solid-js";
|
||||
import type { EditCommentModalProps } from "~/types/comment";
|
||||
import Xmark from "~/components/icons/Xmark";
|
||||
import Button from "~/components/ui/Button";
|
||||
|
||||
export default function EditCommentModal(props: EditCommentModalProps) {
|
||||
let bodyRef: HTMLTextAreaElement | undefined;
|
||||
@@ -52,17 +53,13 @@ export default function EditCommentModal(props: EditCommentModalProps) {
|
||||
<label class="underlinedInputLabel">Edit Comment</label>
|
||||
</div>
|
||||
<div class="flex justify-end pt-2">
|
||||
<button
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={props.editCommentLoading}
|
||||
class={`${
|
||||
props.editCommentLoading
|
||||
? "bg-surface2 opacity-50"
|
||||
: "border-sapphire bg-blue hover:brightness-125"
|
||||
} rounded border px-4 py-2 text-base shadow-md transition-all duration-300 ease-in-out active:scale-90`}
|
||||
loading={props.editCommentLoading}
|
||||
variant="primary"
|
||||
>
|
||||
Submit
|
||||
</button>
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
<Show when={showNoChange()}>
|
||||
|
||||
@@ -9,6 +9,7 @@ import AddAttachmentSection from "~/components/blog/AddAttachmentSection";
|
||||
import XCircle from "~/components/icons/XCircle";
|
||||
import AddImageToS3 from "~/lib/s3upload";
|
||||
import Input from "~/components/ui/Input";
|
||||
import Button from "~/components/ui/Button";
|
||||
|
||||
interface PostFormProps {
|
||||
mode: "create" | "edit";
|
||||
@@ -542,23 +543,14 @@ export default function PostForm(props: PostFormProps) {
|
||||
|
||||
{/* Submit button */}
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
<Button
|
||||
type="submit"
|
||||
disabled={loading()}
|
||||
class={`${
|
||||
loading()
|
||||
? "bg-surface2 cursor-not-allowed"
|
||||
: published()
|
||||
? "bg-peach hover:brightness-125"
|
||||
: "bg-green hover:brightness-125"
|
||||
} text-crust flex w-36 justify-center rounded py-3 transition-all duration-300 ease-out active:scale-90`}
|
||||
loading={loading()}
|
||||
variant={published() ? "primary" : "secondary"}
|
||||
class="text-crust w-36"
|
||||
>
|
||||
{loading()
|
||||
? "Loading..."
|
||||
: published()
|
||||
? "Publish!"
|
||||
: "Save as Draft"}
|
||||
</button>
|
||||
{published() ? "Publish!" : "Save as Draft"}
|
||||
</Button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { For } from "solid-js";
|
||||
import InfoIcon from "~/components/icons/InfoIcon";
|
||||
import Xmark from "~/components/icons/Xmark";
|
||||
import IconButton from "~/components/ui/IconButton";
|
||||
|
||||
export interface TagMakerProps {
|
||||
tagInputValue: string;
|
||||
@@ -42,13 +43,20 @@ export default function TagMaker(props: TagMakerProps) {
|
||||
<div class="overflow-hidden text-base overflow-ellipsis whitespace-nowrap">
|
||||
{tag}
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="bg-mantle bg-opacity-50 absolute inset-0 flex items-center justify-center rounded-xl opacity-0 group-hover:opacity-100"
|
||||
<IconButton
|
||||
icon={
|
||||
<Xmark
|
||||
strokeWidth={1}
|
||||
color={"white"}
|
||||
height={24}
|
||||
width={24}
|
||||
/>
|
||||
}
|
||||
onClick={() => props.deleteTag(idx())}
|
||||
>
|
||||
<Xmark strokeWidth={1} color={"white"} height={24} width={24} />
|
||||
</button>
|
||||
aria-label={`Remove tag ${tag}`}
|
||||
variant="danger"
|
||||
class="bg-mantle bg-opacity-50 absolute inset-0 flex items-center justify-center rounded-xl opacity-0 group-hover:opacity-100"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
|
||||
Reference in New Issue
Block a user