Skip to content

Commit 90bf6b8

Browse files
committed
feat: add open source repository link to Attribution component
1 parent b148ab2 commit 90bf6b8

3 files changed

Lines changed: 108 additions & 2 deletions

File tree

src/components/Attribution.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,22 @@ const Attribution: React.FC = () => {
4949
<FaLinkedin />
5050
</a>
5151
</div>
52+
53+
<div className="repository-section">
54+
<div className="repository-text">
55+
Open Source Project
56+
</div>
57+
<a
58+
href="https://github.com/DeDuckProject/epp-demo"
59+
target="_blank"
60+
rel="noopener noreferrer"
61+
aria-label="View source code on GitHub"
62+
className="repository-link"
63+
>
64+
<FaGithub />
65+
<span>View on GitHub</span>
66+
</a>
67+
</div>
5268
</div>
5369
);
5470
};

src/index.css

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,45 @@ input:focus {
318318
background-color: rgba(59, 130, 246, 0.1);
319319
}
320320

321+
/* Repository section styles */
322+
.repository-section {
323+
margin-top: 0.75rem;
324+
padding-top: 0.75rem;
325+
border-top: 1px solid var(--soft-gray);
326+
}
327+
328+
.repository-text {
329+
font-weight: 500;
330+
line-height: 1.2;
331+
margin-bottom: 0.5rem;
332+
color: var(--secondary-color);
333+
font-size: 0.75rem;
334+
}
335+
336+
.repository-link {
337+
display: flex;
338+
align-items: center;
339+
justify-content: center;
340+
gap: 0.25rem;
341+
color: var(--primary-color);
342+
text-decoration: none;
343+
font-size: 0.75rem;
344+
font-weight: 500;
345+
padding: 0.25rem 0.5rem;
346+
border-radius: 6px;
347+
transition: all 0.2s ease;
348+
}
349+
350+
.repository-link:hover {
351+
color: #2563eb;
352+
background-color: rgba(59, 130, 246, 0.1);
353+
transform: translateY(-1px);
354+
}
355+
356+
.repository-link svg {
357+
font-size: 0.875rem;
358+
}
359+
321360
@media (max-width: 768px) {
322361
.attribution-container {
323362
bottom: 1rem;
@@ -335,6 +374,25 @@ input:focus {
335374
height: 1.25rem;
336375
font-size: 0.9rem;
337376
}
377+
378+
.repository-section {
379+
margin-top: 0.5rem;
380+
padding-top: 0.5rem;
381+
}
382+
383+
.repository-text {
384+
font-size: 0.7rem;
385+
}
386+
387+
.repository-link {
388+
font-size: 0.7rem;
389+
gap: 0.2rem;
390+
padding: 0.2rem 0.4rem;
391+
}
392+
393+
.repository-link svg {
394+
font-size: 0.8rem;
395+
}
338396
}
339397

340398
@media (prefers-color-scheme: light) {

tests/components/Attribution.test.tsx

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,30 @@ describe('Attribution Component', () => {
5353
expect(linksContainer).toHaveClass('attribution-links');
5454
expect(firstLink).toHaveClass('attribution-link');
5555
});
56+
57+
it('should display the repository section', () => {
58+
render(<Attribution />);
59+
60+
expect(screen.getByText('Open Source Project')).toBeInTheDocument();
61+
expect(screen.getByText('View on GitHub')).toBeInTheDocument();
62+
63+
const repoLink = screen.getByLabelText('View source code on GitHub');
64+
expect(repoLink).toBeInTheDocument();
65+
expect(repoLink).toHaveAttribute('href', 'https://github.com/DeDuckProject/epp-demo');
66+
expect(repoLink).toHaveClass('repository-link');
67+
});
68+
69+
it('should style the repository section correctly', () => {
70+
render(<Attribution />);
71+
72+
const repoSection = screen.getByText('Open Source Project').closest('.repository-section');
73+
const repoText = screen.getByText('Open Source Project');
74+
const repoLink = screen.getByLabelText('View source code on GitHub');
75+
76+
expect(repoSection).toHaveClass('repository-section');
77+
expect(repoText).toHaveClass('repository-text');
78+
expect(repoLink).toHaveClass('repository-link');
79+
});
5680
});
5781

5882
describe('when users interact with the attribution', () => {
@@ -74,6 +98,7 @@ describe('Attribution Component', () => {
7498
expect(screen.getByLabelText('LinkedIn profile')).toBeInTheDocument();
7599
expect(screen.getByLabelText('X (Twitter) profile')).toBeInTheDocument();
76100
expect(screen.getByLabelText('Bluesky profile')).toBeInTheDocument();
101+
expect(screen.getByLabelText('View source code on GitHub')).toBeInTheDocument();
77102
});
78103
});
79104

@@ -90,13 +115,20 @@ describe('Attribution Component', () => {
90115

91116
// The story continues: They want to connect with the creator
92117
const socialLinks = screen.getAllByRole('link');
93-
expect(socialLinks).toHaveLength(4);
118+
expect(socialLinks).toHaveLength(5); // Updated to include repository link
94119

95-
// The story concludes: They can easily access the creator's profiles
120+
// The story concludes: They can easily access the creator's profiles and the source code
96121
socialLinks.forEach(link => {
97122
expect(link).toBeVisible();
98123
expect(link.getAttribute('href')).toMatch(/^https:\/\//);
99124
});
125+
126+
// And they can find the open source repository
127+
const repoText = screen.getByText('Open Source Project');
128+
const repoLink = screen.getByLabelText('View source code on GitHub');
129+
expect(repoText).toBeVisible();
130+
expect(repoLink).toBeVisible();
131+
expect(repoLink.getAttribute('href')).toBe('https://github.com/DeDuckProject/epp-demo');
100132
});
101133
});
102134
});

0 commit comments

Comments
 (0)