Skip to content

Commit

Permalink
feat: added testomonial createtion form
Browse files Browse the repository at this point in the history
  • Loading branch information
Shashivadan committed Nov 11, 2024
1 parent cb88e55 commit 93ff4fe
Show file tree
Hide file tree
Showing 9 changed files with 387 additions and 120 deletions.
2 changes: 1 addition & 1 deletion apps/www/src/app/(main)/products/[id]/(indox)/all/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default async function page({ params }: { params: { id: string } }) {
</CardContent>
</Card>
<Card className="mb-2 flex items-center justify-between p-3">
<div className="text-xl font-bold">Reviews</div>
<div className="text-xl font-bold">Testimonials</div>
<CreateTestimonial data={data} />
</Card>

Expand Down
87 changes: 0 additions & 87 deletions apps/www/src/components/products/questons.tsx

This file was deleted.

186 changes: 183 additions & 3 deletions apps/www/src/components/testimonial/create-testimonial-form.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,185 @@
import React from "react";
"use client";

export default function CreateTestimonialForm() {
return <div>CreateTestimonialForm</div>;
import * as React from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { Star } from "lucide-react";
import { useForm } from "react-hook-form";
import { toast } from "sonner";
import { z } from "zod";

import { Button } from "@acme/ui/button";
import {
Form,
FormControl,
FormDescription,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@acme/ui/form";
import { Input } from "@acme/ui/input";
import { Textarea } from "@acme/ui/textarea";

const formSchema = z.object({
authorName: z.string().min(4, "Name must be at least 4 characters"),
profileImages: z.string(),
authorEmail: z.string().email(),
reviewImages: z.string(),
message: z.string().min(10, "Review must be at least 30 characters"),
rating: z.number().min(1).max(5),
});

export function CreateTestimonialForm() {
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
authorName: "",
profileImages: "",
authorEmail: "",
reviewImages: "",
message: "",
rating: 5,
},
});

function onSubmit(values: z.infer<typeof formSchema>) {
try {
toast.success(
`Successfully created testimonial ${JSON.stringify(values)}`,
);
form.reset();
} catch (error) {
toast.error((error as Error).message);
}
}

return (
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-3 p-4">
<FormField
control={form.control}
name="rating"
render={({ field }) => (
<FormItem>
<FormControl>
<div className="flex items-center space-x-1">
{[1, 2, 3, 4, 5].map((value) => (
<button
key={value}
type="button"
className="transition-transform hover:scale-110 focus:outline-none"
onClick={() => field.onChange(value)}
onMouseEnter={() => field.onChange(value)}
>
<Star
className={`h-8 w-8 transition-colors ${field.value >= value ? "fill-yellow-400 text-yellow-500" : "text-zinc-200"}`}
/>
</button>
))}
</div>
</FormControl>
<div className="mt-1 text-sm text-gray-500">
{field.value === 1 && "Poor"}
{field.value === 2 && "Fair"}
{field.value === 3 && "Good"}
{field.value === 4 && "Very Good"}
{field.value === 5 && "Excellent"}
</div>
<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="message"
render={({ field }) => (
<FormItem>
<FormControl>
<Textarea
placeholder="write your experience with us"
className="h-32 resize-none"
{...field}
/>
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="authorName"
render={({ field }) => (
<FormItem>
<FormLabel className="mb-1 flex justify-start">
Name <span className="text-red-500">*</span>
</FormLabel>
<FormControl>
<Input placeholder="Name" {...field} />
</FormControl>
<FormDescription>
This is your public display name.
</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="authorEmail"
render={({ field }) => (
<FormItem>
<FormLabel className="mb-1 flex justify-start">
Email <span className="text-red-500">*</span>
</FormLabel>
<FormControl>
<Input placeholder="[email protected]" {...field} />
</FormControl>
<FormDescription>We won't spam you, we promise.</FormDescription>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="profileImages"
render={({ field }) => (
<FormItem>
<FormLabel className="mb-1 flex justify-start">
Profile-image{" "}
<span className="text-xs text-zinc-500">(optional)</span>
</FormLabel>
<FormControl>
<Input placeholder="profile image-URL" {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<FormField
control={form.control}
name="reviewImages"
render={({ field }) => (
<FormItem>
<FormLabel className="mb-1 flex justify-start">
Review-images{" "}
<span className="text-xs text-zinc-500">(optional)</span>
</FormLabel>
<FormControl>
<Input placeholder="htts://image.png-URL" {...field} />
</FormControl>

<FormMessage />
</FormItem>
)}
/>

<Button type="submit">Submit</Button>
</form>
</Form>
);
}
47 changes: 18 additions & 29 deletions apps/www/src/components/testimonial/create-testimonial.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { GlobeIcon } from "lucide-react";
import { PlusIcon } from "lucide-react";

import { Avatar, AvatarFallback, AvatarImage } from "@acme/ui/avatar";
import { Button } from "@acme/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@acme/ui/card";
import { Card, CardHeader, CardTitle } from "@acme/ui/card";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogOverlay,
DialogTitle,
DialogTrigger,
} from "@acme/ui/dialog";

import type { OrganizationTestimonialType } from "~/types";
import { CreateTestimonialForm } from "./create-testimonial-form";

export default function CreateTestimonial({
data,
Expand All @@ -23,14 +25,20 @@ export default function CreateTestimonial({
<div>
<Dialog>
<DialogTrigger asChild>
<Button>Write a Review</Button>
<div>
<Button className="hidden md:block">Create a Testimonial</Button>
<Button className="block h-fit w-fit border-none p-1 md:hidden">
<PlusIcon className="h-6 w-6" />
</Button>
</div>
</DialogTrigger>
<DialogOverlay className="bg-transparent backdrop-blur-[5px] dark:bg-blend-saturation" />
<DialogContent>
<DialogHeader>
<DialogTitle>Create a Testimonial</DialogTitle>
<Card className="mb-2 w-full border-none bg-transparent shadow-none">
<CardHeader className="flex flex-col items-center gap-4">
<Avatar className="h-32 w-32">
<Card className="w-full border-none bg-transparent shadow-none">
<CardHeader className="flex flex-row items-center gap-4">
<Avatar className="h-16 w-16">
<AvatarImage
src={data.logo ?? ""}
alt={data.organizationName}
Expand All @@ -39,30 +47,11 @@ export default function CreateTestimonial({
{data.organizationName.slice(0, 2).toUpperCase()}
</AvatarFallback>
</Avatar>
<div className="flex flex-col items-center">
<CardTitle className="text-xl">
{data.organizationName}
</CardTitle>
{data.website && (
<a
href={data.website}
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-1 text-sm text-muted-foreground"
>
<GlobeIcon className="h-4 w-4" />
<span className="w-[200px] truncate text-blue-600 md:w-full">
{data.website}
</span>
</a>
)}
</div>
<CardTitle className="text-xl">
{data.organizationName}
</CardTitle>
</CardHeader>
<CardContent className="">
<div className="text-center text-lg">
Give your a valuable review
</div>
</CardContent>
<CreateTestimonialForm />
</Card>
<DialogDescription></DialogDescription>
</DialogHeader>
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
"@radix-ui/react-dropdown-menu": "^2.1.2",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-radio-group": "^1.2.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slider": "^1.2.1",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-tooltip": "^1.1.3",
"class-variance-authority": "^0.7.0",
Expand Down
Loading

0 comments on commit 93ff4fe

Please sign in to comment.