1'use client'
2
3import * as React from 'react'
4import { PencilLine, Star, StarIcon } from 'lucide-react'
5
6import { cn } from '@/lib/utils'
7import { Button } from '@/components/ui/button'
8import {
9 Card,
10 CardContent,
11 CardDescription,
12 CardFooter,
13 CardHeader,
14 CardTitle,
15} from '@/components/ui/card'
16import { Rating } from '@/components/ui/rating'
17import { Separator } from '@/components/ui/separator'
18
19export function Rating01() {
20 const totalRatings = 17400
21 const totalReviews = 567
22 const average = 3.9
23 const distribution: Record<string, number> = {
24 '5': 56,
25 '4': 25,
26 '3': 7,
27 '2': 8,
28 '1': 4,
29 }
30
31 const maxBar = Math.max(...Object.values(distribution))
32
33 return (
34 <Card className="max-w-sm rounded-2xl border border-gray-200 bg-white shadow-sm">
35 <CardHeader className="">
36 <div className="hidden h-9 w-9 items-center justify-center rounded-full border border-gray-300 md:flex">
37 <Star className="h-4 w-4 text-gray-500" />
38 </div>
39 <div className="flex flex-col space-y-2">
40 <CardTitle>Rate Our Product</CardTitle>
41 <CardDescription>
42 Provide us with feedback for the product.
43 </CardDescription>
44 </div>
45 </CardHeader>
46 <CardContent className="px-4 py-3">
47 <div className="flex items-center gap-4 space-y-2">
48 <div className="text-4xl font-semibold text-black">
49 {average}
50 </div>
51 <div className="flex flex-col space-y-2">
52 <Rating value={average} readOnly allowHalf size={18} />
53 <p className="text-sm text-gray-600">
54 {average} ยท {totalRatings.toLocaleString()} Ratings{' '}
55 <a href="#" className="text-blue-600 underline">
56 {totalReviews} reviews
57 </a>
58 </p>
59 </div>
60 </div>
61 <Separator className="my-3" />
62 <div className="mt-4 space-y-2">
63 {[5, 4, 3, 2, 1].map((star) => (
64 <div key={star} className="flex items-center gap-2">
65 <div className="relative h-2 flex-1 overflow-hidden rounded-full bg-gray-100">
66 <div
67 className={cn(
68 'bg-yellow absolute top-0 left-0 h-2 rounded-full transition-all',
69 )}
70 style={{
71 width: `${(distribution[star] / maxBar) * 100}%`,
72 }}
73 />
74 </div>
75 <div className="flex w-10 items-center justify-end gap-1 text-sm text-gray-600">
76 {star}.0
77 <StarIcon className="fill-yellow text-yellow h-3.5 w-3.5" />
78 </div>
79 </div>
80 ))}
81 </div>
82 </CardContent>
83
84 <CardFooter>
85 <Button
86 variant="outline"
87 className="w-full justify-center gap-2 text-gray-800"
88 >
89 <PencilLine className="h-4 w-4" />
90 Write a Review
91 </Button>
92 </CardFooter>
93 </Card>
94 )
95}
963.9 ยท 17,400 Ratings 567 reviews
1'use client'
2
3import * as React from 'react'
4import { PencilLine, Star, StarIcon } from 'lucide-react'
5
6import { cn } from '@/lib/utils'
7import { Button } from '@/components/ui/button'
8import {
9 Card,
10 CardContent,
11 CardDescription,
12 CardFooter,
13 CardHeader,
14 CardTitle,
15} from '@/components/ui/card'
16import { Rating } from '@/components/ui/rating'
17import { Separator } from '@/components/ui/separator'
18
19export function Rating01() {
20 const totalRatings = 17400
21 const totalReviews = 567
22 const average = 3.9
23 const distribution: Record<string, number> = {
24 '5': 56,
25 '4': 25,
26 '3': 7,
27 '2': 8,
28 '1': 4,
29 }
30
31 const maxBar = Math.max(...Object.values(distribution))
32
33 return (
34 <Card className="max-w-sm rounded-2xl border border-gray-200 bg-white shadow-sm">
35 <CardHeader className="">
36 <div className="hidden h-9 w-9 items-center justify-center rounded-full border border-gray-300 md:flex">
37 <Star className="h-4 w-4 text-gray-500" />
38 </div>
39 <div className="flex flex-col space-y-2">
40 <CardTitle>Rate Our Product</CardTitle>
41 <CardDescription>
42 Provide us with feedback for the product.
43 </CardDescription>
44 </div>
45 </CardHeader>
46 <CardContent className="px-4 py-3">
47 <div className="flex items-center gap-4 space-y-2">
48 <div className="text-4xl font-semibold text-black">
49 {average}
50 </div>
51 <div className="flex flex-col space-y-2">
52 <Rating value={average} readOnly allowHalf size={18} />
53 <p className="text-sm text-gray-600">
54 {average} ยท {totalRatings.toLocaleString()} Ratings{' '}
55 <a href="#" className="text-blue-600 underline">
56 {totalReviews} reviews
57 </a>
58 </p>
59 </div>
60 </div>
61 <Separator className="my-3" />
62 <div className="mt-4 space-y-2">
63 {[5, 4, 3, 2, 1].map((star) => (
64 <div key={star} className="flex items-center gap-2">
65 <div className="relative h-2 flex-1 overflow-hidden rounded-full bg-gray-100">
66 <div
67 className={cn(
68 'bg-yellow absolute top-0 left-0 h-2 rounded-full transition-all',
69 )}
70 style={{
71 width: `${(distribution[star] / maxBar) * 100}%`,
72 }}
73 />
74 </div>
75 <div className="flex w-10 items-center justify-end gap-1 text-sm text-gray-600">
76 {star}.0
77 <StarIcon className="fill-yellow text-yellow h-3.5 w-3.5" />
78 </div>
79 </div>
80 ))}
81 </div>
82 </CardContent>
83
84 <CardFooter>
85 <Button
86 variant="outline"
87 className="w-full justify-center gap-2 text-gray-800"
88 >
89 <PencilLine className="h-4 w-4" />
90 Write a Review
91 </Button>
92 </CardFooter>
93 </Card>
94 )
95}
961'use client'
2
3import * as React from 'react'
4import Image from 'next/image'
5import { Flag } from 'lucide-react'
6
7import { Card } from '@/components/ui/card'
8import { Rating } from '@/components/ui/rating'
9
10export function Rating02() {
11 const ratingValue = 3.5
12
13 return (
14 <Card className="flex flex-row items-center justify-between gap-10 rounded-xl border border-gray-200 bg-white px-4 py-3 shadow-sm">
15 <div className="flex items-center gap-3">
16 <div className="h-10 w-10 overflow-hidden rounded-full bg-gray-100">
17 <Image
18 src="/images/profile1.png"
19 alt="James Brown"
20 width={40}
21 height={40}
22 className="object-cover"
23 />
24 </div>
25
26 <div className="flex flex-col">
27 <div className="flex items-center gap-1 sm:gap-0">
28 <span className="text-sm font-semibold text-gray-900">
29 Rafael Costa
30 </span>
31 <span className="text-xs text-gray-500">
32 @rafaelcosta
33 </span>
34 </div>
35
36 <div className="mt-1 flex items-center gap-1">
37 <Rating
38 value={ratingValue}
39 readOnly
40 allowHalf
41 size={16}
42 />
43 <span className="text-xs text-gray-600">
44 ({ratingValue})
45 </span>
46 </div>
47 </div>
48 </div>
49 <div>
50 <Flag className="hover:text-gray h-4 w-4 cursor-pointer text-black" />
51 </div>
52 </Card>
53 )
54}
551'use client'
2
3import * as React from 'react'
4import Image from 'next/image'
5import { Flag } from 'lucide-react'
6
7import { Card } from '@/components/ui/card'
8import { Rating } from '@/components/ui/rating'
9
10export function Rating02() {
11 const ratingValue = 3.5
12
13 return (
14 <Card className="flex flex-row items-center justify-between gap-10 rounded-xl border border-gray-200 bg-white px-4 py-3 shadow-sm">
15 <div className="flex items-center gap-3">
16 <div className="h-10 w-10 overflow-hidden rounded-full bg-gray-100">
17 <Image
18 src="/images/profile1.png"
19 alt="James Brown"
20 width={40}
21 height={40}
22 className="object-cover"
23 />
24 </div>
25
26 <div className="flex flex-col">
27 <div className="flex items-center gap-1 sm:gap-0">
28 <span className="text-sm font-semibold text-gray-900">
29 Rafael Costa
30 </span>
31 <span className="text-xs text-gray-500">
32 @rafaelcosta
33 </span>
34 </div>
35
36 <div className="mt-1 flex items-center gap-1">
37 <Rating
38 value={ratingValue}
39 readOnly
40 allowHalf
41 size={16}
42 />
43 <span className="text-xs text-gray-600">
44 ({ratingValue})
45 </span>
46 </div>
47 </div>
48 </div>
49 <div>
50 <Flag className="hover:text-gray h-4 w-4 cursor-pointer text-black" />
51 </div>
52 </Card>
53 )
54}
551'use client'
2
3import * as React from 'react'
4import { Info, Star } from 'lucide-react'
5import { toast } from 'sonner'
6
7import { Button } from '@/components/ui/button'
8import {
9 Card,
10 CardContent,
11 CardDescription,
12 CardFooter,
13 CardHeader,
14 CardTitle,
15} from '@/components/ui/card'
16import { Checkbox } from '@/components/ui/checkbox'
17import { Input } from '@/components/ui/input'
18import { Label } from '@/components/ui/label'
19import { Rating } from '@/components/ui/rating'
20import { Textarea } from '@/components/ui/textarea'
21
22export function RatingFeedbackCard() {
23 const [rating, setRating] = React.useState(3)
24 const [review, setReview] = React.useState('')
25 const [anonymous, setAnonymous] = React.useState(false)
26
27 const onSubmit = () => {
28 toast.success(`Review submitted ${rating} star`)
29 }
30
31 return (
32 <Card className="max-w-sm rounded-2xl border border-gray-200 bg-white shadow-sm">
33 <CardHeader className="">
34 <div className="border-gray hidden h-9 w-9 items-center justify-center rounded-full border md:flex">
35 <Star className="text-gray h-4 w-4" />
36 </div>
37 <div className="flex flex-col space-y-2">
38 <CardTitle>Rate Our Product</CardTitle>
39 <CardDescription>
40 Provide us with feedback for the product.
41 </CardDescription>
42 </div>
43 </CardHeader>
44 <CardContent className="space-y-2">
45 <div className="space-y-2">
46 <div className="flex items-center gap-1">
47 <span className="text-sm font-medium text-black">
48 Your Rating
49 </span>
50 <Info className="text-gray h-3.5 w-3.5" />
51 </div>
52 <Rating
53 value={rating}
54 onChange={setRating}
55 allowHalf={false}
56 size={28}
57 />
58 </div>
59
60 <div className="space-y-2">
61 <Label className="mb-1 block text-sm font-medium text-black">
62 Product Name *
63 </Label>
64 <Input
65 type="text"
66 placeholder="MacBook Air M1"
67 className="rounded-lg border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
68 />
69 </div>
70
71 <div className="space-y-2">
72 <Label className="block text-sm font-medium text-black">
73 Product Review{' '}
74 <span className="text-gray">(Optional)</span>
75 </Label>
76 <Textarea
77 value={review}
78 onChange={(e) => setReview(e.target.value)}
79 placeholder="Jot down your thoughts..."
80 maxLength={200}
81 className="focus:border-border rounded-lg border-gray-200 focus:ring-2 focus:ring-blue-100"
82 />
83 <div className="text-right text-xs text-gray-400">
84 {review.length}/200
85 </div>
86 </div>
87
88 <div className="flex items-center gap-2">
89 <Checkbox
90 checked={anonymous}
91 onCheckedChange={(checked) =>
92 setAnonymous(checked as boolean)
93 }
94 id="anonymous"
95 />
96 <Label
97 htmlFor="anonymous"
98 className="text-sm text-gray-700"
99 >
100 Remain anonymous
101 </Label>
102 </div>
103 </CardContent>
104 <CardFooter className="gap-2">
105 <Button
106 variant="outline"
107 className="border-gray w-1/2 rounded-lg text-gray-700 hover:bg-gray-100"
108 >
109 Cancel
110 </Button>
111 <Button className="w-1/2 rounded-lg" onClick={onSubmit}>
112 Submit
113 </Button>
114 </CardFooter>
115 </Card>
116 )
117}
1181'use client'
2
3import * as React from 'react'
4import { Info, Star } from 'lucide-react'
5import { toast } from 'sonner'
6
7import { Button } from '@/components/ui/button'
8import {
9 Card,
10 CardContent,
11 CardDescription,
12 CardFooter,
13 CardHeader,
14 CardTitle,
15} from '@/components/ui/card'
16import { Checkbox } from '@/components/ui/checkbox'
17import { Input } from '@/components/ui/input'
18import { Label } from '@/components/ui/label'
19import { Rating } from '@/components/ui/rating'
20import { Textarea } from '@/components/ui/textarea'
21
22export function RatingFeedbackCard() {
23 const [rating, setRating] = React.useState(3)
24 const [review, setReview] = React.useState('')
25 const [anonymous, setAnonymous] = React.useState(false)
26
27 const onSubmit = () => {
28 toast.success(`Review submitted ${rating} star`)
29 }
30
31 return (
32 <Card className="max-w-sm rounded-2xl border border-gray-200 bg-white shadow-sm">
33 <CardHeader className="">
34 <div className="border-gray hidden h-9 w-9 items-center justify-center rounded-full border md:flex">
35 <Star className="text-gray h-4 w-4" />
36 </div>
37 <div className="flex flex-col space-y-2">
38 <CardTitle>Rate Our Product</CardTitle>
39 <CardDescription>
40 Provide us with feedback for the product.
41 </CardDescription>
42 </div>
43 </CardHeader>
44 <CardContent className="space-y-2">
45 <div className="space-y-2">
46 <div className="flex items-center gap-1">
47 <span className="text-sm font-medium text-black">
48 Your Rating
49 </span>
50 <Info className="text-gray h-3.5 w-3.5" />
51 </div>
52 <Rating
53 value={rating}
54 onChange={setRating}
55 allowHalf={false}
56 size={28}
57 />
58 </div>
59
60 <div className="space-y-2">
61 <Label className="mb-1 block text-sm font-medium text-black">
62 Product Name *
63 </Label>
64 <Input
65 type="text"
66 placeholder="MacBook Air M1"
67 className="rounded-lg border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
68 />
69 </div>
70
71 <div className="space-y-2">
72 <Label className="block text-sm font-medium text-black">
73 Product Review{' '}
74 <span className="text-gray">(Optional)</span>
75 </Label>
76 <Textarea
77 value={review}
78 onChange={(e) => setReview(e.target.value)}
79 placeholder="Jot down your thoughts..."
80 maxLength={200}
81 className="focus:border-border rounded-lg border-gray-200 focus:ring-2 focus:ring-blue-100"
82 />
83 <div className="text-right text-xs text-gray-400">
84 {review.length}/200
85 </div>
86 </div>
87
88 <div className="flex items-center gap-2">
89 <Checkbox
90 checked={anonymous}
91 onCheckedChange={(checked) =>
92 setAnonymous(checked as boolean)
93 }
94 id="anonymous"
95 />
96 <Label
97 htmlFor="anonymous"
98 className="text-sm text-gray-700"
99 >
100 Remain anonymous
101 </Label>
102 </div>
103 </CardContent>
104 <CardFooter className="gap-2">
105 <Button
106 variant="outline"
107 className="border-gray w-1/2 rounded-lg text-gray-700 hover:bg-gray-100"
108 >
109 Cancel
110 </Button>
111 <Button className="w-1/2 rounded-lg" onClick={onSubmit}>
112 Submit
113 </Button>
114 </CardFooter>
115 </Card>
116 )
117}
118