Skip to content

Commit b42c95d

Browse files
authored
Merge pull request #48 from binhtran432k/feature/review
feat: enhance review
2 parents 13fbee7 + a8bf8b9 commit b42c95d

File tree

7 files changed

+145
-2
lines changed

7 files changed

+145
-2
lines changed

bun.lockb

328 Bytes
Binary file not shown.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"vite-tsconfig-paths": "^4.2.1"
4949
},
5050
"dependencies": {
51-
"clsx": "^2.1.0"
51+
"clsx": "^2.1.0",
52+
"swiper": "^11.1.9"
5253
}
5354
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
import {
2+
component$,
3+
useSignal,
4+
useStyles$,
5+
useVisibleTask$,
6+
} from "@builder.io/qwik";
7+
import Review, { type ReviewData } from "./review";
8+
import Swiper from "swiper";
9+
import { Pagination, Navigation } from "swiper/modules";
10+
11+
const reviews: ReviewData[] = [];
12+
import swiperStyles from "swiper/swiper-bundle.css?inline";
13+
14+
export default component$(() => {
15+
if (reviews.length === 0) {
16+
return <></>;
17+
}
18+
useStyles$(swiperStyles);
19+
useStyles$(`
20+
.swiper-slide {
21+
filter: blur(2px) !important;
22+
transform: scale(0.8) !important;
23+
transition: all 0.2s;
24+
}
25+
.swiper-slide-active {
26+
filter: blur(0) !important;
27+
transform: scale(1) !important;
28+
}
29+
.swiper-pagination {
30+
position: static;
31+
}
32+
.swiper-pagination-bullet {
33+
width: 2.5rem;
34+
height: 0.25rem;
35+
border-radius: 50px;
36+
background: #fff;
37+
}
38+
.swiper-pagination-bullet-active {
39+
width: 4rem;
40+
}
41+
`);
42+
43+
const swiperRef = useSignal<HTMLElement>();
44+
const nextRef = useSignal<HTMLElement>();
45+
const prevRef = useSignal<HTMLElement>();
46+
const paginationRef = useSignal<HTMLElement>();
47+
48+
// eslint-disable-next-line qwik/no-use-visible-task
49+
useVisibleTask$(() => {
50+
new Swiper(swiperRef.value!, {
51+
spaceBetween: 30,
52+
pagination: {
53+
el: paginationRef.value,
54+
type: "bullets",
55+
clickable: true,
56+
},
57+
navigation: {
58+
prevEl: prevRef.value,
59+
nextEl: nextRef.value,
60+
},
61+
slidesPerView: 1,
62+
breakpoints: {
63+
768: { slidesPerView: 2 },
64+
1280: { slidesPerView: 3 },
65+
},
66+
modules: [Pagination, Navigation],
67+
centeredSlides: true,
68+
slideToClickedSlide: true,
69+
});
70+
});
71+
72+
return (
73+
<section
74+
class="review-slide swiper container m-auto my-4 min-h-[400px] select-none"
75+
ref={swiperRef}
76+
>
77+
<div class="swiper-wrapper">
78+
{reviews.map((review) => (
79+
<div key={review.name} class="swiper-slide">
80+
<Review review={review} />
81+
</div>
82+
))}
83+
</div>
84+
<div class="mt-8 flex justify-center">
85+
<div class="flex gap-2">
86+
<button
87+
class="group rounded-lg border-[1px] px-4 py-2 disabled:opacity-50"
88+
ref={prevRef}
89+
>
90+
<div class="h-3 w-3 translate-x-1/4 rotate-45 border-b-2 border-s-2 border-light" />
91+
</button>
92+
<button
93+
class="group rounded-lg border-[1px] px-4 py-2 disabled:opacity-50"
94+
ref={nextRef}
95+
>
96+
<div class=" h-3 w-3 -translate-x-1/4 rotate-45 border-e-2 border-t-2 border-light" />
97+
</button>
98+
</div>
99+
<div
100+
class="swiper-pagination hidden md:block"
101+
ref={paginationRef}
102+
></div>
103+
</div>
104+
</section>
105+
);
106+
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { component$ } from "@builder.io/qwik";
2+
3+
export interface ReviewData {
4+
content: string;
5+
name: string;
6+
job: string;
7+
img: string;
8+
}
9+
10+
export default component$(({ review }: { review: ReviewData }) => {
11+
return (
12+
<section class="review flex gap-1 px-2">
13+
<div class="font-serif text-6xl text-secondary">&ldquo;</div>
14+
<div class="flex flex-col border-t-[1px] border-t-light pt-6">
15+
<div class="flex items-start gap-2">
16+
<div class="review__content first-letter:font-serif first-letter:text-3xl first-letter:text-secondary">
17+
{review.content}
18+
</div>
19+
<img
20+
class="review__img rounded-[35px] object-cover"
21+
src={review.img}
22+
width={70}
23+
height={100}
24+
/>
25+
</div>
26+
<div class="ml-8 mt-4 font-serif text-sm opacity-80">
27+
<div class="review__name">{review.name}</div>
28+
<div class="review__job">{review.job}</div>
29+
</div>
30+
</div>
31+
</section>
32+
);
33+
});

src/routes/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { component$ } from "@builder.io/qwik";
22
import type { DocumentHead } from "@builder.io/qwik-city";
33
import GhStats from "~/components/gh-stats/gh-stats";
44
import Landing from "~/components/landing/landing";
5+
import ReviewSlide from "~/components/review-slide/review-slide";
56
import Skill from "~/components/skill/skill";
67

78
export default component$(() => {
@@ -10,6 +11,7 @@ export default component$(() => {
1011
<Landing />
1112
<Skill />
1213
<GhStats />
14+
<ReviewSlide />
1315
</>
1416
);
1517
});

tailwind.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export default {
1313
warning: colors.yellow["300"],
1414
info: colors.cyan["500"],
1515
light: colors.gray["50"],
16+
gray: colors.gray["500"],
1617
dark: colors.gray["950"],
1718
},
1819
extend: {

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@
2222
}
2323
},
2424
"files": ["./.eslintrc.cjs"],
25-
"include": ["src", "./*.d.ts", "./*.config.ts"]
25+
"include": ["src", "./*.d.ts", "./*.config.ts", "./*.config.js"]
2626
}

0 commit comments

Comments
 (0)