diff --git a/package-lock.json b/package-lock.json index 61e4442..c567ab5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,11 @@ "@astrojs/vue": "^5.1.1", "@tailwindcss/vite": "^4.1.11", "@vueuse/core": "^13.9.0", - "astro": "^5.14.1", + "astro": "^5.13.10", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "embla-carousel-autoplay": "^8.6.0", + "embla-carousel-vue": "^8.6.0", "lucide-vue-next": "^0.539.0", "reka-ui": "^2.5.0", "tailwind-merge": "^3.3.1", @@ -3675,9 +3677,9 @@ } }, "node_modules/astro": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/astro/-/astro-5.14.1.tgz", - "integrity": "sha512-gPa8NY7/lP8j8g81iy8UwANF3+aukKRWS68IlthZQNgykpg80ne6lbHOp6FErYycxQ1TUhgEfkXVDQZAoJx8Bg==", + "version": "5.13.10", + "resolved": "https://registry.npmjs.org/astro/-/astro-5.13.10.tgz", + "integrity": "sha512-PgIrIYvrR7fCoSPPt1sGlpoYK/FNil1BwKazND1DyaZC7SbWLi9hdIHM3ApdrL2SWK7oiADRPw7cTn80UyDWqA==", "license": "MIT", "dependencies": { "@astrojs/compiler": "^2.12.2", @@ -4623,6 +4625,43 @@ "integrity": "sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w==", "license": "ISC" }, + "node_modules/embla-carousel": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz", + "integrity": "sha512-SjWyZBHJPbqxHOzckOfo8lHisEaJWmwd23XppYFYVh10bU66/Pn5tkVkbkCMZVdbUE5eTCI2nD8OyIP4Z+uwkA==", + "license": "MIT" + }, + "node_modules/embla-carousel-autoplay": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-autoplay/-/embla-carousel-autoplay-8.6.0.tgz", + "integrity": "sha512-OBu5G3nwaSXkZCo1A6LTaFMZ8EpkYbwIaH+bPqdBnDGQ2fh4+NbzjXjs2SktoPNKCtflfVMc75njaDHOYXcrsA==", + "license": "MIT", + "peerDependencies": { + "embla-carousel": "8.6.0" + } + }, + "node_modules/embla-carousel-reactive-utils": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.6.0.tgz", + "integrity": "sha512-fMVUDUEx0/uIEDM0Mz3dHznDhfX+znCCDCeIophYb1QGVM7YThSWX+wz11zlYwWFOr74b4QLGg0hrGPJeG2s4A==", + "license": "MIT", + "peerDependencies": { + "embla-carousel": "8.6.0" + } + }, + "node_modules/embla-carousel-vue": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/embla-carousel-vue/-/embla-carousel-vue-8.6.0.tgz", + "integrity": "sha512-v8UO5UsyLocZnu/LbfQA7Dn2QHuZKurJY93VUmZYP//QRWoCWOsionmvLLAlibkET3pGPs7++03VhJKbWD7vhQ==", + "license": "MIT", + "dependencies": { + "embla-carousel": "8.6.0", + "embla-carousel-reactive-utils": "8.6.0" + }, + "peerDependencies": { + "vue": "^3.2.37" + } + }, "node_modules/emmet": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.11.tgz", diff --git a/package.json b/package.json index 00b270e..a770e18 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,11 @@ "@astrojs/vue": "^5.1.1", "@tailwindcss/vite": "^4.1.11", "@vueuse/core": "^13.9.0", - "astro": "^5.14.1", + "astro": "^5.13.10", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", + "embla-carousel-autoplay": "^8.6.0", + "embla-carousel-vue": "^8.6.0", "lucide-vue-next": "^0.539.0", "reka-ui": "^2.5.0", "tailwind-merge": "^3.3.1", diff --git a/src/assets/marketing.png b/src/assets/marketing.png new file mode 100644 index 0000000..42ceb66 Binary files /dev/null and b/src/assets/marketing.png differ diff --git a/src/assets/mentor.jpg b/src/assets/mentor.jpg new file mode 100644 index 0000000..d58b9fa Binary files /dev/null and b/src/assets/mentor.jpg differ diff --git a/src/assets/open-source.jpg b/src/assets/open-source.jpg new file mode 100644 index 0000000..0ac2947 Binary files /dev/null and b/src/assets/open-source.jpg differ diff --git a/src/components/CarouselTestimonials.vue b/src/components/CarouselTestimonials.vue new file mode 100644 index 0000000..731d123 --- /dev/null +++ b/src/components/CarouselTestimonials.vue @@ -0,0 +1,33 @@ + + + diff --git a/src/components/CarouselTimeline.astro b/src/components/CarouselTimeline.astro new file mode 100644 index 0000000..6f31c83 --- /dev/null +++ b/src/components/CarouselTimeline.astro @@ -0,0 +1,20 @@ +--- +import CarouselTimelineVue from "./CarouselTimeline.vue"; +import Mentor from "./Mentor.astro"; +import Communication from "./Communication.astro"; +import Developer from "./Developer.astro"; +--- + +
+ +
+ +
+
+ +
+
+ +
+
+
diff --git a/src/components/CarouselTimeline.vue b/src/components/CarouselTimeline.vue new file mode 100644 index 0000000..849d364 --- /dev/null +++ b/src/components/CarouselTimeline.vue @@ -0,0 +1,112 @@ + + + diff --git a/src/components/Communication.astro b/src/components/Communication.astro new file mode 100644 index 0000000..dcc0c81 --- /dev/null +++ b/src/components/Communication.astro @@ -0,0 +1,52 @@ +--- +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "./ui/card"; +import { Button } from "./ui/button"; +import { Image } from "astro:assets"; +import marketing from "src/assets/marketing.png"; +--- + + + +
+
+

