Skip to content

Commit

Permalink
Implemented Tag Card
Browse files Browse the repository at this point in the history
  • Loading branch information
Aman254 committed Feb 18, 2025
1 parent 26e8003 commit 2ca2b39
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 10 deletions.
50 changes: 45 additions & 5 deletions components/cards/TagCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,71 @@ import ROUTES from "@/constants/routes";
import Link from "next/link";
import { Badge } from "../ui/badge";
import { getDeviconClassName } from "@/lib/utils";
import Image from "next/image";

interface Props {
_id: string;
name: String;
questions?: number;
showCount?: boolean;
compact?: boolean;
remove?: boolean;
isButton?: boolean;
handleRemove?: () => void;
}

const TagCard = ({ _id, name, questions, showCount, compact }: Props) => {
const TagCard = ({
_id,
name,
questions,
showCount,
compact,
remove,
isButton,
handleRemove,
}: Props) => {
const iconClass = getDeviconClassName(name);
return (
<Link href={`${ROUTES.TAGS(_id)}`} className="flex justify-between gap-2">
<Badge className="subtle-medium background-light800_dark300 text-light400_light500 rounded-md border-none px-4 py-2 uppercase">

const handleClick = (e: React.MouseEvent) => {
e.preventDefault();
};

const Content = (
<>
<Badge className="subtle-medium background-light800_dark300 text-light400_light500 rounded-md border-none px-4 py-2 uppercase flex flex-row gap-2">
<div className="flex-center space-x-2">
<i className={`${iconClass} text-sm`}></i>
<span>{name}</span>
</div>
{remove && (
<Image
src="/icons/close.svg"
width={12}
height={12}
alt="close icon"
className="cursor-pointer object-contain invert-0 dark:invert"
onClick={handleRemove}
/>
)}
</Badge>

{showCount && (
<p className="small-medium text-dark-500_light700">{questions}</p>
)}
</Link>
</>
);

if (compact) {
return isButton ? (
<button onClick={handleClick} className="flex justify-between gap-2">
{Content}
</button>
) : (
<Link href={`${ROUTES.TAGS(_id)}`} className="flex justify-between gap-2">
{Content}
</Link>
);
}
};

export default TagCard;
2 changes: 1 addition & 1 deletion components/editor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const Editor = ({ value, fieldChange, editorRef, ...props }: Props) => {
return (
<MDXEditor
key={resolvedTheme}
className="background-light800_dark200 light-border-2 mardown-editor dark-editor w-full border"
className="background-light800_dark200 light-border-2 mardown-editor dark-editor grid w-full border"
markdown={value}
ref={editorRef}
onChange={fieldChange}
Expand Down
63 changes: 59 additions & 4 deletions components/forms/QuestionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ import { Input } from "../ui/input";
import { Button } from "../ui/button";
import { MDXEditorMethods } from "@mdxeditor/editor";
import dynamic from "next/dynamic";
import { z } from "zod";
import TagCard from "../cards/TagCard";

const Editor = dynamic(() => import("@/components/editor/index"), {
ssr: false,
});

const QuestionForm = () => {
const editorRef = useRef<MDXEditorMethods>(null);
const form = useForm({

const form = useForm<z.infer<typeof AskQuestionSchema>>({
resolver: zodResolver(AskQuestionSchema),
defaultValues: {
title: "",
Expand All @@ -33,7 +36,45 @@ const QuestionForm = () => {
},
});

const handleCreateQuestion = () => {};
const handleInputKeyDown = (
e: React.KeyboardEvent<HTMLInputElement>,
field: { value: string[] }
) => {
if (e.key === "Enter") {
e.preventDefault();
const tagInput = e.currentTarget.value.trim();

if (tagInput && tagInput.length < 15 && !field.value.includes(tagInput)) {
form.setValue("tags", [...field.value, tagInput]);
e.currentTarget.value = "";
form.clearErrors("tags");
} else if (tagInput.length > 15) {
form.setError("tags", {
type: "manual",
message: "Tag should be less than 15 characters.",
});
} else if (field.value.includes(tagInput)) {
form.setError("tags", {
type: "manual",
message: "Tag already exists.",
});
}
}
};

const handleTagRemove = (tag: string, field: { value: string[] }) => {
const newTags = field.value.filter((t) => t !== tag);
form.setValue("tags", newTags);
if (newTags.length == 0) {
form.setError("tags", {
type: "manual",
message: "Tags are required.",
});
}
};
const handleCreateQuestion = (data: z.infer<typeof AskQuestionSchema>) => {
console.log(data);
};
return (
<Form {...form}>
<form
Expand Down Expand Up @@ -99,9 +140,23 @@ const QuestionForm = () => {
<Input
className="paragraph-regular background-light700_dark300 light-border-2 text-dark300_light700 no-focus min-h-[56px] border"
placeholder="Add tags..."
{...field}
onKeyDown={(e) => handleInputKeyDown(e, field)}
/>
Tags
{field.value.length > 0 && (
<div className="flex-start mt-2.5 flex-wrap gap-2.5">
{field?.value?.map((tag: string) => (
<TagCard
key={tag}
_id={tag}
compact
name={tag}
remove
isButton
handleRemove={() => handleTagRemove(tag, field)}
/>
))}
</div>
)}
</div>
</FormControl>
<FormDescription className="body-regular mt-2.5 text-light-500">
Expand Down

0 comments on commit 2ca2b39

Please sign in to comment.