Skip to content

Commit 094e6a8

Browse files
authored
Merge pull request #127 from itshover/feat/bags-ca-integration
Feat/bags ca integration
2 parents f403549 + 401301c commit 094e6a8

9 files changed

Lines changed: 522 additions & 63 deletions

File tree

app/page.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import Hero from "@/components/hero-section";
44
import Features from "@/components/features";
55
import CTASection from "@/components/cta-section";
66
import BackedBy from "@/components/backed-by";
7+
import TestimonialSection from "@/components/testimonials";
78

89
export default function Home() {
910
return (
@@ -12,6 +13,7 @@ export default function Home() {
1213
<Hero />
1314
<Features />
1415
<BackedBy />
16+
<TestimonialSection />
1517
<CTASection />
1618
</Container>
1719
</div>

components/backed-by.tsx

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
8181
</div>
8282
</>
8383
) : (
84-
<span>Upload Logo</span>
84+
<span className="text-xs lowercase">Upload Logo</span>
8585
)}
8686
</label>
8787
) : logoPreview ? (
@@ -96,8 +96,8 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
9696
) : sponsor.logo ? (
9797
<div className="text-foreground z-10">{sponsor.logo}</div>
9898
) : (
99-
<div className="border-border/60 text-muted-foreground/60 group-hover:border-border group-hover:text-muted-foreground/80 z-10 flex h-48 w-full items-center justify-center rounded-lg border border-dashed text-sm transition-colors sm:h-64">
100-
{sponsor.placeholderText || "Your Image Here"}
99+
<div className="border-border/60 text-muted-foreground/60 group-hover:border-border group-hover:text-muted-foreground/80 z-10 flex h-48 w-full items-center justify-center rounded-lg border border-dashed text-sm lowercase transition-colors sm:h-64">
100+
{sponsor.placeholderText || "your image here"}
101101
</div>
102102
)}
103103
</div>
@@ -109,19 +109,19 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
109109
<input
110110
value={name}
111111
onChange={(e) => setName(e.target.value)}
112-
className="border-primary/50 focus:border-primary placeholder:text-muted-foreground/50 max-w-full border-b bg-transparent py-1 text-2xl font-semibold tracking-tight outline-none"
113-
placeholder="Company Name"
112+
className="border-primary/50 focus:border-primary placeholder:text-muted-foreground/50 max-w-full border-b bg-transparent py-1 text-2xl font-semibold tracking-tight lowercase outline-none"
113+
placeholder="company name"
114114
autoFocus
115115
/>
116116
) : (
117-
<h3 className="text-2xl font-semibold tracking-tight">
118-
{name || "Company Name"}
117+
<h3 className="text-2xl font-semibold tracking-tight lowercase">
118+
{name || "company name"}
119119
</h3>
120120
)}
121121