+ O design e marketing são essenciais para o CoderDojo Braga, pois + permitem expandir a nossa atuação, dando-nos a conhecer a mais + pessoas, sejam novos guardiões e ninjas, ou mentores e voluntários. +

+

+ Junta-te à nossa equipa, e contribui para tornar este projeto nalgo + cada vez maior e melhor. +

+
+
+ Design e Marketing +
+
+
+ + + + + +
diff --git a/src/components/Developer.astro b/src/components/Developer.astro new file mode 100644 index 0000000..15e4dfa --- /dev/null +++ b/src/components/Developer.astro @@ -0,0 +1,48 @@ +--- +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "./ui/card"; +import { Button } from "./ui/button"; +import { Image } from "astro:assets"; +import openSource from "src/assets/open-source.jpg"; +--- + + + +
+
+

+ O código-fonte destas plataformas é público, o que significa que + qualquer pessoa pode ver e contribuir para as mesmas. +

+

+ Ao contribuires para as nossas plataformas, estás não só a ganhar + experiência profissional, como também a melhorar a qualidade do + trabalho que desenvolvemos. +

+
+
+ Plataforma Open Source +
+
+
+ + + + + + + + +
diff --git a/src/components/Header.astro b/src/components/Header.astro index 8e199a3..b494456 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -6,7 +6,7 @@ import AppSidebar from "./AppSidebar.vue"; const pages = { Equipa: "/team", - Recruitment: "/recruitment", + Recrutamento: "/recruitment", FAQs: "/faqs", }; --- diff --git a/src/components/Mentor.astro b/src/components/Mentor.astro new file mode 100644 index 0000000..975de63 --- /dev/null +++ b/src/components/Mentor.astro @@ -0,0 +1,50 @@ +--- +import { Button } from "./ui/button"; +import { + Card, + CardContent, + CardFooter, + CardHeader, + CardTitle, +} from "./ui/card"; +import { Image } from "astro:assets"; +import mentor from "src/assets/mentor.jpg"; +--- + + + +
+
+

+ Os Mentores são o coração do CoderDojo Braga. Sem eles, não há sessões + e não há ninjas a aprender a programar. +

+ +

+ Ao seres mentor, não só estás a ter um impacto positivo na vida dos + ninjas, como estás a desenvolver as tuas soft skills, + nomeadamente a forma como comunicas com os outros. +

+
+
+ Mentores do Dojo +
+
+
+ + + + + +
diff --git a/src/components/Page.astro b/src/components/Page.astro index a2943de..a2ded40 100644 --- a/src/components/Page.astro +++ b/src/components/Page.astro @@ -8,13 +8,13 @@ const { title, description } = Astro.props; ---
-
-

{title}

-
-
- +
+ + +

{title}

+ +
+

diff --git a/src/components/Testimonial.vue b/src/components/Testimonial.vue new file mode 100644 index 0000000..9d0063d --- /dev/null +++ b/src/components/Testimonial.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/components/Timeline.astro b/src/components/Timeline.astro new file mode 100644 index 0000000..c9d748e --- /dev/null +++ b/src/components/Timeline.astro @@ -0,0 +1,7 @@ +

+
    + +
