Skip to content

Commit

Permalink
Statistics, Icon & New component layout + badges (#12)
Browse files Browse the repository at this point in the history
* 🚚 Rename marketing-components to marketing-ui

* 🚚 Sort manually alphabetically components

* chore: Add @radix-ui/react-slot v1.1.0 & update lucide-react to v 0.427.0

* 💄 Add icon to navigation

* 🚚 Add & move Shadcn UI based components

* 🎨 refactor menus

* ✨ Add icon & badges names & description

* ✨ Add Variant2FeatureFourImages component for less animated feature section

* ✨ Improve card variant

* 🐛 fix overflow on chromium

* 💄 Improve layout & repsonsive

* 💄 Improve caption styles for different text sizes

* ✨ Add AnimatedNumberVariant1 component for animated numbers on scroll
  • Loading branch information
damien-schneider authored Aug 11, 2024
1 parent 4867645 commit 9e51fc1
Show file tree
Hide file tree
Showing 34 changed files with 873 additions and 277 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,14 @@
"@radix-ui/react-scroll-area": "1.1.0",
"@radix-ui/react-select": "2.0.0",
"@radix-ui/react-slider": "1.2.0",
"@radix-ui/react-slot": "1.1.0",
"class-variance-authority": "0.7.0",
"clsx": "2.1.0",
"cmdk": "1.0.0",
"date-fns": "3.6.0",
"framer-motion": "11.2.10",
"fs-extra": "11.2.0",
"lucide-react": "0.395.0",
"lucide-react": "0.427.0",
"next": "14.2.3",
"next-themes": "0.3.0",
"path": "0.12.7",
Expand Down
15 changes: 9 additions & 6 deletions pnpm-lock.yaml

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

Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export function ModernInnerShadowCardVariant1() {
return (
<div
className={cn(
"rounded-2xl border text-card-foreground p-6 max-w-sm mx-auto group dark:border-white/10 border-neutral-500/10 ",
"rounded-2xl border p-6 max-w-sm group dark:border-white/10 border-neutral-500/10 ",
"dark:shadow-[2px_4px_16px_0px_rgba(248,248,248,0.06)_inset]",
"hover:scale-[1.01] transition-transform transform-gpu group",
"bg-gray-50 dark:bg-neutral-800/80",
Expand Down
1 change: 1 addition & 0 deletions src/app/(components)/common-ui/cards/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default async function Page() {
isIframed={false}
title="Modern inner shadow card"
description="A card that showcases a set of tools that you use to create your product."
componentBadges={["better-in-dark-mode"]}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
"use client";
import React, { useEffect, useState } from "react";
import "#/src/styles/globals.css";
import { cn } from "#/src/utils/cn";

//TODO : Improve mobile version to display the image down the corresponding text instead of at the full bottom

const data = [
{
title: "Visit the cuicui.day website",
content:
"Visit the cuicui.day website and browse through the dozens of available components to help you build your web or mobile application.",
srcImage:
"https://images.unsplash.com/photo-1717501219716-b93a67d2f7b2?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzfHx8ZW58MHx8fHx8",
},
{
title: "Browse the site and choose your component",
content:
"Browse the categories, the variants of each component, try them out, and integrate them into your project with just a few clicks.",
srcImage:
"https://images.unsplash.com/photo-1717501219074-943fc738e5a2?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwcm9maWxlLXBhZ2V8M3x8fGVufDB8fHx8fA%3D%3D",
},
{
title: "Set up your environment",
content:
"Set up your development environment to integrate Cuicui library components. You can customize them infinitely to match your branding guidelines.",
srcImage:
"https://images.unsplash.com/photo-1717501218636-a390f9ac5957?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwcm9maWxlLXBhZ2V8Nnx8fGVufDB8fHx8fA%3D%3D",
},
{
title: "Copy and paste the code",
content:
"Copy and paste the code generated by the Cuicui library into your project and enjoy modern, ready-to-use components.",
srcImage:
"https://images.unsplash.com/photo-1717501219781-54ac9d09051b?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwcm9maWxlLXBhZ2V8N3x8fGVufDB8fHx8fA%3D%3D",
},
];

export function Variant1FeatureFourImages() {
const [featureOpen, setFeatureOpen] = useState<number>(0);
const [timer, setTimer] = useState<number>(0);
useEffect(() => {
const interval = setInterval(() => {
setTimer((prev) => prev + 10);
}, 10);
return () => clearInterval(interval);
}, []);

useEffect(() => {
if (timer > 10000) {
setFeatureOpen((prev) => (prev + 1) % data.length);
setTimer(0);
}
}, [timer]);

return (
<div className="container">
<div className="text-center mb-20">
<p className=" uppercase text-neutral-500 mb-2 text-sm font-medium">
How does it work ?
</p>

<h2 className="text-3xl font-semibold tracking-tighter dark:text-neutral-300 text-neutral-800 mb-4">
How to use the Easiest component librairy : Cuicui
</h2>
</div>
<div className=" grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="space-y-6 ">
{data.map((item, index) => (
<button
type="button"
className="w-full"
key={item.title}
onClick={() => {
setFeatureOpen(index);
setTimer(0);
}}
>
<TextComponent
number={index + 1}
title={item.title}
content={item.content}
isOpen={featureOpen === index}
loadingWidthPercent={featureOpen === index ? timer / 100 : 0}
/>
</button>
))}
</div>
<div className="h-full">
<div
className={cn(
"relative h-96 md:h-[500px] w-full rounded-lg overflow-hidden",
)}
>
{data.map((item, index) => (
<img
key={item.title}
src={item.srcImage}
alt={item.title}
className={cn(
"rounded-lg absolute w-full object-cover transition-all duration-300 h-[500px] transform-gpu",
featureOpen === index ? "scale-100" : "scale-70",
featureOpen > index ? "translate-y-full" : "",
)}
style={{ zIndex: data.length - index }}
/>
))}
</div>
</div>
</div>
</div>
);
}

function TextComponent({
number,
title,
content,
isOpen,
loadingWidthPercent,
}: Readonly<{
number: number;
title: string;
content: string;
isOpen: boolean;
loadingWidthPercent?: number;
}>) {
return (
<div
className={cn(
"transition-all rounded-lg transform-gpu border",
isOpen
? "bg-gradient-to-b from-neutral-200/15 to-neutral-200/5 dark:from-neutral-600/15 dark:to-neutral-600/5 dark:border-neutral-500/15 border-neutral-500/10 dark:shadow-[2px_4px_25px_0px_rgba(248,248,248,0.06)_inset] "
: "saturate-0 opacity-50 border-transparent scale-90",
)}
>
<div className="w-full p-4 flex gap-4 items-center">
<p
className={cn(
"inline-flex size-8 rounded-md items-center justify-center text-neutral-600 bg-neutral-500/20 shrink-0",
)}
>
{number}
</p>
<h2
className={cn(
"text-xl font-medium dark:text-neutral-200 text-neutral-800 text-left",
)}
>
{title}
</h2>
</div>
<div
className={cn(
"overflow-hidden transition-all duration-500 text-left dark:text-neutral-400 text-neutral-600 w-full transform-gpu",
isOpen ? " max-h-64" : "max-h-0",
)}
>
<p className="p-4 text-lg">{content}</p>
<div className="w-full pb-4 px-4">
<div className="h-1 relative rounded-full w-full overflow-hidden">
<div
className={cn("absolute top-0 left-0 h-1 bg-neutral-500")}
style={{ width: `${loadingWidthPercent}%` }}
/>
</div>
</div>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"use client";
import Image from "next/image";
import React, { useEffect, useState } from "react";
import "#/src/styles/globals.css";
import { cn } from "#/src/utils/cn";
Expand All @@ -7,36 +8,36 @@ import { cn } from "#/src/utils/cn";

const data = [
{
title: "Paramétrez votre CRA en 3 clicks",
title: "Visit the cuicui.day website",
content:
"Sélectionnez votre période, le prestataire qui réalise la mission et le client pour lequel vous travaillez : votre CRA est créé et prêt à être rempli.",
"Visit the cuicui.day website and browse through the dozens of available components to help you build your web or mobile application.",
srcImage:
"https://images.unsplash.com/photo-1717501219716-b93a67d2f7b2?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxlZGl0b3JpYWwtZmVlZHwzfHx8ZW58MHx8fHx8",
},
{
title: "Saissisez vos temps sans effort",
title: "Browse the site and choose your component",
content:
"Que vous travailliez à l’heure ou à la journée, Timizer vous permet de remplir simplement et rapidement les temps que vous avez passés quotidiennement sur votre mission sur votre CRA.",
"Browse the categories, the variants of each component, try them out, and integrate them into your project with just a few clicks.",
srcImage:
"https://images.unsplash.com/photo-1717501219074-943fc738e5a2?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwcm9maWxlLXBhZ2V8M3x8fGVufDB8fHx8fA%3D%3D",
},
{
title: "Exportez votre CRA au format PDF",
title: "Set up your environment",
content:
"Chaque fin de mois, générez un PDF contenant toutes les informations utiles de la mission, en y intégrant votre signature, avant de le soumettre à la validation de votre client.",
"Set up your development environment to integrate Cuicui library components. You can customize them infinitely to match your branding guidelines.",
srcImage:
"https://images.unsplash.com/photo-1717501218636-a390f9ac5957?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwcm9maWxlLXBhZ2V8Nnx8fGVufDB8fHx8fA%3D%3D",
},
{
title: "Faites-le signer par votre client",
title: "Copy and paste the code",
content:
"Une fois votre CRA validé, plus besoin de l’imprimer : partagez-le à votre client et faites-le signer directement en ligne depuis l’application Timizer dans une interface dédiée et sécurisée.",
"Copy and paste the code generated by the Cuicui library into your project and enjoy modern, ready-to-use components.",
srcImage:
"https://images.unsplash.com/photo-1717501219781-54ac9d09051b?w=600&auto=format&fit=crop&q=60&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwcm9maWxlLXBhZ2V8N3x8fGVufDB8fHx8fA%3D%3D",
},
];

export function Variant1FeatureFourImages() {
export function Variant2FeatureFourImages() {
const [featureOpen, setFeatureOpen] = useState<number>(0);
const [timer, setTimer] = useState<number>(0);
useEffect(() => {
Expand All @@ -56,12 +57,12 @@ export function Variant1FeatureFourImages() {
return (
<div className="container">
<div className="text-center mb-20">
<p className=" uppercase text-green-500 mb-2 text-lg font-medium">
Comment ça marche
<p className=" uppercase text-violet-500 mb-2 text-lg font-medium">
How does it work ?
</p>

<h2 className="text-3xl font-medium dark:text-gray-300 text-gray-800 mb-4">
La gestion de votre CRA simplifée en 4 étapes
<h2 className="text-3xl font-medium dark:text-gray-300 text-gray-800 mb-4 shrink-0">
How to use the Easiest component librairy : Cuicui
</h2>
</div>
<div className=" grid grid-cols-1 md:grid-cols-2 gap-4">
Expand Down Expand Up @@ -89,16 +90,18 @@ export function Variant1FeatureFourImages() {
<div className="h-full">
<div
className={cn(
"relative h-96 md:h-full w-full rounded-lg overflow-hidden",
"relative h-[500px] w-full rounded-lg overflow-hidden",
)}
>
{data.map((item, index) => (
<img
<Image
key={item.title}
src={item.srcImage}
alt={item.title}
width={400}
height={800}
className={cn(
"rounded-lg absolute w-full object-cover transition-all duration-300 h-full transform-gpu",
"rounded-lg absolute w-full object-cover transition-all duration-300 h-[500px] transform-gpu",
featureOpen === index ? "scale-100" : "scale-70",
featureOpen > index ? "translate-y-full" : "",
)}
Expand Down Expand Up @@ -129,13 +132,13 @@ function TextComponent({
<div
className={cn(
"transition-colors rounded-lg transform-gpu",
isOpen ? "bg-green-600/10" : "saturate-0 opacity-50",
isOpen ? "bg-violet-600/10" : "saturate-0 opacity-50",
)}
>
<div className="w-full p-4 flex gap-4 items-center">
<p
className={cn(
"inline-flex size-8 rounded-md items-center justify-center text-green-600 bg-green-500/20",
"inline-flex size-8 rounded-md items-center justify-center text-violet-600 bg-violet-500/20",
)}
>
{number}
Expand All @@ -158,7 +161,7 @@ function TextComponent({
<div className="w-full pb-4 px-4">
<div className="h-1 relative rounded-full w-full overflow-hidden">
<div
className={cn("absolute top-0 left-0 h-1 bg-green-500")}
className={cn("absolute top-0 left-0 h-1 bg-violet-500")}
style={{ width: `${loadingWidthPercent}%` }}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,29 @@ import FullComponent from "#/src/components/full-component";
import { getFileContentAsString } from "#/src/utils/get-file-content-as-string";
import { AnimatedCardVariant1 } from "./animated-cards/variant1";
import { Variant1FeatureFourImages } from "./feature-four-images/variant1";
import { Variant2FeatureFourImages } from "./feature-four-images/variant2";

export default async function Page() {
return (
<>
<FullComponent
componentList={[
{
variantName: "test",
variantName: "Sober colors",
component: <Variant1FeatureFourImages />,
code: await getFileContentAsString({
componentSlug: "features",
variantName: "feature-four-images/variant1",
}),
},
{
variantName: "Less animations with colors",
component: <Variant2FeatureFourImages />,
code: await getFileContentAsString({
componentSlug: "features",
variantName: "feature-four-images/variant2",
}),
},
]}
title="Feature Four Images"
description="An auto-scrolling feature section with four images and text. It could be also used with videos or other content. Perfect to shocase in details multiple features of a product or service."
Expand Down
Loading

0 comments on commit 9e51fc1

Please sign in to comment.