Create testimonial component + testimonials section (#53)

This commit is contained in:
Szymon Kin 2022-10-23 16:47:56 +02:00 committed by GitHub
parent af323d1642
commit 1a5e537750
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 126 additions and 3 deletions

View file

@ -0,0 +1 @@
<div class="w-full h-px bg-gray-200"></div>

View file

@ -1 +1 @@
<div class="p-8 bg-white rounded-2xl shadow-md"><slot /></div> <div class="p-8 bg-white rounded-2xl shadow-md flex flex-col gap-6"><slot /></div>

View file

@ -0,0 +1,37 @@
---
import { Image } from '@astrojs/image/components';
import IconButton from '@/atoms/icon-button.astro';
import Typography from '@/atoms/typography.astro';
import type { Testimonial } from '@/types/testimonials-section';
export interface Props extends astroHTML.JSX.HTMLAttributes {
testimonial: Testimonial;
}
const {
testimonial: { author, content, image, relation, socials },
} = Astro.props;
---
<div class:list={['w-full', 'px-4', 'py-8', 'flex', 'flex-col', 'gap-4']}>
<div class:list={['flex', 'justify-between']}>
<div class:list={['flex', 'gap-4', 'flex-col', 'sm:flex-row']}>
<Image src={image} alt={author} format="webp" class:list={['w-14', 'h-14', 'rounded-lg']} />
<div>
<Typography variant="item-title">{author}</Typography>
<Typography variant="item-subtitle">{relation}</Typography>
</div>
</div>
{
socials && (
<div class:list={['flex', 'gap-3']}>
{socials.map(({ icon, url }) => (
<IconButton icon={icon} href={url} target="_blank" size="small" />
))}
</div>
)
}
</div>
<Typography variant="paragraph">{content}</Typography>
</div>

View file

@ -1,8 +1,28 @@
--- ---
import Divider from '@/atoms/divider.astro';
import SectionCard from '@/atoms/section-card.astro'; import SectionCard from '@/atoms/section-card.astro';
import Typography from '@/atoms/typography.astro';
import Testimonial from '@/organisms/testimonial.astro';
import type { TestimonialsSection } from '@/types/testimonials-section'; import type { TestimonialsSection } from '@/types/testimonials-section';
export interface Props extends TestimonialsSection {} export interface Props extends TestimonialsSection {}
const {
testimonials,
config: { title },
} = Astro.props;
--- ---
<SectionCard>Testimonials section</SectionCard> <SectionCard>
<Typography variant="section-title">{title}</Typography>
<div class:list={['flex', 'flex-col']}>
{
testimonials.map((testimonial, index) => (
<>
<Testimonial testimonial={testimonial} />
{index !== testimonials.length - 1 && <Divider />}
</>
))
}
</div>
</SectionCard>

View file

@ -0,0 +1,20 @@
---
import Testimonial from '@/organisms/testimonial.astro';
import type { Testimonial as TestimonialData } from '@/types/testimonials-section';
const testimonial: TestimonialData = {
author: 'Howard Stewart',
relation: 'We work together as front-end developers at Google',
content:
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed euismod, nisl vel tincidunt aliquam, nunc nisl aliquet nisl, eget aliquet nunc nisl euismod nisl. Sed euismod, nisl vel tincidunt aliquam, nunc nisl aliquet nisl, eget aliquet nunc nisl euismod nisl.',
image: import('@/assets/testimonials/testimonial-1.jpeg'),
socials: [
{ name: 'GitHub', icon: 'fa6-brands:github', url: '#' },
{ name: 'LinkedIn', icon: 'fa6-brands:linkedin-in', url: '#' },
],
};
---
<div class:list={['flex', 'flex-col', 'gap-2', 'max-w-[896px]']}>
<Testimonial testimonial={testimonial} />
</div>

View file

@ -0,0 +1,45 @@
---
import TestimonialsSection from '@/sections/testimonials-section.astro';
import type { Testimonial } from '@/types/testimonials-section';
const testimonials: Testimonial[] = [
{
image: import('@/assets/testimonials/testimonial-1.jpeg'),
author: 'Howard Stewart',
relation: 'We work together as front-end developers at Google',
content:
'In nec mattis sem. Morbi purus lorem, euismod ac varius at, aliquet vitae augue. Pellentesque ut facilisis felis. In sed dui blandit, aliquet odio eu, elementum leo. In facilisis dapibus tortor ac volutpat. Cras cursus nec odio maximus elementum.',
socials: [
{ name: 'GitHub', icon: 'fa6-brands:github', url: '#' },
{ name: 'LinkedIn', icon: 'fa6-brands:linkedin-in', url: '#' },
],
},
{
image: import('@/assets/testimonials/testimonial-2.jpeg'),
author: 'Jean Richards',
relation: 'My project manager at GitLab',
content:
'Praesent nec congue elit. Vestibulum lobortis congue ipsum, a gravida mi tempus ac. Mauris aliquet purus nibh, vel varius turpis tempus non. Nullam eget ultricies orci. Quisque nulla ante, auctor eget varius ac, imperdiet nec magna.',
socials: [{ name: 'LinkedIn', icon: 'fa6-brands:linkedin-in', url: '#' }],
},
{
image: import('@/assets/testimonials/testimonial-3.jpeg'),
author: 'Jason Fisher',
relation: 'My customer for sidewing.com website',
content:
'Mauris tincidunt at purus vehicula porta. Mauris eget mollis turpis. Sed iaculis rutrum pharetra. Vivamus risus quam, suscipit et semper ut, aliquet ut tellus. Donec quis auctor nunc.',
socials: [
{ name: 'GitHub', icon: 'fa6-brands:github', url: '#' },
{ name: 'Website', icon: 'fa6-solid:globe', url: '#' },
],
},
];
---
<body class="flex justify-center bg-gray-50">
<div class="flex gap-8 w-full max-w-6xl px-2 py-3 sm:px-8 sm:py-12 lg:px-16 lg:py-20 lg:ml-22">
<main class="w-full space-y-4 sm:space-y-6 lg:space-y-8">
<TestimonialsSection testimonials={testimonials} config={{ title: 'Testimonials', icon: 'fa6-solid:comment' }} />
</main>
</div>
</body>

View file

@ -1,6 +1,6 @@
import type { LocalImage, SectionConfig, Social } from './common'; import type { LocalImage, SectionConfig, Social } from './common';
interface Testimonial { export interface Testimonial {
image: LocalImage; image: LocalImage;
author: string; author: string;
relation: string; relation: string;