bandsbender's picture
Upload 348 files
21a686e verified
raw
history blame
19.7 kB
"use client";
import React from "react";
import { Shield } from "lucide-react";
import { useId } from "react";
import { cn } from "@/lib/utils";
import Image from "next/image";
import { motion } from "motion/react";
export function ContactFormGridWithDetails() {
return (
<div className="mx-auto grid w-full max-w-7xl grid-cols-1 gap-10 px-4 py-10 md:px-6 md:py-20 lg:grid-cols-2">
<div className="relative flex flex-col items-center overflow-hidden lg:items-start">
<motion.div
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.2 }}
className="flex items-start justify-start"
>
<FeatureIconContainer className="flex items-center justify-center overflow-hidden">
<motion.div
animate={{ rotate: [0, 360] }}
transition={{ duration: 2, repeat: Infinity, ease: "linear" }}
>
<Shield className="h-6 w-6 text-red-primary" />
</motion.div>
</FeatureIconContainer>
</motion.div>
<motion.h2
initial={{ y: -50, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.4 }}
className="mt-9 bg-gradient-to-b from-dark-gray-secondary to-dark-gray-secondary bg-clip-text text-left text-xl font-bold text-transparent md:text-3xl lg:text-5xl"
>
Get Your Free Quote
</motion.h2>
<motion.p
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.6 }}
className="mt-8 max-w-lg text-center text-base text-supporting-gray md:text-left"
>
Contact our experts for a personalized consultation and quote.
</motion.p>
<motion.div
initial={{ x: -50, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.8 }}
className="mt-10 hidden flex-col items-center gap-4 md:flex-row lg:flex"
>
<motion.p
whileHover={{ scale: 1.1 }}
transition={{ duration: 0.3 }}
className="text-sm text-supporting-gray"
>
raghavsukhadia@gmail.com
</motion.p>
<div className="h-1 w-1 rounded-full bg-supporting-gray" />
<motion.p
whileHover={{ scale: 1.1 }}
transition={{ duration: 0.3 }}
className="text-sm text-supporting-gray"
>
+91 8657081114
</motion.p>
<div className="h-1 w-1 rounded-full bg-supporting-gray" />
<motion.p
whileHover={{ scale: 1.1 }}
transition={{ duration: 0.3 }}
className="text-sm text-supporting-gray"
>
303 Western Palace, Congress Nagar, Opposite Park, Nagpur
</motion.p>
</motion.div>
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 1.0 }}
className="mt-8 space-y-2 hidden lg:flex lg:flex-col"
>
<h3 className="text-lg font-semibold text-dark-gray-secondary">Business Hours</h3>
<div className="space-y-1 text-sm text-supporting-gray">
<motion.p
whileHover={{ x: 10 }}
transition={{ duration: 0.3 }}
>
Monday - Saturday: 10:00 AM - 08:00 PM
</motion.p>
<motion.p
whileHover={{ x: 10 }}
transition={{ duration: 0.3 }}
>
Sunday: Closed
</motion.p>
</div>
<motion.p
animate={{
color: ["#DC2626", "#EF4444", "#DC2626"],
textShadow: ["0 0 5px #DC2626", "0 0 10px #DC2626", "0 0 5px #DC2626"]
}}
transition={{ duration: 2, repeat: Infinity }}
className="text-sm text-red-primary font-medium pt-2"
>
Free on-site consultations available
</motion.p>
</motion.div>
<motion.div
initial={{ scale: 0, opacity: 0 }}
animate={{ scale: 1, opacity: 1 }}
transition={{ duration: 1, delay: 1.2 }}
className="div relative mt-20 flex w-[600px] flex-shrink-0 -translate-x-10 items-center justify-center [perspective:800px] [transform-style:preserve-3d] sm:-translate-x-0 lg:-translate-x-32"
>
<Pin className="top-0 right-1" />
<motion.div
animate={{ rotateY: [0, 360] }}
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
>
<Image
src="/world.svg"
width={500}
height={500}
alt="world map"
className="[transform:rotateX(45deg)_translateZ(0px)] dark:invert dark:filter"
/>
</motion.div>
</motion.div>
</div>
<motion.div
initial={{ x: 50, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.4 }}
className="relative mx-auto flex w-full max-w-2xl flex-col items-start gap-4 overflow-hidden rounded-3xl bg-gradient-to-b from-gray-100 to-gray-200 p-4 sm:p-10 dark:from-neutral-900 dark:to-neutral-950"
>
<Grid size={20} />
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 0.6 }}
className="relative z-20 mb-4 w-full"
>
<label
className="mb-2 inline-block text-sm font-medium text-dark-gray-secondary"
htmlFor="name"
>
Name
</label>
<input
id="name"
type="text"
placeholder="Your Full Name"
className="shadow-input h-10 w-full rounded-md border border-transparent bg-white pl-4 text-sm text-dark-gray-secondary placeholder-supporting-gray outline-none focus:ring-2 focus:ring-red-primary focus:outline-none active:outline-none transition-all duration-300 focus:scale-105"
/>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 0.7 }}
className="relative z-20 mb-4 w-full"
>
<label
className="mb-2 inline-block text-sm font-medium text-dark-gray-secondary"
htmlFor="email"
>
Email
</label>
<input
id="email"
type="email"
placeholder="your@email.com"
className="shadow-input h-10 w-full rounded-md border border-transparent bg-white pl-4 text-sm text-dark-gray-secondary placeholder-supporting-gray outline-none focus:ring-2 focus:ring-red-primary focus:outline-none active:outline-none transition-all duration-300 focus:scale-105"
/>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 0.8 }}
className="relative z-20 mb-4 w-full"
>
<label
className="mb-2 inline-block text-sm font-medium text-dark-gray-secondary"
htmlFor="phone"
>
Phone
</label>
<input
id="phone"
type="tel"
placeholder="+91 8657081114"
className="shadow-input h-10 w-full rounded-md border border-transparent bg-white pl-4 text-sm text-dark-gray-secondary placeholder-supporting-gray outline-none focus:ring-2 focus:ring-red-primary focus:outline-none active:outline-none transition-all duration-300 focus:scale-105"
/>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 0.9 }}
className="relative z-20 mb-4 w-full"
>
<label
className="mb-2 inline-block text-sm font-medium text-dark-gray-secondary"
htmlFor="property-type"
>
Property Type
</label>
<select
id="property-type"
className="shadow-input h-10 w-full rounded-md border border-transparent bg-white pl-4 text-sm text-dark-gray-secondary outline-none focus:ring-2 focus:ring-red-primary focus:outline-none active:outline-none transition-all duration-300 focus:scale-105"
>
<option value="">Select Property Type</option>
<option value="residential">Residential</option>
<option value="commercial">Commercial</option>
<option value="automotive">Automotive</option>
</select>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 1.0 }}
className="relative z-20 mb-4 w-full"
>
<label
className="mb-2 inline-block text-sm font-medium text-dark-gray-secondary"
htmlFor="service-needed"
>
Service Needed
</label>
<select
id="service-needed"
className="shadow-input h-10 w-full rounded-md border border-transparent bg-white pl-4 text-sm text-dark-gray-secondary outline-none focus:ring-2 focus:ring-red-primary focus:outline-none active:outline-none transition-all duration-300 focus:scale-105"
>
<option value="">Select Service</option>
<option value="new-installation">New Installation</option>
<option value="replacement">Replacement</option>
<option value="consultation">Consultation</option>
</select>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 1.1 }}
className="relative z-20 mb-4 w-full"
>
<label
className="mb-2 inline-block text-sm font-medium text-dark-gray-secondary"
htmlFor="message"
>
Message
</label>
<textarea
id="message"
rows={5}
placeholder="Tell us about your project..."
className="shadow-input w-full rounded-md border border-transparent bg-white pt-4 pl-4 text-sm text-dark-gray-secondary placeholder-supporting-gray outline-none focus:ring-2 focus:ring-red-primary focus:outline-none active:outline-none transition-all duration-300 focus:scale-105"
/>
</motion.div>
<motion.button
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.6, delay: 1.2 }}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
className="relative z-10 flex items-center justify-center rounded-md border border-transparent bg-red-primary px-4 py-2 text-sm font-medium text-white shadow-[0px_1px_0px_0px_#FFFFFF20_inset] transition-all duration-300 hover:bg-red-600 hover:shadow-lg hover:shadow-red-600/25 md:text-sm"
>
Get Free Quote
</motion.button>
</motion.div>
</div>
);
}
const Pin = ({ className }: { className?: string }) => {
return (
<motion.div
style={{ transform: "translateZ(1px)" }}
className={cn(
"pointer-events-none absolute z-[60] flex h-40 w-96 items-center justify-center opacity-100 transition duration-500",
className
)}
>
<div className="h-full w-full">
<motion.div
initial={{ y: -20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ duration: 0.8, delay: 0.5 }}
className="absolute inset-x-0 top-0 z-20 mx-auto inline-block w-fit rounded-lg bg-neutral-200 px-2 py-1 text-xs font-normal text-neutral-700 dark:bg-neutral-800 dark:text-white"
>
We are here
<motion.span
animate={{
background: ["linear-gradient(to right, rgba(59, 130, 246, 0) 0%, rgba(59, 130, 246, 0.9) 50%, rgba(59, 130, 246, 0) 100%)",
"linear-gradient(to right, rgba(220, 38, 38, 0) 0%, rgba(220, 38, 38, 0.9) 50%, rgba(220, 38, 38, 0) 100%)",
"linear-gradient(to right, rgba(59, 130, 246, 0) 0%, rgba(59, 130, 246, 0.9) 50%, rgba(59, 130, 246, 0) 100%)"]
}}
transition={{ duration: 3, repeat: Infinity }}
className="absolute -bottom-0 left-[1.125rem] h-px w-[calc(100%-2.25rem)] bg-gradient-to-r from-blue-400/0 via-blue-400/90 to-blue-400/0 transition-opacity duration-500"
/>
</motion.div>
<div
style={{
perspective: "800px",
transform: "rotateX(70deg) translateZ(0px)",
}}
className="absolute top-1/2 left-1/2 mt-4 ml-[0.09375rem] -translate-x-1/2 -translate-y-1/2"
>
<>
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{
opacity: [0, 1, 0.5, 0],
scale: 1,
}}
transition={{ duration: 6, repeat: Infinity, delay: 0 }}
className="absolute top-1/2 left-1/2 h-20 w-20 -translate-x-1/2 -translate-y-1/2 rounded-[50%] bg-sky-500/[0.08] shadow-[0_8px_16px_rgb(0_0_0/0.4)] dark:bg-sky-500/[0.2]"
/>
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{
opacity: [0, 1, 0.5, 0],
scale: 1,
}}
transition={{ duration: 6, repeat: Infinity, delay: 2 }}
className="absolute top-1/2 left-1/2 h-20 w-20 -translate-x-1/2 -translate-y-1/2 rounded-[50%] bg-sky-500/[0.08] shadow-[0_8px_16px_rgb(0_0_0/0.4)] dark:bg-sky-500/[0.2]"
/>
<motion.div
initial={{ opacity: 0, scale: 0 }}
animate={{
opacity: [0, 1, 0.5, 0],
scale: 1,
}}
transition={{ duration: 6, repeat: Infinity, delay: 4 }}
className="absolute top-1/2 left-1/2 h-20 w-20 -translate-x-1/2 -translate-y-1/2 rounded-[50%] bg-sky-500/[0.08] shadow-[0_8px_16px_rgb(0_0_0/0.4)] dark:bg-sky-500/[0.2]"
/>
</>
</div>
<>
<motion.div
animate={{
background: ["linear-gradient(to bottom, transparent, #3b82f6)",
"linear-gradient(to bottom, transparent, #dc2626)",
"linear-gradient(to bottom, transparent, #3b82f6)"]
}}
transition={{ duration: 3, repeat: Infinity }}
className="absolute right-1/2 bottom-1/2 h-20 w-px translate-y-[14px] bg-gradient-to-b from-transparent to-blue-500 blur-[2px]"
/>
<motion.div
animate={{
background: ["linear-gradient(to bottom, transparent, #3b82f6)",
"linear-gradient(to bottom, transparent, #dc2626)",
"linear-gradient(to bottom, transparent, #3b82f6)"]
}}
transition={{ duration: 3, repeat: Infinity }}
className="absolute right-1/2 bottom-1/2 h-20 w-px translate-y-[14px] bg-gradient-to-b from-transparent to-blue-500"
/>
<motion.div
animate={{
backgroundColor: ["#2563eb", "#dc2626", "#2563eb"],
boxShadow: ["0 0 10px #2563eb", "0 0 15px #dc2626", "0 0 10px #2563eb"]
}}
transition={{ duration: 3, repeat: Infinity }}
className="absolute right-1/2 bottom-1/2 z-40 h-[4px] w-[4px] translate-x-[1.5px] translate-y-[14px] rounded-full bg-blue-600 blur-[3px]"
/>
<motion.div
animate={{
backgroundColor: ["#93c5fd", "#fca5a5", "#93c5fd"]
}}
transition={{ duration: 3, repeat: Infinity }}
className="absolute right-1/2 bottom-1/2 z-40 h-[2px] w-[2px] translate-x-[0.5px] translate-y-[14px] rounded-full bg-blue-300"
/>
</>
</div>
</motion.div>
);
};
export const FeatureIconContainer = ({
children,
className,
}: {
children: React.ReactNode;
className?: string;
}) => {
return (
<div
className={cn(
"relative h-14 w-14 rounded-md bg-gradient-to-b from-gray-50 to-neutral-200 p-[4px] dark:from-neutral-800 dark:to-neutral-950",
className
)}
>
<div
className={cn(
"relative z-20 h-full w-full rounded-[5px] bg-gray-50 dark:bg-neutral-800",
className
)}
>
{children}
</div>
<div className="absolute inset-x-0 bottom-0 z-30 mx-auto h-4 w-full rounded-full bg-neutral-600 opacity-50 blur-lg"></div>
<div className="absolute inset-x-0 bottom-0 mx-auto h-px w-[60%] bg-gradient-to-r from-transparent via-red-primary to-transparent"></div>
<div className="absolute inset-x-0 bottom-0 mx-auto h-px w-[60%] bg-gradient-to-r from-transparent via-red-600 to-transparent dark:h-[8px] dark:blur-sm"></div>
</div>
);
};
export const Grid = ({
pattern,
size,
}: {
pattern?: number[][];
size?: number;
}) => {
const p = pattern ?? [
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
[Math.floor(Math.random() * 4) + 7, Math.floor(Math.random() * 6) + 1],
];
return (
<div className="pointer-events-none absolute top-0 left-1/2 -mt-2 -ml-20 h-full w-full [mask-image:linear-gradient(white,transparent)]">
<div className="absolute inset-0 bg-gradient-to-r from-zinc-900/30 to-zinc-900/30 opacity-10 [mask-image:radial-gradient(farthest-side_at_top,white,transparent)] dark:from-zinc-900/30 dark:to-zinc-900/30">
<GridPattern
width={size ?? 20}
height={size ?? 20}
x="-12"
y="4"
squares={p}
className="absolute inset-0 h-full w-full fill-black/100 stroke-black/100 mix-blend-overlay dark:fill-white/100 dark:stroke-white/100"
/>
</div>
</div>
);
};
export function GridPattern({ width, height, x, y, squares, ...props }: any) {
const patternId = useId();
return (
<svg aria-hidden="true" {...props}>
<defs>
<pattern
id={patternId}
width={width}
height={height}
patternUnits="userSpaceOnUse"
x={x}
y={y}
>
<path d={`M.5 ${height}V.5H${width}`} fill="none" />
</pattern>
</defs>
<rect
width="100%"
height="100%"
strokeWidth={0}
fill={`url(#${patternId})`}
/>
{squares && (
<svg x={x} y={y} className="overflow-visible">
{squares.map(([x, y]: any, idx: number) => (
<rect
strokeWidth="0"
key={`${x}-${y}-${idx}`}
width={width + 1}
height={height + 1}
x={x * width}
y={y * height}
/>
))}
</svg>
)}
</svg>
);
}