Skip to content

Commit

Permalink
feat: added search input markup
Browse files Browse the repository at this point in the history
  • Loading branch information
kujo205 committed Apr 29, 2024
1 parent 7d1c048 commit 38b6e70
Show file tree
Hide file tree
Showing 17 changed files with 1,230 additions and 33 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-tabs": "^1.0.4",
Expand Down
85 changes: 85 additions & 0 deletions pnpm-lock.yaml

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

31 changes: 31 additions & 0 deletions src/app/posts/_components/PostSearch/SortOptionsSelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import * as React from "react";

import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectLabel,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";

interface SortOptionsSelectProps {
className?: string;
}

export function SortOptionsSelect({ className }: SortOptionsSelectProps) {
return (
<Select>
<SelectTrigger className={className}>
<SelectValue placeholder="Select a fruit" />
</SelectTrigger>
<SelectContent>
<SelectItem value="liked">Most Liked</SelectItem>
<SelectItem value="popular">Most Popular</SelectItem>
<SelectItem value="new">Newest First</SelectItem>
<SelectItem value="old">Oldest First</SelectItem>
</SelectContent>
</Select>
);
}
66 changes: 66 additions & 0 deletions src/app/posts/_components/PostSearch/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"use client";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Search } from "lucide-react";
import { SortOptionsSelect } from "./SortOptionsSelect";
import { useMemo, useState } from "react";

interface PostSearchProps {
tags: { value: number; label: string }[];
}

function PostSearch({ tags }: PostSearchProps) {
const [selectedTagIds, setSelectedTagIds] = useState<number[]>([]);

const sortedTags = useMemo(() => {
return tags.sort((a, b) => {
if (selectedTagIds.includes(a.value)) {
return -1;
}
return 0;
});
}, [selectedTagIds]);

function handleSelectTag(tagId: number) {
setSelectedTagIds((prev) => {
if (prev.includes(tagId)) {
return prev.filter((id) => id !== tagId);
}
return [...prev, tagId];
});
}

return (
<div className="0:w-full flex max-w-[1080px] flex-col gap-[16px]">
{/* search with select */}
<div className=" flex justify-between rounded bg-gradient-to-r from-[#4F3ABA] to-[#D94E68] p-[16px] max-sm:flex-col max-sm:gap-[16px]">
<div className="flex w-full flex-[.55] gap-[8px]">
<Input placeholder="Search for a post..." />
<Button variant="outline" className="p-[8px]">
<Search />
</Button>
</div>
<SortOptionsSelect className="w-full flex-[.2]" />
</div>

{/* tags */}
<div className="flex gap-[8px] overflow-x-auto">
{sortedTags.map((tag) => (
<Button
variant={
selectedTagIds.some((id) => id === tag.value)
? "outline-selected"
: "outline"
}
key={tag.value}
onClick={() => handleSelectTag(tag.value)}
>
{tag.label}
</Button>
))}
</div>
</div>
);
}

export { PostSearch };
15 changes: 10 additions & 5 deletions src/app/posts/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import { api } from "@/trpc/server";
import { PostSearch } from "./_components/PostSearch";

export default async function Page() {
const resonse = await api.post.getPosts.query({
const postsResponse = await api.post.getPosts.query({
page: 0,
pageSize: 10,
search: "w",
tagIds: [1, 2],
});

const tags = await api.post.getAllTags.query();

return (
<section>
<pre>{JSON.stringify(resonse.posts, undefined, 2)}</pre>
{resonse.left}
<main className="flex flex-col items-center px-[16px] py-[62px]">
<PostSearch tags={tags} />
<span>{JSON.stringify(postsResponse, undefined, 2)}</span>
{postsResponse.left}
<h1>Working on it cap</h1>
</section>
</main>
);
}
8 changes: 7 additions & 1 deletion src/components/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { SocialMedia } from "@/components/icons/social-media";
import { Menu, Delete, MousePointerClick, PlusIcon } from "lucide-react";
import {
Menu,
Delete,
MousePointerClick,
PlusIcon,
Search,
} from "lucide-react";

export const Icons = {
SocialMedia,
Expand Down
1 change: 1 addition & 0 deletions src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const buttonVariants = cva(
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
"outline-selected": "border border-input bg-slate-200",
"outline-black":
"border border-black bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
Expand Down
2 changes: 1 addition & 1 deletion src/components/ui/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input> & {
additionalChildren: React.ReactNode;
additionalChildren?: React.ReactNode;
}
>(({ additionalChildren, className, ...props }, ref) => (
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
Expand Down
Loading

0 comments on commit 38b6e70

Please sign in to comment.