Skip to content

Commit 81975cf

Browse files
fix(web): testimonials responsiveness and add more testimonials
1 parent b65aa47 commit 81975cf

File tree

2 files changed

+134
-110
lines changed

2 files changed

+134
-110
lines changed
Lines changed: 114 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
"use client";
22

3+
import { motion } from "framer-motion";
34
import { Terminal } from "lucide-react";
4-
import { motion } from "motion/react";
5-
import { useMemo } from "react";
65
import { Tweet } from "react-tweet";
76

87
const TWEET_IDS = [
@@ -13,9 +12,11 @@ const TWEET_IDS = [
1312
"1933149770639614324",
1413
"1937599252173128103",
1514
"1930511724702285885",
15+
"1945204056063913989",
1616
"1912836377365905496",
1717
"1907817662215757853",
1818
"1933216760896934060",
19+
"1942558041704182158",
1920
"1937383786637094958",
2021
"1931709370003583004",
2122
"1929147326955704662",
@@ -27,29 +28,39 @@ const TWEET_IDS = [
2728
"1917640304758514093",
2829
"1907831059275735353",
2930
"1912924558522524039",
31+
"1945054982870282575",
3032
"1933150129738981383",
3133
"1911490975173607495",
3234
"1930104047845158972",
3335
"1913773945523953713",
36+
"1944937093387706572",
3437
"1904241046898556970",
3538
"1913834145471672652",
39+
"1946245671880966269",
3640
"1930514202260635807",
3741
"1931589579749892480",
3842
"1904144343125860404",
3943
"1917610656477348229",
4044
"1904215768272654825",
4145
"1931830211013718312",
46+
"1944895251811893680",
4247
"1913833079342522779",
4348
"1930449311848087708",
49+
"1942680754384953790",
4450
"1907723601731530820",
51+
"1944553262792810603",
4552
"1904233896851521980",
4653
"1930294868808515726",
54+
"1943290033383047237",
4755
"1913801258789491021",
4856
"1907841646513005038",
4957
"1904301540422070671",
58+
"1944208789617471503",
5059
"1912837026925195652",
5160
"1904338606409531710",
61+
"1942965795920679188",
5262
"1904318186750652606",
63+
"1943656585294643386",
5364
"1908568583799484519",
5465
"1913018977321693448",
5566
"1904179661086556412",
@@ -61,20 +72,18 @@ const TWEET_IDS = [
6172
];
6273

6374
export default function Testimonials() {
64-
// Split tweets into 3 columns
65-
const columns = useMemo(() => {
66-
const col1: string[] = [];
67-
const col2: string[] = [];
68-
const col3: string[] = [];
75+
const getResponsiveColumns = (numCols: number) => {
76+
const columns: string[][] = Array(numCols)
77+
.fill(null)
78+
.map(() => []);
6979

7080
TWEET_IDS.forEach((tweetId, index) => {
71-
if (index % 3 === 0) col1.push(tweetId);
72-
else if (index % 3 === 1) col2.push(tweetId);
73-
else col3.push(tweetId);
81+
const colIndex = index % numCols;
82+
columns[colIndex].push(tweetId);
7483
});
7584

76-
return [col1, col2, col3];
77-
}, []);
85+
return columns;
86+
};
7887

7988
const containerVariants = {
8089
hidden: { opacity: 0 },
@@ -92,8 +101,43 @@ export default function Testimonials() {
92101
},
93102
};
94103

104+
const TweetCard = ({
105+
tweetId,
106+
index,
107+
}: {
108+
tweetId: string;
109+
index: number;
110+
}) => (
111+
<motion.div
112+
className="w-full min-w-0"
113+
initial={{ opacity: 0, y: 20, scale: 0.95 }}
114+
animate={{ opacity: 1, y: 0, scale: 1 }}
115+
transition={{
116+
delay: index * 0.05,
117+
duration: 0.4,
118+
ease: "easeOut",
119+
}}
120+
>
121+
<div className="terminal-block-hover w-full min-w-0 overflow-hidden rounded border border-border bg-background">
122+
<div className="sticky top-0 z-10 border-border border-b bg-muted/20 px-3 py-2">
123+
<div className="flex items-center gap-2">
124+
<span className="text-primary text-xs"></span>
125+
<span className="font-mono font-semibold text-xs">
126+
[TWEET_{String(index + 1).padStart(3, "0")}]
127+
</span>
128+
</div>
129+
</div>
130+
<div className="w-full min-w-0 overflow-hidden">
131+
<div style={{ width: "100%", minWidth: 0, maxWidth: "100%" }}>
132+
<Tweet id={tweetId} />
133+
</div>
134+
</div>
135+
</div>
136+
</motion.div>
137+
);
138+
95139
return (
96-
<div className="mb-12">
140+
<div className="mb-12 w-full max-w-full overflow-hidden px-4">
97141
<div className="mb-6 flex flex-wrap items-center justify-between gap-2 sm:flex-nowrap">
98142
<div className="flex items-center gap-2">
99143
<Terminal className="h-5 w-5 text-primary" />
@@ -122,114 +166,74 @@ export default function Testimonials() {
122166
</div>
123167
</div>
124168

125-
<motion.div
126-
className="flex flex-col gap-4 sm:flex-row"
127-
variants={containerVariants}
128-
initial="hidden"
129-
animate="visible"
130-
>
169+
<div className="block sm:hidden">
131170
<motion.div
132-
className="flex flex-1 flex-col gap-4"
133-
variants={columnVariants}
171+
className="flex flex-col gap-4"
172+
variants={containerVariants}
173+
initial="hidden"
174+
animate="visible"
134175
>
135-
{columns[0]?.map((tweetId, tweetIndex) => {
136-
const globalIndex = 0 + tweetIndex * 3;
137-
return (
138-
<motion.div
139-
key={tweetId}
140-
className="terminal-block-hover overflow-hidden rounded border border-border bg-background"
141-
initial={{ opacity: 0, y: 20, scale: 0.95 }}
142-
animate={{ opacity: 1, y: 0, scale: 1 }}
143-
transition={{
144-
delay: tweetIndex * 0.05,
145-
duration: 0.4,
146-
ease: "easeOut",
147-
}}
148-
>
149-
<div className="sticky top-0 z-10 border-border border-b bg-muted/20 px-3 py-2">
150-
<div className="flex items-center gap-2">
151-
<span className="text-primary text-xs"></span>
152-
<span className="font-mono font-semibold text-xs">
153-
[TWEET_{String(globalIndex + 1).padStart(3, "0")}]
154-
</span>
155-
</div>
156-
</div>
157-
<div className="p-0">
158-
<Tweet id={tweetId} />
159-
</div>
160-
</motion.div>
161-
);
162-
})}
176+
{TWEET_IDS.map((tweetId, index) => (
177+
<TweetCard key={tweetId} tweetId={tweetId} index={index} />
178+
))}
163179
</motion.div>
180+
</div>
164181

182+
<div className="hidden sm:block lg:hidden">
165183
<motion.div
166-
className="flex flex-1 flex-col gap-4"
167-
variants={columnVariants}
184+
className="grid grid-cols-2 gap-4"
185+
variants={containerVariants}
186+
initial="hidden"
187+
animate="visible"
168188
>
169-
{columns[1]?.map((tweetId, tweetIndex) => {
170-
const globalIndex = 1 + tweetIndex * 3;
171-
return (
172-
<motion.div
173-
key={tweetId}
174-
className="terminal-block-hover overflow-hidden rounded border border-border bg-background"
175-
initial={{ opacity: 0, y: 20, scale: 0.95 }}
176-
animate={{ opacity: 1, y: 0, scale: 1 }}
177-
transition={{
178-
delay: tweetIndex * 0.05,
179-
duration: 0.4,
180-
ease: "easeOut",
181-
}}
182-
>
183-
<div className="sticky top-0 z-10 border-border border-b bg-muted/20 px-3 py-2">
184-
<div className="flex items-center gap-2">
185-
<span className="text-primary text-xs"></span>
186-
<span className="font-mono font-semibold text-xs">
187-
[TWEET_{String(globalIndex + 1).padStart(3, "0")}]
188-
</span>
189-
</div>
190-
</div>
191-
<div className="p-0">
192-
<Tweet id={tweetId} />
193-
</div>
194-
</motion.div>
195-
);
196-
})}
189+
{getResponsiveColumns(2).map((column, colIndex) => (
190+
<motion.div
191+
key={column.join("-")}
192+
className="flex min-w-0 flex-col gap-4"
193+
variants={columnVariants}
194+
>
195+
{column.map((tweetId, tweetIndex) => {
196+
const globalIndex = colIndex + tweetIndex * 2;
197+
return (
198+
<TweetCard
199+
key={tweetId}
200+
tweetId={tweetId}
201+
index={globalIndex}
202+
/>
203+
);
204+
})}
205+
</motion.div>
206+
))}
197207
</motion.div>
208+
</div>
198209

210+
<div className="hidden lg:block">
199211
<motion.div
200-
className="flex flex-1 flex-col gap-4"
201-
variants={columnVariants}
212+
className="grid grid-cols-3 gap-4"
213+
variants={containerVariants}
214+
initial="hidden"
215+
animate="visible"
202216
>
203-
{columns[2]?.map((tweetId, tweetIndex) => {
204-
const globalIndex = 2 + tweetIndex * 3;
205-
return (
206-
<motion.div
207-
key={tweetId}
208-
className="terminal-block-hover overflow-hidden rounded border border-border bg-background"
209-
initial={{ opacity: 0, y: 20, scale: 0.95 }}
210-
animate={{ opacity: 1, y: 0, scale: 1 }}
211-
transition={{
212-
delay: tweetIndex * 0.05,
213-
duration: 0.4,
214-
ease: "easeOut",
215-
}}
216-
>
217-
<div className="sticky top-0 z-10 border-border border-b bg-muted/20 px-3 py-2">
218-
<div className="flex items-center gap-2">
219-
<span className="text-primary text-xs"></span>
220-
<span className="font-mono font-semibold text-xs">
221-
[TWEET_{String(globalIndex + 1).padStart(3, "0")}]
222-
</span>
223-
</div>
224-
</div>
225-
<div className="p-0">
226-
<Tweet id={tweetId} />
227-
</div>
228-
</motion.div>
229-
);
230-
})}
217+
{getResponsiveColumns(3).map((column, colIndex) => (
218+
<motion.div
219+
key={column.join("-")}
220+
className="flex min-w-0 flex-col gap-4"
221+
variants={columnVariants}
222+
>
223+
{column.map((tweetId, tweetIndex) => {
224+
const globalIndex = colIndex + tweetIndex * 3;
225+
return (
226+
<TweetCard
227+
key={tweetId}
228+
tweetId={tweetId}
229+
index={globalIndex}
230+
/>
231+
);
232+
})}
233+
</motion.div>
234+
))}
231235
</motion.div>
232-
</motion.div>
236+
</div>
233237
</div>
234238
);
235239
}

apps/web/src/app/global.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@
1212
.react-tweet-theme {
1313
--tweet-container-margin: 0 !important;
1414
@apply !bg-background !border-none !h-full !border-transparent !w-full;
15+
max-width: 100% !important;
16+
min-width: 0 !important;
17+
}
18+
19+
.react-tweet-theme > * {
20+
max-width: 100% !important;
21+
width: 100% !important;
22+
min-width: 0 !important;
23+
}
24+
25+
.react-tweet-theme img,
26+
.react-tweet-theme video {
27+
max-width: 100% !important;
28+
height: auto !important;
29+
}
30+
31+
.react-tweet-theme * {
32+
word-wrap: break-word !important;
33+
word-break: break-word !important;
34+
overflow-wrap: break-word !important;
1535
}
1636

1737
.shiny-text {

0 commit comments

Comments
 (0)