+
diff --git a/src/components/TimelineItem.astro b/src/components/TimelineItem.astro new file mode 100644 index 0000000..155c99a --- /dev/null +++ b/src/components/TimelineItem.astro @@ -0,0 +1,28 @@ +--- +interface Props { + title: string; + svgPath: string; +} + +const { title, svgPath } = Astro.props as Props; +--- + +
  • + + + +

    {title}

    + +
  • diff --git a/src/components/ui/card/Card.vue b/src/components/ui/card/Card.vue new file mode 100644 index 0000000..e885e6e --- /dev/null +++ b/src/components/ui/card/Card.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/components/ui/card/CardAction.vue b/src/components/ui/card/CardAction.vue new file mode 100644 index 0000000..812885b --- /dev/null +++ b/src/components/ui/card/CardAction.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/card/CardContent.vue b/src/components/ui/card/CardContent.vue new file mode 100644 index 0000000..8381e57 --- /dev/null +++ b/src/components/ui/card/CardContent.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/card/CardDescription.vue b/src/components/ui/card/CardDescription.vue new file mode 100644 index 0000000..2c45bda --- /dev/null +++ b/src/components/ui/card/CardDescription.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/card/CardFooter.vue b/src/components/ui/card/CardFooter.vue new file mode 100644 index 0000000..6c0b578 --- /dev/null +++ b/src/components/ui/card/CardFooter.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/card/CardHeader.vue b/src/components/ui/card/CardHeader.vue new file mode 100644 index 0000000..449ac11 --- /dev/null +++ b/src/components/ui/card/CardHeader.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/card/CardTitle.vue b/src/components/ui/card/CardTitle.vue new file mode 100644 index 0000000..27d86f9 --- /dev/null +++ b/src/components/ui/card/CardTitle.vue @@ -0,0 +1,17 @@ + + + diff --git a/src/components/ui/card/index.ts b/src/components/ui/card/index.ts new file mode 100644 index 0000000..409685b --- /dev/null +++ b/src/components/ui/card/index.ts @@ -0,0 +1,7 @@ +export { default as Card } from "./Card.vue"; +export { default as CardAction } from "./CardAction.vue"; +export { default as CardContent } from "./CardContent.vue"; +export { default as CardDescription } from "./CardDescription.vue"; +export { default as CardFooter } from "./CardFooter.vue"; +export { default as CardHeader } from "./CardHeader.vue"; +export { default as CardTitle } from "./CardTitle.vue"; diff --git a/src/components/ui/carousel/Carousel.vue b/src/components/ui/carousel/Carousel.vue new file mode 100644 index 0000000..4bdfc6e --- /dev/null +++ b/src/components/ui/carousel/Carousel.vue @@ -0,0 +1,53 @@ + + + diff --git a/src/components/ui/carousel/CarouselContent.vue b/src/components/ui/carousel/CarouselContent.vue new file mode 100644 index 0000000..460d031 --- /dev/null +++ b/src/components/ui/carousel/CarouselContent.vue @@ -0,0 +1,33 @@ + + + diff --git a/src/components/ui/carousel/CarouselItem.vue b/src/components/ui/carousel/CarouselItem.vue new file mode 100644 index 0000000..dedce9c --- /dev/null +++ b/src/components/ui/carousel/CarouselItem.vue @@ -0,0 +1,24 @@ + + + diff --git a/src/components/ui/carousel/CarouselNext.vue b/src/components/ui/carousel/CarouselNext.vue new file mode 100644 index 0000000..a40c946 --- /dev/null +++ b/src/components/ui/carousel/CarouselNext.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/components/ui/carousel/CarouselPrevious.vue b/src/components/ui/carousel/CarouselPrevious.vue new file mode 100644 index 0000000..d290c6a --- /dev/null +++ b/src/components/ui/carousel/CarouselPrevious.vue @@ -0,0 +1,41 @@ + + + diff --git a/src/components/ui/carousel/index.ts b/src/components/ui/carousel/index.ts new file mode 100644 index 0000000..3c306c2 --- /dev/null +++ b/src/components/ui/carousel/index.ts @@ -0,0 +1,8 @@ +export { default as Carousel } from "./Carousel.vue"; +export { default as CarouselContent } from "./CarouselContent.vue"; +export { default as CarouselItem } from "./CarouselItem.vue"; +export { default as CarouselNext } from "./CarouselNext.vue"; +export { default as CarouselPrevious } from "./CarouselPrevious.vue"; +export type { UnwrapRefCarouselApi as CarouselApi } from "./interface"; + +export { useCarousel } from "./useCarousel"; diff --git a/src/components/ui/carousel/interface.ts b/src/components/ui/carousel/interface.ts new file mode 100644 index 0000000..74a45c0 --- /dev/null +++ b/src/components/ui/carousel/interface.ts @@ -0,0 +1,24 @@ +import type useEmblaCarousel from "embla-carousel-vue"; +import type { EmblaCarouselVueType } from "embla-carousel-vue"; +import type { HTMLAttributes, UnwrapRef } from "vue"; + +type CarouselApi = EmblaCarouselVueType[1]; +type UseCarouselParameters = Parameters; +type CarouselOptions = UseCarouselParameters[0]; +type CarouselPlugin = UseCarouselParameters[1]; + +export type UnwrapRefCarouselApi = UnwrapRef; + +export interface CarouselProps { + opts?: CarouselOptions; + plugins?: CarouselPlugin; + orientation?: "horizontal" | "vertical"; +} + +export interface CarouselEmits { + (e: "init-api", payload: UnwrapRefCarouselApi): void; +} + +export interface WithClassAsProps { + class?: HTMLAttributes["class"]; +} diff --git a/src/components/ui/carousel/useCarousel.ts b/src/components/ui/carousel/useCarousel.ts new file mode 100644 index 0000000..c8f4c5c --- /dev/null +++ b/src/components/ui/carousel/useCarousel.ts @@ -0,0 +1,66 @@ +import type { + UnwrapRefCarouselApi as CarouselApi, + CarouselEmits, + CarouselProps, +} from "./interface"; +import { createInjectionState } from "@vueuse/core"; +import emblaCarouselVue from "embla-carousel-vue"; +import { onMounted, ref } from "vue"; + +const [useProvideCarousel, useInjectCarousel] = createInjectionState( + ({ opts, orientation, plugins }: CarouselProps, emits: CarouselEmits) => { + const [emblaNode, emblaApi] = emblaCarouselVue( + { + ...opts, + axis: orientation === "horizontal" ? "x" : "y", + }, + plugins, + ); + + function scrollPrev() { + emblaApi.value?.scrollPrev(); + } + function scrollNext() { + emblaApi.value?.scrollNext(); + } + + const canScrollNext = ref(false); + const canScrollPrev = ref(false); + + function onSelect(api: CarouselApi) { + canScrollNext.value = api?.canScrollNext() || false; + canScrollPrev.value = api?.canScrollPrev() || false; + } + + onMounted(() => { + if (!emblaApi.value) return; + + emblaApi.value?.on("init", onSelect); + emblaApi.value?.on("reInit", onSelect); + emblaApi.value?.on("select", onSelect); + + emits("init-api", emblaApi.value); + }); + + return { + carouselRef: emblaNode, + carouselApi: emblaApi, + canScrollPrev, + canScrollNext, + scrollPrev, + scrollNext, + orientation, + }; + }, +); + +function useCarousel() { + const carouselState = useInjectCarousel(); + + if (!carouselState) + throw new Error("useCarousel must be used within a "); + + return carouselState; +} + +export { useCarousel, useProvideCarousel }; diff --git a/src/data/testimonials.json b/src/data/testimonials.json new file mode 100644 index 0000000..2c79226 --- /dev/null +++ b/src/data/testimonials.json @@ -0,0 +1,17 @@ +[ + { + "testimonial": "Enquanto alguém que tem uma enorme paixão por tecnologia, ser mentor permite me ser o veículo de aprendizagem para jovens que partilham dessa paixão, algo que me realiza particularmente. Além disso, aprendi muito e continuo a aprender com aqueles que já cá estavam e me receberam de braços abertos.", + "author": "Filipe Felício", + "major": "Engenharia Informática" + }, + { + "testimonial": "É realmente fantástico fazer parte de um projeto que tanto tem crescido nos últimos anos e poder ajudá-lo a chegar ainda mais longe. Integrar a equipa de Comunicação e Marketing do Dojo tem-me permitido ganhar experiência prática na minha área e aprender imenso com os restantes mentores e voluntários.", + "author": "Francisco Alves", + "major": "Ciências da Comunicação" + }, + { + "testimonial": "Ser voluntário no CoderDojo Braga é uma experiência muito gratificante, pois permite-me apoiar e melhorar uma organização cujas atividades têm um efeito positivo profundo e duradouro nos ninjas, mentores e voluntários que nelas participam.", + "author": "Miguel Brandão", + "major": "Engenharia Informática" + } +] diff --git a/src/pages/recruitment.astro b/src/pages/recruitment.astro index e69de29..bb86480 100644 --- a/src/pages/recruitment.astro +++ b/src/pages/recruitment.astro @@ -0,0 +1,48 @@ +--- +import CarouselTestimonials from "@/components/CarouselTestimonials.vue"; +import Timeline from "@/components/Timeline.astro"; +import Page from "@/components/Page.astro"; +import MainLayout from "@/layouts/MainLayout.astro"; +import TimelineItem from "@/components/TimelineItem.astro"; +import Developer from "@/components/Developer.astro"; +import Mentor from "@/components/Mentor.astro"; +import Communication from "@/components/Communication.astro"; +import CarouselTimeline from "@/components/CarouselTimeline.astro"; +--- + + + + + + + + + + + + + + + + + + + +