Skip to content

Commit

Permalink
Merge pull request #66 from dotslashf/development
Browse files Browse the repository at this point in the history
Improvement
  • Loading branch information
dotslashf authored Sep 12, 2024
2 parents 2f730ce + d58cbac commit 4604222
Show file tree
Hide file tree
Showing 37 changed files with 814 additions and 388 deletions.
23 changes: 23 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"next": "^14.2.4",
"next-auth": "^4.24.7",
"next-themes": "^0.3.0",
"nextjs-toploader": "^3.6.15",
"react": "^18.3.1",
"react-day-picker": "8.10.1",
"react-dom": "^18.3.1",
Expand Down
2 changes: 1 addition & 1 deletion src/app/_components/CopyPastaByIdPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default function CopyPastaById({ id }: CopyPastaByIdProps) {
const breadcrumbs = getBreadcrumbs(pathname);
const currentPath = breadcrumbs.map((path, i) => {
return {
url: path.url === "/copy-pasta" ? "/#main" : path.url,
url: path.url,
text:
i === breadcrumbs.length - 1
? trimContent(copyPasta.content, 20)
Expand Down
165 changes: 105 additions & 60 deletions src/app/_components/CreateCollectionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { LoaderCircle, PlusIcon } from "lucide-react";
import { type z } from "zod";
import useToast from "~/components/ui/use-react-hot-toast";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { FORM_COLLECTION_CONSTANT, parseErrorMessages } from "~/lib/constant";
import { createCollectionForm } from "~/server/form/collection";
import SearchBar from "~/components/Collection/SearchBar";
Expand All @@ -31,16 +31,21 @@ import BreadCrumbs from "~/components/BreadCrumbs";
import { getBreadcrumbs } from "~/lib/utils";

export default function CreateCollection() {
const createMutation = api.collection.create.useMutation();

const [searchResults, setSearchResults] = useState<CardCopyPastaMinimal[]>(
[],
);
const [isSearching, setIsSearching] = useState<boolean>(false);
const [listOfCollections, setListOfCollections] = useState<
CardCopyPastaMinimal[]
>([]);
const [showResults, setShowResults] = useState<boolean>(false);
const searchAreaRef = useRef<HTMLDivElement>(null);

const createMutation = api.collection.create.useMutation();

const toast = useToast();
const pathname = usePathname();
const breadcrumbs = getBreadcrumbs(pathname);
const router = useRouter();

const form = useForm<z.infer<typeof createCollectionForm>>({
Expand All @@ -52,39 +57,6 @@ export default function CreateCollection() {
},
});

const toast = useToast();

useEffect(() => {
if (createMutation.isSuccess) {
return router.push("/dashboard/profile?utm_content=create_collection");
}
}, [createMutation.isSuccess, router]);

useEffect(() => {
form.setValue(
"copyPastaIds",
listOfCollections.map((copy) => copy.id),
);
}, [listOfCollections, form]);

async function onSubmit(values: z.infer<typeof createCollectionForm>) {
try {
await toast({
message: "",
type: "promise",
promiseFn: createMutation.mutateAsync({
...values,
}),
promiseMsg: {
loading: "Sedang memasak 🔥",
success: "Makasih! Koleksimu sudah dibuat ya 😎",
// eslint-disable-next-line
error: (err) => `${parseErrorMessages(err)}`,
},
});
} catch (error) {}
}

const handleAddToCollection = (copyPasta: CardCopyPastaMinimal) => {
if (listOfCollections.length >= FORM_COLLECTION_CONSTANT.copyPastaIds.max) {
return toast({
Expand All @@ -101,6 +73,11 @@ export default function CreateCollection() {
});
}

void toast({
type: "success",
message: "Ditambahkan dalam koleksi 😉",
});

setListOfCollections([...listOfCollections, copyPasta]);
};

Expand All @@ -119,8 +96,65 @@ export default function CreateCollection() {
/>
);

const pathname = usePathname();
const breadcrumbs = getBreadcrumbs(pathname);
const handleSearchBlur = useCallback(() => {
setShowResults(false);
}, []);

const handleSearchFocus = () => {
setShowResults(true);
};

const handleSearchResults = (results: CardCopyPastaMinimal[]) => {
setSearchResults(results);
setShowResults(true);
};

useEffect(() => {
const handleMouseDown = (event: MouseEvent) => {
if (
searchAreaRef.current &&
!searchAreaRef.current.contains(event.target as Node)
) {
handleSearchBlur();
}
};

document.addEventListener("mousedown", handleMouseDown);
return () => {
document.removeEventListener("mousedown", handleMouseDown);
};
}, [handleSearchBlur]);

useEffect(() => {
if (createMutation.isSuccess) {
return router.push("/dashboard/profile?utm_content=create_collection");
}
}, [createMutation.isSuccess, router]);

useEffect(() => {
form.setValue(
"copyPastaIds",
listOfCollections.map((copy) => copy.id),
);
}, [listOfCollections, form]);

async function onSubmit(values: z.infer<typeof createCollectionForm>) {
try {
await toast({
message: "",
type: "promise",
promiseFn: createMutation.mutateAsync({
...values,
}),
promiseMsg: {
loading: "Sedang memasak 🔥",
success: "Makasih! Koleksimu sudah dibuat ya 😎",
// eslint-disable-next-line
error: (err) => `${parseErrorMessages(err)}`,
},
});
} catch (error) {}
}

return (
<div className="flex w-full flex-col">
Expand Down Expand Up @@ -162,29 +196,40 @@ export default function CreateCollection() {
</FormItem>
)}
/>
<SearchBar
onSearchResults={setSearchResults}
onLoadingState={setIsSearching}
/>
{isSearching && <LoaderCircle className="mb-4 w-4 animate-spin" />}
{searchResults.length > 0 && (
<ScrollArea className="w-full whitespace-nowrap rounded-md border">
<div className="flex space-x-2 bg-secondary p-2">
{searchResults.map((copy) => {
return (
<CardSearchResult
type="add"
key={copy.id}
copyPasta={copy}
onAddToCollection={handleAddToCollection}
onRemoveFromCollection={handleRemoveFromCollection}
/>
);
})}
<div
className="flex flex-col gap-4"
ref={searchAreaRef}
onFocus={handleSearchFocus}
>
<SearchBar
onSearchResults={handleSearchResults}
onLoadingState={setIsSearching}
/>
{isSearching && (
<div className="flex h-20 items-center justify-center rounded-md border bg-secondary">
<LoaderCircle className="w-4 animate-spin" />
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
)}
)}
{!isSearching && showResults && searchResults.length > 0 && (
<ScrollArea className="w-full whitespace-nowrap rounded-md border">
<div className="flex w-full space-x-2 bg-secondary p-2">
{searchResults.map((copy) => {
return (
<div key={copy.id} className="w-80">
<CardSearchResult
type="add"
copyPasta={copy}
onAddToCollection={handleAddToCollection}
onRemoveFromCollection={handleRemoveFromCollection}
/>
</div>
);
})}
</div>
<ScrollBar orientation="horizontal" />
</ScrollArea>
)}
</div>
<FormField
control={form.control}
name="copyPastaIds"
Expand Down
23 changes: 16 additions & 7 deletions src/app/_components/CreateCopyPastaPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Button } from "~/components/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
Expand Down Expand Up @@ -37,6 +38,7 @@ import { DateTimePicker } from "~/components/ui/datetime-picker";
import { id } from "date-fns/locale";
import { DAYS, parseErrorMessages } from "~/lib/constant";
import BreadCrumbs from "~/components/BreadCrumbs";
import Link from "next/link";

export default function CreateCopyPasta() {
const [tags] = api.tag.list.useSuspenseQuery(undefined, {
Expand Down Expand Up @@ -147,16 +149,10 @@ export default function CreateCopyPasta() {

const pathname = usePathname();
const breadcrumbs = getBreadcrumbs(pathname);
const currentPath = breadcrumbs.map((path) => {
return {
url: path.url === "/copy-pasta" ? "/#main" : path.url,
text: path.text,
};
});

return (
<div className="flex w-full flex-col">
<BreadCrumbs path={currentPath} />
<BreadCrumbs path={breadcrumbs} />
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="w-full">
<div className="grid grid-cols-1 gap-4">
Expand All @@ -173,6 +169,19 @@ export default function CreateCopyPasta() {
rows={5}
/>
</FormControl>
<FormDescription className="font-semibold">
Pastikan mengecek templatenya sudah ada atau belum yah! 😎
<br />
Bisa menggunakan fitur{" "}
<Link
href={"/copy-pasta"}
className="text-primary underline"
prefetch={false}
target="__blank"
>
cari disini
</Link>
</FormDescription>
<FormMessage />
</FormItem>
)}
Expand Down
Loading

0 comments on commit 4604222

Please sign in to comment.