feat: image filter

This commit is contained in:
VizoleLabs 2024-04-08 06:22:33 +00:00
parent 7242a0afab
commit 67fe4ba060
10 changed files with 38350 additions and 1079 deletions

View file

@ -1,7 +1,7 @@
import "styles/tailwind.css" import "styles/tailwind.css"
import "styles/custom.css" import "styles/custom.css"
import Navbar from "components/Navbar/Navbar" import Navbar from "components/Navbar/Navbar"
import StarBackground from "components/StarBackground/StarBackground";
import Footer from "components/Footer/Footer" import Footer from "components/Footer/Footer"
export default function RootLayout({ children }: { children: React.ReactNode }) { export default function RootLayout({ children }: { children: React.ReactNode }) {

View file

@ -13,6 +13,7 @@ import { MdOutlineAppSettingsAlt } from "react-icons/md"
import { Glow, GlowCapture } from "@codaworks/react-glow" import { Glow, GlowCapture } from "@codaworks/react-glow"
import StarBackground from "components/StarBackground/StarBackground" import StarBackground from "components/StarBackground/StarBackground"
import { Textarea } from "@nextui-org/react" import { Textarea } from "@nextui-org/react"
import ImageFilter from "components/ImageFilter/ImageFilter"
export default function Web() { export default function Web() {
const [init, setInit] = useState(false) const [init, setInit] = useState(false)
@ -25,7 +26,7 @@ export default function Web() {
<div> <div>
<section className="bg-[#0f172a] md:pl-0 md:pr-0 lg:pl-[15%] lg:pr-[15%]"> <section className="bg-[#0f172a] md:pl-0 md:pr-0 lg:pl-[15%] lg:pr-[15%]">
<div <div
className=" h-[80%] rounded-[3rem] pt-[10%]" className=" h-[80%] rounded-[3rem] pt-[10%] max-md:rounded-none"
style={{ style={{
backgroundImage: `url('/images/glow-bottom.svg')`, backgroundImage: `url('/images/glow-bottom.svg')`,
backgroundSize: "fill", backgroundSize: "fill",
@ -73,7 +74,7 @@ export default function Web() {
</section> </section>
<section className="bg-[#0f172a] md:pl-0 md:pr-0 lg:pl-[15%] lg:pr-[15%]"> <section className="bg-[#0f172a] md:pl-0 md:pr-0 lg:pl-[15%] lg:pr-[15%]">
<div <div
className=" h-[60%] rounded-[3rem]" className=" h-[60%] rounded-[3rem] max-md:rounded-none"
style={{ style={{
backgroundImage: `url('/images/glow-top.svg')`, backgroundImage: `url('/images/glow-top.svg')`,
backgroundSize: "cover", backgroundSize: "cover",
@ -81,7 +82,7 @@ export default function Web() {
backgroundRepeat: "no-repeat", backgroundRepeat: "no-repeat",
}} }}
> >
<div className="flex w-[100%] items-center justify-around pb-[10vh] pt-[5vh]"> <div className="flex w-[100%] items-center justify-around pb-[10vh] pt-[5vh] max-md:flex-wrap">
<div className="mx-auto max-w-screen-xl px-4 py-8 lg:py-16"> <div className="mx-auto max-w-screen-xl px-4 py-8 lg:py-16">
<div className="mx-auto text-left text-white"> <div className="mx-auto text-left text-white">
<h4 className="bg-gradient-to-r from-vizoleG1 via-vizoleG2 to-vizoleG3 bg-clip-text pt-20 font-bold text-transparent "> <h4 className="bg-gradient-to-r from-vizoleG1 via-vizoleG2 to-vizoleG3 bg-clip-text pt-20 font-bold text-transparent ">
@ -127,8 +128,7 @@ export default function Web() {
</div> </div>
<div> <div>
<iframe <iframe
width="560" className="h-[315px] w-[560px] max-md:h-[14rem] max-md:w-[25rem]"
height="315"
src="https://www.youtube.com/embed/_vhf0RZg0fg" src="https://www.youtube.com/embed/_vhf0RZg0fg"
title="YouTube video player" title="YouTube video player"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
@ -137,14 +137,16 @@ export default function Web() {
</div> </div>
</div> </div>
</section> </section>
<section className="mt-[3%] bg-[#0f172a] md:pl-0 md:pr-0 lg:pl-[10%] lg:pr-[10%]"> <section className="mt-[3%] bg-[#0f172a] max-md:p-4 md:pl-0 md:pr-0 lg:pl-[10%] lg:pr-[10%]">
<div> <div>
<GlowCapture> <GlowCapture>
<div className="flex flex-col items-center justify-around"> <div className="flex flex-col items-center justify-around">
<div className="mb-4 max-w-3xl text-center text-4xl font-extrabold capitalize leading-none tracking-tight text-white md:text-4xl xl:text-5xl"> <div className="mb-4 max-w-3xl text-center text-4xl font-extrabold capitalize leading-none tracking-tight text-white md:text-4xl xl:text-5xl">
<h2 className="">Our Services</h2> <h2 className="bg-gradient-to-r from-slate-400 via-white to-slate-400 bg-clip-text text-transparent">
Our Services
</h2>
</div> </div>
<p className="mb-6 max-w-2xl text-center font-light text-gray-200 md:text-lg lg:mb-8 lg:text-xl"> <p className="mb-6 max-w-2xl text-center font-light text-[#94a3b8] md:text-lg lg:mb-8 lg:text-xl">
Let us transform your vision into reality with cutting-edge VR/AR experiences and custom software Let us transform your vision into reality with cutting-edge VR/AR experiences and custom software
solutions powered by AI. solutions powered by AI.
</p> </p>
@ -189,7 +191,7 @@ export default function Web() {
</div> </div>
</div> </div>
</Glow> </Glow>
<Glow color="#F5887A"> <Glow color="#F0B37D">
<div className=" glowable-text flex max-w-[100%] items-center rounded-[20px] border p-4 glow:border-glow glow:bg-glow/[.50] glow:ring-2 glow:ring-glow"> <div className=" glowable-text flex max-w-[100%] items-center rounded-[20px] border p-4 glow:border-glow glow:bg-glow/[.50] glow:ring-2 glow:ring-glow">
<div className=" text-center"> <div className=" text-center">
<div className="mr-3 inline-flex flex-shrink-0 items-center justify-center rounded-full px-5 "> <div className="mr-3 inline-flex flex-shrink-0 items-center justify-center rounded-full px-5 ">
@ -228,7 +230,7 @@ export default function Web() {
</div> </div>
</div> </div>
</Glow> </Glow>
<Glow color="#C37EB6"> <Glow color="#F0B37D">
<div className=" glowable-text flex max-w-[100%] items-center rounded-[20px] border p-4 glow:border-glow glow:bg-glow/[.50] glow:ring-2 glow:ring-glow"> <div className=" glowable-text flex max-w-[100%] items-center rounded-[20px] border p-4 glow:border-glow glow:bg-glow/[.50] glow:ring-2 glow:ring-glow">
<div className=" text-center"> <div className=" text-center">
<div className="mr-3 inline-flex flex-shrink-0 items-center justify-center rounded-full px-5 "> <div className="mr-3 inline-flex flex-shrink-0 items-center justify-center rounded-full px-5 ">
@ -267,7 +269,7 @@ export default function Web() {
</div> </div>
</div> </div>
</Glow> </Glow>
<Glow color="#D30253"> <Glow color="#F0B37D">
<div className=" glowable-text flex max-w-[100%] items-center rounded-[20px] border p-4 glow:border-glow glow:bg-glow/[.50] glow:ring-2 glow:ring-glow"> <div className=" glowable-text flex max-w-[100%] items-center rounded-[20px] border p-4 glow:border-glow glow:bg-glow/[.50] glow:ring-2 glow:ring-glow">
<div className=" text-center"> <div className=" text-center">
<div className="mr-3 inline-flex flex-shrink-0 items-center justify-center rounded-full px-5 "> <div className="mr-3 inline-flex flex-shrink-0 items-center justify-center rounded-full px-5 ">
@ -311,36 +313,19 @@ export default function Web() {
</div> </div>
</section> </section>
<section className="h-[150vh] bg-[#0f172a] pl-[10%] pr-[10%] pt-40"> <section className="mb-32 h-[150vh] bg-[#0f172a] pl-[10%] pr-[10%] pt-40">
<div className="mx-auto place-self-center text-center"> <div className="mx-auto place-self-center text-center">
<div className="mb-4 text-center text-4xl font-extrabold capitalize leading-none tracking-tight text-white md:text-4xl xl:text-5xl"> <div className="mb-4 text-center text-4xl font-extrabold capitalize leading-none tracking-tight text-white md:text-4xl xl:text-5xl">
<h1 className="">Our Portfolio</h1> <h1 className="bg-gradient-to-r from-slate-400 via-white to-slate-400 bg-clip-text text-transparent">
Our Portfolio
</h1>
</div> </div>
<p className="pl-5 pr-5 text-2xl text-white"> <p className="pl-5 pr-5 text-2xl text-white">
The showcase of our innovations. Dive in to explore our diverse range of projects and see how we’re driving The showcase of our innovations. Dive in to explore our diverse range of projects and see how we’re driving
digital transformation across industries.” digital transformation across industries.”
</p> </p>
</div> </div>
<div className="grid grid-cols-2 gap-4 md:grid-cols-3"> <ImageFilter />
<div className="mt-10 flex max-w-full rounded-xl border border-gray-200 bg-transparent shadow dark:border-gray-700 dark:bg-gray-800">
<img className="h-auto max-w-full rounded-lg" src="/images/site01.png" alt="" />
</div>
<div className="mt-10 flex max-w-full rounded-xl border border-gray-200 bg-transparent shadow dark:border-gray-700 dark:bg-gray-800">
<img className="h-auto max-w-full rounded-lg" src="/images/site02.png" alt="" />
</div>
<div className="mt-10 flex max-w-full rounded-xl border border-gray-200 bg-transparent shadow dark:border-gray-700 dark:bg-gray-800">
<img className="h-auto max-w-full rounded-lg" src="/images/site03.png" alt="" />
</div>
<div className="mt-10 flex max-w-full rounded-xl border border-gray-200 bg-transparent shadow dark:border-gray-700 dark:bg-gray-800">
<img className="h-auto max-w-full rounded-lg" src="/images/site01.png" alt="" />
</div>
<div className="mt-10 flex max-w-full rounded-xl border border-gray-200 bg-transparent shadow dark:border-gray-700 dark:bg-gray-800">
<img className="h-auto max-w-full rounded-lg" src="/images/site02.png" alt="" />
</div>
<div className="flex] mt-10 max-w-full rounded-xl border border-gray-200 bg-transparent shadow dark:border-gray-700 dark:bg-gray-800">
<img className="h-auto max-w-full rounded-lg" src="/images/site03.png" alt="" />
</div>
</div>
</section> </section>
<section className="bg-[#0f172a] dark:bg-gray-900"> <section className="bg-[#0f172a] dark:bg-gray-900">

View file

@ -2,37 +2,67 @@ import { cva, type VariantProps } from "class-variance-authority"
import { twMerge } from "tailwind-merge" import { twMerge } from "tailwind-merge"
const button = cva( const button = cva(["inline-flex", "items-center", "rounded-xl", "text-center", "transition-colors", "delay-50"], {
[ variants: {
intent: {
"inline-flex", primary: ["bg-blue-400", "justify-center", "text-white", "hover:enabled:bg-blue-700"],
"items-center", secondary: [
"rounded-xl", "bg-transparent",
"text-center", "justify-center",
"transition-colors", "text-white",
"delay-50", "hover:bg-slate-100",
], "rounded-3xl",
{ "hover:text-vizoleG2",
variants: { "border-solid",
intent: { "border-2",
primary: ["bg-blue-400", "justify-center", "text-white", "hover:enabled:bg-blue-700"], "border-slate-100",
secondary: ["bg-transparent", "justify-center", "text-white", "hover:bg-slate-100", "rounded-3xl", "hover:text-vizoleG2", "border-solid", "border-2", "border-slate-100"], ],
hero1: ["text-black", "bg-white", "justify-center","font-medium", "rounded-3xl", "text-sm", "text-center", "me-2", "mb-2", "border-solid", "border-2", "border-slate-100"], hero1: [
aboutUs: ["text-left","bg-transparent", "text-white", "font-semibold", "hover:text-white", "py-2", "px-4", "border", "border-gray-400","transition-all", "hover:border-white", "rounded", "flex", , "my-1","w-[50%]"] "text-black",
}, "bg-white",
size: { "justify-center",
sm: ["min-w-20", "h-full", "min-h-10", "text-sm", "py-1.5", "px-4"], "font-medium",
lg: ["min-w-32", "h-full", "min-h-12", "text-lg", "py-2.5", "px-6"], "rounded-3xl",
hero1: ["min-w-15", "h-full", "min-h-5", "text-sm", "px-5", "py-2"] "text-sm",
}, "text-center",
underline: { true: ["underline"], false: [] }, "me-2",
"mb-2",
"border-solid",
"border-2",
"border-slate-100",
],
aboutUs: [
"text-left",
"bg-transparent",
"text-white",
"font-semibold",
"hover:text-white",
"py-2",
"px-4",
"border",
"border-gray-400",
"transition-all",
"hover:border-white",
"rounded",
"flex",
,
"my-1",
"w-[50%]",
"max-md:w-full",
],
}, },
defaultVariants: { size: {
intent: "primary", sm: ["min-w-20", "h-full", "min-h-10", "text-sm", "py-1.5", "px-4"],
size: "lg", lg: ["min-w-32", "h-full", "min-h-12", "text-lg", "py-2.5", "px-6"],
hero1: ["min-w-15", "h-full", "min-h-5", "text-sm", "px-5", "py-2"],
}, },
} underline: { true: ["underline"], false: [] },
) },
defaultVariants: {
intent: "primary",
size: "lg",
},
})
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLAnchorElement>, VariantProps<typeof button> { export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLAnchorElement>, VariantProps<typeof button> {
underline?: boolean underline?: boolean

View file

@ -0,0 +1,26 @@
export const FilterableData = [
{
name: "Web",
src: "/images/site01.png",
title: "Mountains",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
},
{
name: "UI/UX",
src: "/images/site02.png",
title: "BMW",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
},
{
name: "Web",
src: "/images/site03.png",
title: "Modeller",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
},
{
name: "Web",
src: "/images/site04.png",
title: "Billing App",
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
},
]

View file

@ -0,0 +1,59 @@
"use client"
import { Button } from "components/Button/Button"
import { useState } from "react"
import { Image } from "./image"
import { FilterableData } from "./FilterableData"
import { motion } from "framer-motion" // Import motion
const ImageFilter = () => {
const [activeFilter, setActiveFilter] = useState<string>("all")
const buttonCaptions = ["all", "Web", "Mobile App", "UI/UX"]
const handleFilterClick = (filter: string) => {
setActiveFilter(filter)
}
return (
<section className="mb-3 flex w-full flex-col gap-12 px-5 py-16 md:px-10 lg:px-16">
<div className="flex w-full flex-wrap items-start gap-3 md:justify-center md:gap-6">
{buttonCaptions.map((filter) => (
<button
key={filter}
onClick={() => handleFilterClick(filter)}
type="button"
className={`mb-2 rounded-lg border-2 border-[#F0B37D] px-5 py-2.5 text-sm font-medium capitalize text-white hover:bg-[#F0B37D] focus:outline-none ${
activeFilter === filter ? "bg-[#F0B37D]" : " "
}`}
>
{filter === "all" ? "Show all" : filter}
</button>
))}
{/* filtered cards display */}
</div>
<main className="grid w-full gap-x-5 gap-y-8 md:mt-8 md:grid-cols-2 lg:grid-cols-3">
{FilterableData.map((item, index) => (
<motion.div
key={index}
layout
className={`w-full cursor-pointer rounded-lg border border-gray-600 bg-gray-800 shadow ${
activeFilter === "all" || activeFilter === item.name
? "" /* Show card */
: "hidden" /* Hide if not matched */
}`}
>
<Image
className="h-[400px] w-full overflow-hidden rounded-lg"
image={item.src}
alt={item.name}
objectCover="object-cover"
/>
</motion.div>
))}
</main>
</section>
)
}
export default ImageFilter

View file

@ -0,0 +1,25 @@
type ImageOwnProps<T extends React.ElementType> = {
className: string
image: string
alt: string
objectCover?: string
as?: T
}
type ImageProps<T extends React.ElementType> = ImageOwnProps<T> & Omit<React.ComponentProps<T>, keyof ImageOwnProps<T>>
export const Image = <T extends React.ElementType = "div">({
className,
image,
alt,
objectCover,
as,
...rest
}: ImageProps<T>) => {
const Component = as || "div"
return (
<Component className={className} {...rest}>
<img src={image} alt={alt} className={`h-full w-full ${objectCover}`} />
</Component>
)
}

37091
package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -56,6 +56,7 @@
"@tsparticles/react": "^3.0.0", "@tsparticles/react": "^3.0.0",
"@vercel/otel": "^0.3.0", "@vercel/otel": "^0.3.0",
"class-variance-authority": "^0.7.0", "class-variance-authority": "^0.7.0",
"framer-motion": "^11.0.25",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"next": "^14.0.3", "next": "^14.0.3",
"next-compose-plugins": "^2.2.1", "next-compose-plugins": "^2.2.1",

BIN
public/images/site04.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 742 KiB

2086
yarn.lock

File diff suppressed because it is too large Load diff