Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: feature card - Customer Rating (Resolves #216) #378

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions animata/card/customer-rating.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import CustomerRating from "@/animata/card/customer-rating";
import { Meta, StoryObj } from "@storybook/react";

const meta = {
title: "Card/Customer Rating",
component: CustomerRating,
parameters: {
layout: "centered",
},
tags: ["autodocs"],
argTypes: {},
} satisfies Meta<typeof CustomerRating>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Primary: Story = {
args: {
name: "Jonathan Doe",
rating: 75,
imageUrl:
"https://images.unsplash.com/photo-1581092165309-2ab35320ca70?q=80&w=1770&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
},
};
73 changes: 73 additions & 0 deletions animata/card/customer-rating.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use client";
import { useState } from "react";
import { Poppins } from "next/font/google";
import Image from "next/image";

import { cn } from "@/lib/utils";

interface CustomerRatingProps extends React.HTMLAttributes<HTMLDivElement> {
name: string;
imageUrl: string;
rating: number;
}
export const poppins = Poppins({
subsets: ["latin"],
weight: "700",
});

const CustomerRating: React.FC<CustomerRatingProps> = ({
name,
rating,
imageUrl,
}: CustomerRatingProps) => {
const [hovered, setHovered] = useState(false);

return (
<div
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
Comment on lines +23 to +28
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you don't need state for this and can use group hover from tailwindcss.

className={cn(
poppins.className,
"w-80 rounded-3xl border border-gray-400 bg-white pl-8 pr-8 text-black shadow-md",
"transform transition-transform duration-300",
{ "scale-105": hovered, "scale-100": !hovered }, // Conditional scaling
)}
>
{/* Customer Image and Name */}
<div className="mb-4 mt-8 flex items-center gap-4">
<div className="relative h-12 w-12 overflow-hidden rounded-full">
<Image
className="rounded-full object-cover"
src={imageUrl}
alt={name}
width={50}
height={50}
loading="lazy"
/>
</div>

<div>
<h6 className="text-lg font-medium">{name}</h6>
<span className="mt-2 text-xl font-extrabold text-gray-700">{rating}%</span>
</div>
</div>

{/* Rating Bar */}
<div className="mb-8 mt-4 flex w-full items-center justify-start">
<div
className={cn(
"relative h-4 overflow-hidden rounded-full bg-gray-300 transition-all duration-300",
{ "w-full": hovered, "w-10": !hovered },
)}
>
<div
className="absolute left-0 top-0 h-full rounded-full bg-green-600 transition-all duration-300"
style={{ width: hovered ? `${rating}%` : "0%" }} // Dynamically set width
/>
</div>
</div>
</div>
);
};

export default CustomerRating;
42 changes: 42 additions & 0 deletions content/docs/card/customer-rating.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: Customer Rating
description: A customer rating component that will display ratings out of 100. The rating bar will be revealed when hovered on the component.
labels: ["requires interaction", "hover"]
author: [Darshan Odedara](https://github.com/codeza-ai)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should twitter username

---

<ComponentPreview name="card-customer-rating--docs" />

## Installation

<Steps>
<Step>Run the following commmand to create the component file.</Step>

It will create a new file `customer-rating.tsx` inside the `components/animata/card` directory.

```bash
mkdir -p components/animata/card && touch components/animata/card/customer-rating.tsx
```

<Step>Paste the code</Step>{" "}

Open the newly created file and paste the following code:

```jsx file=<rootDir>/animata/card/customer-rating.tsx

```

<Step>Use the responsive component with your own props.<Step>
Import the compoent with the import statement given below.

```jsx
import { CustomerRating } from "./components/animata/card/customer-rating";
```

</Steps>

## Credits

Built by [Darshan Odedara](https://github.com/codeza-ai)

...Add appropriate credits here.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this line

1 change: 1 addition & 0 deletions next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const nextConfig = {
swcMinify: true,
images: {
unoptimized: true,
domains: ['images.unsplash.com'],
},
};

Expand Down
Loading