Skip to content

Commit c5b16b4

Browse files
committed
feat: add questions
1 parent 4bba15f commit c5b16b4

File tree

7 files changed

+134
-31
lines changed

7 files changed

+134
-31
lines changed

src/components/Carousel.astro

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ import Sprite from "./Sprite.astro";
6565
.carousel-button {
6666
position: absolute;
6767
top: 50%;
68-
z-index: 10;
68+
z-index: 5;
6969
transform: translateY(-50%);
7070
background: transparent;
7171
border: none;
@@ -80,15 +80,15 @@ import Sprite from "./Sprite.astro";
8080
}
8181

8282
&.prev {
83-
left: var(--size-page-padding);
83+
left: 0;
8484

8585
svg {
8686
rotate: 0.25turn;
8787
}
8888
}
8989

9090
&.next {
91-
right: var(--size-page-padding);
91+
right: 0;
9292

9393
svg {
9494
rotate: 0.75turn;
@@ -104,35 +104,37 @@ import Sprite from "./Sprite.astro";
104104
import ClassNames from "embla-carousel-class-names";
105105

106106
function register() {
107-
const embla = document.querySelector(".carousel") as HTMLElement;
108-
if (!embla) throw new Error("Embla node not found");
109-
110-
const emblaViewport = embla.querySelector(".carousel-viewport") as HTMLElement;
111-
const options: EmblaOptionsType = { loop: true };
112-
const plugins = [Autoplay({ delay: 10000 }), ClassNames()];
113-
const emblaApi = EmblaCarousel(emblaViewport, options, plugins);
114-
115-
const updateActiveOverlay = () => {
116-
const slide = emblaApi.selectedScrollSnap();
117-
const overlay = embla.querySelector(`[data-slide-id="${slide}"]`) as HTMLElement;
118-
overlay?.classList.add("active");
119-
const overlays = embla.querySelectorAll(".carousel-overlay [data-slide-id]") as NodeListOf<HTMLElement>;
120-
overlays.forEach((o) => {
121-
if (o !== overlay) o.classList.remove("active");
122-
});
123-
};
124-
125-
if (embla.querySelector(".carousel-overlay")) {
126-
updateActiveOverlay();
127-
emblaApi.on("select", () => {
107+
const emblas = document.querySelectorAll(".carousel") as NodeListOf<HTMLElement>;
108+
if (!emblas) throw new Error("No Embla node not found");
109+
110+
emblas.forEach((embla) => {
111+
const emblaViewport = embla.querySelector(".carousel-viewport") as HTMLElement;
112+
const options: EmblaOptionsType = { loop: true };
113+
const plugins = [Autoplay({ delay: 10000 }), ClassNames()];
114+
const emblaApi = EmblaCarousel(emblaViewport, options, plugins);
115+
116+
const updateActiveOverlay = () => {
117+
const slide = emblaApi.selectedScrollSnap();
118+
const overlay = embla.querySelector(`[data-slide-id="${slide}"]`) as HTMLElement;
119+
overlay?.classList.add("active");
120+
const overlays = embla.querySelectorAll(".carousel-overlay [data-slide-id]") as NodeListOf<HTMLElement>;
121+
overlays.forEach((o) => {
122+
if (o !== overlay) o.classList.remove("active");
123+
});
124+
};
125+
126+
if (embla.querySelector(".carousel-overlay")) {
128127
updateActiveOverlay();
129-
});
130-
}
128+
emblaApi.on("select", () => {
129+
updateActiveOverlay();
130+
});
131+
}
131132

132-
const prevButton = embla.querySelector(".carousel-button.prev") as HTMLElement;
133-
const nextButton = embla.querySelector(".carousel-button.next") as HTMLElement;
134-
prevButton.addEventListener("click", () => emblaApi.scrollPrev(), false);
135-
nextButton.addEventListener("click", () => emblaApi.scrollNext(), false);
133+
const prevButton = embla.querySelector(".carousel-button.prev") as HTMLElement;
134+
const nextButton = embla.querySelector(".carousel-button.next") as HTMLElement;
135+
prevButton.addEventListener("click", () => emblaApi.scrollPrev(), false);
136+
nextButton.addEventListener("click", () => emblaApi.scrollNext(), false);
137+
});
136138
}
137139

138140
register();

src/content.config.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,28 @@ const referenceProjectsCollection = defineCollection({
7575
),
7676
});
7777

78+
const questionsCollection = defineCollection({
79+
loader: i18nContentLoader({ pattern: "**/[^_]*.yaml", base: "./src/content/questions" }),
80+
schema: extendI18nLoaderSchema(
81+
z.object({
82+
author: z.string(),
83+
items: localized(
84+
z.array(
85+
z.object({
86+
question: z.string(),
87+
answer: z.string(),
88+
}),
89+
),
90+
),
91+
}),
92+
),
93+
});
94+
7895
export const collections = {
7996
navigation: navigationCollection,
8097
pages: pagesCollection,
8198
sections: sectionsCollection,
8299
referenceCompanies: referenceCompaniesCollection,
83100
referenceProjects: referenceProjectsCollection,
101+
questions: questionsCollection,
84102
};

src/content/questions/diego.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
author: Diego Steiner
2+
items:
3+
de:
4+
- question: Was ist der beste Editor und welches Erweiterung darf nicht fehlen?
5+
answer: Ich arbeite am effektivsten mit Visual Studio Code mit der Vim-Erweiterung.
6+
- question: Was braucht es, um einen guten Teamgeist aufzubauen?
7+
answer: Dafür braucht es zunächst mal ein tolles Team aus Personen, die sich gegenseitig respektieren und sich selbst in die Gemeinschaft einbringen wollen. Auf diesem Fundament entsteht ein guter Teamgeist, wenn man ein gemeinsames Ziel vor Augen hat.
8+
9+
en:
10+
- question: What is the best editor and which extension is a must-have?
11+
answer: I work most effectively with Visual Studio Code with the Vim extension.
12+
- question: What does it take to build a good team spirit?
13+
answer: First of all, it takes a great team of people who respect each other and want to contribute to the community. On this foundation, a good team spirit arises when you have a common goal in mind.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
author: Leonardo Olivo
2+
items:
3+
de:
4+
- question: Was ist die beste Programmiersprache?
5+
answer: Keine Antwort.
6+
- question: Ein Gadget, das an deinem Arbeitsplatz nicht fehlen darf?
7+
answer: Keine Antwort.
8+
en:
9+
- question: What is the best programming language?
10+
answer: No answer.
11+
- question: A gadget that must not be missing at your workplace?
12+
answer: No answer.

src/content/questions/robin.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
author: Robin Bühler
2+
items:
3+
de:
4+
- question: Was ist zurzeit das beste Javascript Framework?
5+
answer: Je nach vorhaben unterschiedlich! Mir gefällt Astro für die Entwicklung von statischen Webseiten sehr gut. Fürs Beschreiben von UI-Komponenten ist meiner Meinung nach React schwer zu schlagen.
6+
- question: Welches ist das beste Betriebssystem?
7+
answer: Ich mag auf Linux basierte Betriebssysteme sehr, insbesondere Arch Linux, weil diese Systeme es einem ermöglichen alles anzusehen und zu verändern, wie es einem gefällt.
8+
- question: Welche Werte sind wichtig für das funktionieren einer Firma?
9+
answer: Offenheit, Ehrlichkeit, ein gesundes Mass für die Einschätzung der eigenen Fähig- und Möglichkeiten, sowie das stete Lernen aus Fehlern und suchen nach Verbesserungen.
10+
en:
11+
- question: What is currently the best Javascript framework?
12+
answer: It depends on the project! I really like Astro for developing static websites. For describing UI components, in my opinion, React is hard to beat.
13+
- question: What is the best operating system?
14+
answer: I really like Linux-based operating systems, especially Arch Linux, because these systems allow you to view and modify everything as you like.
15+
- question: Which values are important for a company to function?
16+
answer: Openness, honesty, a healthy sense of one's own abilities and possibilities, as well as constantly learning from mistakes and seeking improvements.
Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,43 @@
1+
---
2+
import { currentLocale } from "astro-nanostores-i18n:runtime";
3+
import { getCollection } from "astro:content";
4+
import Carousel from "../../components/Carousel.astro";
5+
6+
const locale = currentLocale.get();
7+
const questionsCollection = await getCollection("questions", (entry) => entry.data.locale === locale);
8+
const questions = questionsCollection.flatMap((q) => {
9+
if (Array.isArray(q.data.items)) {
10+
return q.data.items.map((item) => ({ ...item, author: q.data.author }));
11+
}
12+
return [];
13+
});
14+
questions.sort(() => Math.random() - 0.5);
15+
---
16+
117
<section>
2-
<slot />
18+
<Carousel>
19+
{
20+
questions.map((q) => (
21+
<div>
22+
<h3>{q.question}</h3>
23+
<p>{q.answer}</p>
24+
<p>
25+
<em>- {q.author}</em>
26+
</p>
27+
</div>
28+
))
29+
}
30+
</Carousel>
331
</section>
32+
433
<style>
534
section {
635
background-color: var(--color-background);
736
padding: 8rem var(--size-page-padding);
37+
user-select: none;
38+
39+
.carousel .carousel-viewport {
40+
margin: 0 var(--size-gutter-huge);
41+
}
842
}
943
</style>

src/layouts/sections/SpotlightSection.astro

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ import Carousel from "../../components/Carousel.astro";
1818
margin-inline-end: calc(var(--size-page-padding) + 7rem);
1919
}
2020

21+
.prev {
22+
left: var(--size-page-padding);
23+
}
24+
25+
.next {
26+
right: var(--size-page-padding);
27+
}
28+
2129
.active {
2230
display: flex;
2331
flex-direction: column;

0 commit comments

Comments
 (0)