122122
{sponsor.badge && (
123123
<span
124-
className={`rounded-md border px-2.5 py-1 text-xs font-medium whitespace-nowrap ${
124+
className={`rounded-md border px-2.5 py-1 text-[10px] font-medium whitespace-nowrap lowercase ${
125125
sponsor.badgeColor === "success"
126126
? "border-green-500/20 bg-green-500/10 text-green-500"
127127
: "bg-muted text-muted-foreground border-border/50"
@@ -136,13 +136,12 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
136136
<textarea
137137
value={description}
138138
onChange={(e) => setDescription(e.target.value)}
139-
className="text-muted-foreground border-primary/50 focus:border-primary placeholder:text-muted-foreground/50 mb-8 h-32 w-full resize-none rounded-md border bg-transparent p-3 text-[15px] leading-relaxed outline-none"
140-
placeholder="Write a short description about how your company supports developers or open source..."
139+
className="text-muted-foreground border-primary/50 focus:border-primary placeholder:text-muted-foreground/50 mb-8 h-32 w-full resize-none rounded-md border bg-transparent p-3 text-[15px] leading-relaxed lowercase outline-none"
140+
placeholder="write a short description about how your company supports developers or open source..."
141141
/>
142142
) : (
143-
<p className="text-muted-foreground mb-8 line-clamp-4 max-w-md text-[15px] leading-relaxed">
144-
{description ||
145-
"Add a description of your company and how you support the community."}
143+
<p className="text-muted-foreground mb-8 line-clamp-4 max-w-md text-[15px] leading-relaxed lowercase">
144+
{description}
146145
</p>
147146
)}
148147

@@ -154,7 +153,7 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
154153
target="_blank"
155154
rel="noopener noreferrer"
156155
>
157-
<SecondaryButton className="text-sm">
156+
<SecondaryButton className="text-sm lowercase">
158157
{sponsor.action.label}
159158
</SecondaryButton>
160159
</Link>
@@ -163,10 +162,10 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
163162

164163
{isEditing && (
165164
<SecondaryButton
166-
className="border-primary/50 text-primary hover:bg-primary/10 ml-auto text-sm"
165+
className="border-primary/50 text-primary hover:bg-primary/10 ml-auto text-sm lowercase"
167166
onClick={() => setIsEditing(false)}
168167
>
169-
Done Editing
168+
done editing
170169
</SecondaryButton>
171170
)}
172171
</div>
@@ -178,11 +177,11 @@ const SponsorCard = ({ sponsor }: { sponsor: SponsorProps }) => {
178177
export default function BackedBy() {
179178
const sponsors: SponsorProps[] = [
180179
{
181-
name: "Vercel",
182-
badge: "Open Source Program",
180+
name: "vercel",
181+
badge: "open source program",
183182
badgeColor: "default",
184183
description:
185-
"Providing the robust infrastructure that keeps Its Hover fast, reliable, and accessible to creators worldwide. Vercel enables seamless deployment with zero configuration.",
184+
"providing the robust infrastructure that keeps its hover fast, reliable, and accessible to creators worldwide. vercel enables seamless deployment with zero configuration.",
186185
logo: (
187186
<svg
188187
fill="currentColor"
@@ -196,13 +195,13 @@ export default function BackedBy() {
196195
),
197196
},
198197
{
199-
name: "Your Company Here",
198+
name: "your company here",
200199
description:
201-
"Join us in building the future of interactive icons. Sponsor Its Hover to get your brand featured here, reaching thousands of developers and designers.",
202-
placeholderText: "Your Logo Here",
200+
"join us in building the future of interactive icons. sponsor its hover to get your brand featured here, reaching thousands of developers and designers.",
201+
placeholderText: "your logo here",
203202
editable: true,
204203
action: {
205-
label: "Contact Us",
204+
label: "contact us",
206205
href: "https://x.com/abhijitwt",
207206
},
208207
},
@@ -217,35 +216,26 @@ export default function BackedBy() {
217216
viewport={{ once: true }}
218217
className="mb-16 flex flex-col items-center space-y-4 text-center"
219218
>
220-
<h2
221-
className="font-serif text-3xl md:text-4xl"
222-
style={{ fontFamily: "Georgia, serif" }}
223-
>
224-
Backed By
219+
<h2 className="text-4xl font-bold tracking-tight lowercase md:text-5xl">
220+
backed by
225221
</h2>
226-
<p className="text-muted-foreground max-w-2xl px-4">
227-
Its Hover is supported by incredible tools and companies.
222+
<p className="text-muted-foreground max-w-2xl px-4 lowercase">
223+
its hover is supported by incredible tools and companies.
228224
</p>
229225
</motion.div>
230226

231227
<div className="grid grid-cols-1 gap-6">
232-
<motion.div
233-
initial={{ opacity: 0, y: 20 }}
234-
whileInView={{ opacity: 1, y: 0 }}
235-
transition={{ duration: 0.5, delay: 0.1 }}
236-
viewport={{ once: true }}
237-
>
238-
<SponsorCard sponsor={sponsors[0]} />
239-
</motion.div>
240-
241-
<motion.div
242-
initial={{ opacity: 0, y: 20 }}
243-
whileInView={{ opacity: 1, y: 0 }}
244-
transition={{ duration: 0.5, delay: 0.2 }}
245-
viewport={{ once: true }}
246-
>
247-
<SponsorCard sponsor={sponsors[1]} />
248-
</motion.div>
228+
{sponsors.map((sponsor, index) => (
229+
<motion.div
230+
key={sponsor.name}
231+
initial={{ opacity: 0, y: 20 }}
232+
whileInView={{ opacity: 1, y: 0 }}
233+
transition={{ duration: 0.5, delay: 0.1 * (index + 1) }}
234+
viewport={{ once: true }}
235+
>
236+
<SponsorCard sponsor={sponsor} />
237+
</motion.div>
238+
))}
249239
</div>
250240
</section>
251241
);

components/footer.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"use client";
2-
import { useState } from "react";
2+
import { useState, useRef } from "react";
33
import Link from "next/link";
44
import { motion } from "motion/react";
5-
import { LINKS, SPONSOR } from "@/constants";
5+
import { LINKS, SPONSOR, TOKEN } from "@/constants";
66
import GithubIcon from "@/icons/github-icon";
77
import TwitterXIcon from "@/icons/twitter-x-icon";
88
import HeartIcon from "@/icons/heart-icon";
@@ -24,6 +24,8 @@ import GearIcon from "@/icons/gear-icon";
2424
import MessageCircleIcon from "@/icons/message-circle-icon";
2525
import SendIcon from "@/icons/send-icon";
2626
import CheckedIcon from "@/icons/checked-icon";
27+
import BrandBagsFmIcon from "@/icons/brand-bags-fm-icon";
28+
import type { AnimatedIconHandle } from "@/icons/types";
2729
import RequestIconModal from "./request-icon-modal";
2830

2931
const CryptoAddress = ({
@@ -79,6 +81,7 @@ const Footer = () => {
7981
];
8082

8183
const [isRequestModalOpen, setIsRequestModalOpen] = useState(false);
84+
const bagsIconRef = useRef<AnimatedIconHandle>(null);
8285

8386
return (
8487
<motion.footer
@@ -142,6 +145,7 @@ const Footer = () => {
142145
</Link>
143146
<div className="text-muted-foreground space-y-2 text-sm">
144147
<p className="text-foreground font-medium">Crypto</p>
148+
<CryptoAddress label="CA" address={TOKEN.CA} />
145149
<CryptoAddress label="BTC" address={SPONSOR.btc} />
146150
<CryptoAddress label="ETH" address={SPONSOR.eth} />
147151
<CryptoAddress label="SOL" address={SPONSOR.sol} />
@@ -214,6 +218,17 @@ const Footer = () => {
214218
>
215219
<TwitterXIcon size={20} />
216220
</Link>
221+
<Link
222+
href={LINKS.BAGS}
223+
target="_blank"
224+
rel="noreferrer"
225+
onMouseEnter={() => bagsIconRef.current?.startAnimation()}
226+
onMouseLeave={() => bagsIconRef.current?.stopAnimation()}
227+
className="text-muted-foreground hover:text-foreground transition-colors"
228+
aria-label="Bags"
229+
>
230+
<BrandBagsFmIcon ref={bagsIconRef} size={20} />
231+
</Link>
217232
</div>
218233
</div>
219234
</div>

components/hero-section.tsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"use client";
2-
import { useRef, useEffect, useCallback } from "react";
2+
import { useRef, useEffect, useCallback, useState } from "react";
33
import Link from "next/link";
44
import PrimaryButton from "@/components/ui/primary-button";
55
import SecondaryButton from "@/components/ui/secondary-button";
@@ -14,9 +14,20 @@ import LikeIcon from "@/icons/like-icon";
1414
import SendIcon from "@/icons/send-icon";
1515
import GhostIcon from "@/icons/ghost-icon";
1616
import ArrowNarrowRightIcon from "@/icons/arrow-narrow-right-icon";
17+
import CopyIcon from "@/icons/copy-icon";
18+
import CheckedIcon from "@/icons/checked-icon";
19+
import { TOKEN } from "@/constants";
1720
import type { AnimatedIconHandle } from "@/icons/types";
1821

1922
const Hero = () => {
23+
const [copied, setCopied] = useState(false);
24+
25+
const handleCopy = async () => {
26+
await navigator.clipboard.writeText(TOKEN.CA);
27+
setCopied(true);
28+
setTimeout(() => setCopied(false), 2000);
29+
};
30+
2031
const textAnimation = {
2132
initial: {
2233
opacity: 0,
@@ -56,6 +67,30 @@ const Hero = () => {
5667
Editable React components with motion baked in. Works seamlessly with
5768
Next.js, shadcn, and modern design systems.
5869
</motion.p>
70+
<motion.div
71+
variants={textAnimation}
72+
initial="initial"
73+
animate="animate"
74+
transition={{ ...textAnimation.transition, delay: 0.1 }}
75+
className="flex flex-col items-center pt-4"
76+
>
77+
<button
78+
onClick={handleCopy}
79+
className="text-muted-foreground hover:text-foreground flex items-center gap-2 transition-colors"
80+
>
81+
<span className="font-mono text-xs font-medium tracking-wider uppercase">
82+
ca:{" "}
83+
<span className="text-foreground/80 font-normal break-all lowercase">
84+
{TOKEN.CA}
85+
</span>
86+
</span>
87+
{copied ? (
88+
<CheckedIcon className="h-3 w-3 text-green-500" />
89+
) : (
90+
<CopyIcon className="h-3 w-3 border-none bg-transparent" />
91+
)}
92+
</button>
93+
</motion.div>
5994
</div>
6095
<motion.div
6196
variants={textAnimation}

0 commit comments

Comments
 (0)