Skip to content

Commit 1d26b96

Browse files
authored
Merge pull request #225 from ELIXIR-NO/feat/phase-1-improvements
feat: phase 1 improvements
2 parents 4bfcbf3 + ea61f00 commit 1d26b96

File tree

197 files changed

+1023
-408
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

197 files changed

+1023
-408
lines changed

alter.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
# Check if directory argument is provided
4+
if [ -z "$1" ]; then
5+
echo "Usage: $0 <directory>"
6+
exit 1
7+
fi
8+
9+
DIR="$1"
10+
11+
# Check if directory exists
12+
if [ ! -d "$DIR" ]; then
13+
echo "Directory does not exist: $DIR"
14+
exit 1
15+
fi
16+
17+
# Lines to add
18+
prepend="layout: \"../../layouts/page.astro\"
19+
variant: \"article\""
20+
21+
# Loop through all .mdx files in the directory
22+
for file in "$DIR"/*.mdx; do
23+
# Skip if no files found
24+
[ -e "$file" ] || continue
25+
26+
# Check if file contains front matter
27+
if grep -q '^---' "$file"; then
28+
# Check if lines are already present
29+
if ! grep -q 'layout: "../../layouts/page.astro"' "$file"; then
30+
# Insert lines after first ---
31+
awk -v prepend="$prepend" 'NR==1{print; print prepend; next}1' "$file" > tmpfile && mv tmpfile "$file"
32+
echo "Updated $file"
33+
else
34+
echo "Already contains layout/variant: $file"
35+
fi
36+
else
37+
echo "No front matter found in $file, skipping..."
38+
fi
39+
done
40+
3.22 MB
Loading

src/components/breadcrumbs.astro

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
interface Crumb {
3+
label: string;
4+
href?: string;
5+
}
6+
7+
interface Props {
8+
crumbs?: Crumb[];
9+
}
10+
11+
const { crumbs = [] } = Astro.props;
12+
13+
// Auto-generate from URL if not provided
14+
const autoCrumbs = crumbs.length === 0
15+
? Astro.url.pathname
16+
.split('/')
17+
.filter(Boolean)
18+
.map((segment, index, array) => ({
19+
label: segment
20+
.split('-')
21+
.map(w => w.charAt(0).toUpperCase() + w.slice(1))
22+
.join(' '),
23+
href: index < array.length - 1
24+
? '/' + array.slice(0, index + 1).join('/')
25+
: undefined
26+
}))
27+
: crumbs;
28+
29+
const allCrumbs = [{ label: 'Home', href: '/' }, ...autoCrumbs];
30+
---
31+
32+
<nav aria-label="Breadcrumb" class="mb-6">
33+
<ol class="flex items-center space-x-2 text-sm">
34+
{allCrumbs.map((crumb, index) => (
35+
<li class="flex items-center">
36+
{index > 0 && (
37+
<svg
38+
class="h-5 w-5 text-gray-400 mx-2"
39+
fill="currentColor"
40+
viewBox="0 0 20 20"
41+
aria-hidden="true"
42+
>
43+
<path d="M5.555 17.776l8-16 .894.448-8 16-.894-.448z" />
44+
</svg>
45+
)}
46+
{crumb.href ? (
47+
<a
48+
href={crumb.href}
49+
class="text-gray-600 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-200 transition-colors"
50+
>
51+
{crumb.label}
52+
</a>
53+
) : (
54+
<span
55+
class="font-semibold text-gray-900 dark:text-white"
56+
aria-current="page"
57+
>
58+
{crumb.label}
59+
</span>
60+
)}
61+
</li>
62+
))}
63+
</ol>
64+
</nav>

src/components/card.v2.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ export default function CardV2(props: CardTypeProps) {
1414
<li className="shadow-xl bg-light-surface dark:bg-dark-surface rounded-lg overflow-clip transition-all duration-300 hover:shadow-2xl hover:opacity-95">
1515
<a href={`${props.link}`} className="block">
1616
<div className="h-48 bg-white overflow-clip flex items-center justify-center">
17-
<img src={props?.cover ?? "/assets/og/default.jpg"} alt="Article Cover"
17+
<img src={props?.cover ?? "/assets/og/default.jpg"}
18+
alt={props.title || "Article cover image"}
19+
loading="lazy"
1820
className="w-auto h-auto"/>
1921
</div>
2022
<div className="flex px-6 pt-4 pb-6 flex-col gap-y-2">

src/components/command-palette.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export default function CommandPalette({ open, setOpen }) {
7272
autoFocus
7373
className="h-12 w-full border-0 bg-transparent pl-11 pr-4 text-gray-900 placeholder:text-gray-400 focus:ring-0 sm:text-sm"
7474
placeholder="Search..."
75+
aria-label="Search site content"
7576
onChange={debounce(handleSearch, debounceTime)}
7677
onBlur={() => setSearchTerm('')}
7778
/>

src/components/footer.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,18 @@ const ElixirBrand = () => {
2323
<div className="flex flex-col justify-between items-center lg:items-start gap-y-12">
2424
<a href="/" className="sm:order-1">
2525
<img
26-
alt="ELIXIR.NO Logo"
26+
alt="ELIXIR Norway Logo"
2727
src="/assets/logos/elixir-no-light.svg"
2828
className="hidden dark:block h-28 lg:h-36 w-auto"
29+
width="auto"
30+
height="144"
2931
/>
3032
<img
31-
alt="ELIXIR.NO Logo"
33+
alt="ELIXIR Norway Logo"
3234
src="/assets/logos/elixir-no-dark.svg"
3335
className="block dark:hidden h-24 w-auto"
36+
width="auto"
37+
height="96"
3438
/>
3539
</a>
3640
<div className="flex space-x-4 sm:order-2">
Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
---
2-
import React from "react";
2+
const {links} = Astro.props;
33
4-
const { links } = Astro.props;
4+
const hash = Astro.url.hash;
55
---
66

7-
<div class="overflow-hidden bg-slate-50 dark:bg-dark-surface shadow sm:rounded-md">
7+
<div class="overflow-hidden sm:rounded-md">
88
<ul role="list" class="divide-y divide-gray-200 dark:divide-gray-700">
9-
{links?.map((link) => {
10-
const pathname = new URL(Astro.request.url).pathname;
11-
const isActive = pathname === link.href;
12-
return (
13-
<li>
14-
<a href={link.href}
15-
class={`text-base block w-full h-full py-2 px-6 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition duration-150 ease-in-out ${isActive ? 'bg-blue-100 text-blue-700' : ''}`}>{link.text}</a>
16-
</li>
17-
)
18-
})}
9+
{links?.map((link) => (
10+
<li>
11+
<a
12+
href={link.href}
13+
class={`text-base block w-full h-full py-2 px-6 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition duration-150 ease-in-out focus:outline-none focus:ring-2 focus:ring-inset focus:ring-brand-primary`}
14+
aria-current={hash === link.href ? 'page' : undefined}
15+
>
16+
{link.text}
17+
</a>
18+
</li>
19+
))}
1920
</ul>
20-
</div>
21+
</div>

src/components/navigation.tsx

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,18 @@ export const Navigation = ({ pathname }) => {
5757
<a href="/" className="-m-1.5 p-1.5">
5858
<span className="sr-only">ELIXIR Norway</span>
5959
<img
60-
alt="ELIXIR.NO Logo"
60+
alt="ELIXIR Norway logo"
6161
src="/assets/logos/elixir-no-light.svg"
6262
className="hidden dark:block h-20 w-auto"
63+
width="auto"
64+
height="80"
6365
/>
6466
<img
65-
alt="ELIXIR.NO Logo"
67+
alt="ELIXIR Norway logo"
6668
src="/assets/logos/elixir-no-dark.svg"
6769
className="block dark:hidden h-20 w-auto"
70+
width="auto"
71+
height="80"
6872
/>
6973
</a>
7074
</div>
@@ -81,9 +85,12 @@ export const Navigation = ({ pathname }) => {
8185
</div>
8286
<div className="hidden lg:flex lg:gap-x-12">
8387
{navigation.map((item) => (
84-
<a key={item.name}
85-
href={item.href}
86-
className={`hover:text-brand-primary/75 text-lg font-semibold leading-6 ${pathname === item.href ? "text-brand-primary" : "text-slate-950 dark:text-slate-50"}`}>
88+
<a
89+
key={item.name}
90+
href={item.href}
91+
className={`hover:text-brand-primary/75 text-lg font-semibold leading-6 transition-colors focus:outline-none focus:ring-2 focus:ring-brand-primary focus:ring-offset-2 rounded ${pathname === item.href ? 'text-brand-primary' : 'text-gray-900 dark:text-white'}`}
92+
aria-current={pathname === item.href ? 'page' : undefined}
93+
>
8794
{item.name}
8895
</a>
8996
))}
@@ -107,9 +114,18 @@ export const Navigation = ({ pathname }) => {
107114
<a href="/" className="-m-1.5 p-1.5">
108115
<span className="sr-only">ELIXIR Norway</span>
109116
<img
110-
alt="ELIXIR.NO Logo"
117+
alt="ELIXIR Norway logo"
118+
src="/assets/logos/elixir-no-light.svg"
119+
className="hidden dark:block h-16 w-auto"
120+
width="auto"
121+
height="80"
122+
/>
123+
<img
124+
alt="ELIXIR Norway logo"
111125
src="/assets/logos/elixir-no-dark.svg"
112-
className="h-16 w-auto"
126+
className="block dark:hidden h-16 w-auto"
127+
width="auto"
128+
height="80"
113129
/>
114130
</a>
115131
<button
@@ -140,8 +156,12 @@ export const Navigation = ({ pathname }) => {
140156
))}
141157
</div>
142158
<div className="py-6">
143-
<button onClick={onSearchClick}>
144-
<IoSearch/>
159+
<button
160+
onClick={onSearchClick}
161+
className="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-brand-primary focus:ring-offset-2 transition-colors"
162+
aria-label="Open search"
163+
>
164+
<IoSearch className="h-6 w-6" aria-hidden="true" />
145165
</button>
146166
</div>
147167
</div>
@@ -154,26 +174,4 @@ export const Navigation = ({ pathname }) => {
154174

155175
};
156176

157-
export const ContextualHeader = ({ sections }) => {
158-
return (
159-
<nav
160-
className={`sticky top-0 z-40 bg-white dark:bg-basic-black shadow-lg animate__animated animate__fadeInDown ${sections?.length > 0 ? "" : "hidden"}`}>
161-
<div
162-
className="max-w-7xl mx-auto px-6 py-3 text-gray-900 text-sm">
163-
<div className="flex flex-wrap items-center justify-center divide-x divide-gray-500">
164-
{sections.map((section) => (
165-
<a
166-
key={section.id}
167-
href={`#${section.id}`}
168-
className="first:px-l-0 last:px-r-0 px-2 text-center hover:underline"
169-
>
170-
{section.name}
171-
</a>
172-
))}
173-
</div>
174-
</div>
175-
</nav>
176-
)
177-
};
178-
179177
export default Navigation;

src/components/seo-head.astro

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
---
2+
interface Props {
3+
title?: string;
4+
description?: string;
5+
image?: string;
6+
article?: boolean;
7+
publishedTime?: string;
8+
modifiedTime?: string;
9+
author?: string;
10+
tags?: string[];
11+
canonical?: string;
12+
}
13+
14+
const {
15+
title = "ELIXIR Norway - Life Science Data Infrastructure",
16+
description = "ELIXIR Norway provides services and infrastructure for life science data management, analysis, and sharing.",
17+
image = "/assets/og/default.jpg",
18+
article = false,
19+
publishedTime,
20+
modifiedTime,
21+
author,
22+
tags = [],
23+
canonical
24+
} = Astro.props;
25+
26+
const siteUrl = "https://elixir.no";
27+
const currentUrl = canonical || `${siteUrl}${Astro.url.pathname}`;
28+
const imageUrl = image.startsWith('http') ? image : `${siteUrl}${image}`;
29+
const fullTitle = title.includes("ELIXIR Norway") ? title : `${title} - ELIXIR Norway`;
30+
---
31+
32+
<!-- Primary Meta Tags -->
33+
<title>{fullTitle}</title>
34+
<meta name="title" content={fullTitle} />
35+
<meta name="description" content={description} />
36+
<link rel="canonical" href={currentUrl} />
37+
38+
<!-- Open Graph / Facebook -->
39+
<meta property="og:type" content={article ? "article" : "website"} />
40+
<meta property="og:url" content={currentUrl} />
41+
<meta property="og:title" content={fullTitle} />
42+
<meta property="og:description" content={description} />
43+
<meta property="og:image" content={imageUrl} />
44+
<meta property="og:site_name" content="ELIXIR Norway" />
45+
46+
{article && publishedTime && (
47+
<meta property="article:published_time" content={publishedTime} />
48+
)}
49+
{article && modifiedTime && (
50+
<meta property="article:modified_time" content={modifiedTime} />
51+
)}
52+
{article && author && (
53+
<meta property="article:author" content={author} />
54+
)}
55+
{tags.map(tag => (
56+
<meta property="article:tag" content={tag} />
57+
))}
58+
59+
<!-- Twitter -->
60+
<meta property="twitter:card" content="summary_large_image" />
61+
<meta property="twitter:url" content={currentUrl} />
62+
<meta property="twitter:title" content={fullTitle} />
63+
<meta property="twitter:description" content={description} />
64+
<meta property="twitter:image" content={imageUrl} />
65+
66+
<!-- Additional SEO -->
67+
<meta name="robots" content="index, follow" />
68+
<meta name="language" content="English" />

0 commit comments

Comments
 (0)