diff --git a/base.css b/base.css index 6f24f762..fc17be13 100644 --- a/base.css +++ b/base.css @@ -130,4 +130,13 @@ body :is(h1, h2, h3, h4, h5, h6) { @apply tracking-[-0.03em] font-aktiv; } + + .projects-gradient { + background: linear-gradient( + 180deg, + rgba(0, 0, 0, 0) 0%, + rgba(0, 0, 0, 0.217) 40.39%, + rgba(0, 0, 0, 0.7) 74.77% + ); + } } diff --git a/public/tolocar_illustration_projects.svg b/public/tolocar_illustration_projects.svg new file mode 100644 index 00000000..4b0d339b --- /dev/null +++ b/public/tolocar_illustration_projects.svg @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/arrow-up.svg b/src/assets/arrow-up.svg new file mode 100644 index 00000000..53ad921f --- /dev/null +++ b/src/assets/arrow-up.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/ButtonLink.tsx b/src/components/ButtonLink.tsx index dfa7e14c..bae2a191 100644 --- a/src/components/ButtonLink.tsx +++ b/src/components/ButtonLink.tsx @@ -20,7 +20,7 @@ const ButtonLink: React.FC = ({ const classes = { light: "bg-white z-10 text-tolo-green flex gap-2 justify-center items-center px-3 py-2 rounded-full font-semibold text-lg lg:mt-4 h-10 w-44", - dark: "bg-black z-10 text-white flex gap-2 justify-center items-center px-3 rounded-full font-semibold text-lg lg:mt-4 h-10 w-44", + dark: "bg-neutral-700 z-10 text-white flex gap-2.5 justify-center items-center px-6 rounded-full font-semibold lg:text-lg lg:leading-6 text-base leading-[22px] h-10 w-fit", search: "bg-black z-10 inline-flex items-center bg-opacity-20 opacity-90 rounded-full py-4 px-5 mt-8", github: @@ -39,6 +39,7 @@ const ButtonLink: React.FC = ({ {variant === "search" && ( )} + {variant === "dark" && } ); }; diff --git a/src/components/CommunityGridCard.tsx b/src/components/CommunityGridCard.tsx index c599495f..120ba0b0 100644 --- a/src/components/CommunityGridCard.tsx +++ b/src/components/CommunityGridCard.tsx @@ -1,4 +1,5 @@ import React from "react"; +import { ConditionalLinkWrapper } from "@components"; interface Props { className?: string; @@ -15,7 +16,7 @@ const CommunityGridCard: React.FC = ({ }: Props) => { return ( - + ); }; -const LinkWrapper = ({ condition, wrapper, children }) => - condition ? wrapper(children) : children; - export default CommunityGridCard; diff --git a/src/components/ConditionalLinkWrapper.tsx b/src/components/ConditionalLinkWrapper.tsx new file mode 100644 index 00000000..4e381687 --- /dev/null +++ b/src/components/ConditionalLinkWrapper.tsx @@ -0,0 +1,4 @@ +const ConditionalLinkWrapper = ({ condition, wrapper, children }) => + condition ? wrapper(children) : children; + +export default ConditionalLinkWrapper; diff --git a/src/components/ProjectCard.tsx b/src/components/ProjectCard.tsx new file mode 100644 index 00000000..acf25637 --- /dev/null +++ b/src/components/ProjectCard.tsx @@ -0,0 +1,44 @@ +import React from "react"; +import type { IProjectsFrontmatter } from "@interfaces/IProjects"; +import { ReactComponent as ArrowUpIcon } from "@assets/arrow-up.svg"; +import { ConditionalLinkWrapper } from "@components"; + +interface Props extends IProjectsFrontmatter { + className?: string; + href?: string; +} + +const ProjectCard: React.FC = ({ + className, + title, + img, + teaser, + href, +}) => { + return ( + {children}} + > +
+ Project photo +
+
+ {title && ( +

+ {title} + +

+ )} + {teaser &&

{teaser}

} +
+
+ + ); +}; + +export default ProjectCard; diff --git a/src/components/ProjectsHeader.tsx b/src/components/ProjectsHeader.tsx new file mode 100644 index 00000000..709d6e94 --- /dev/null +++ b/src/components/ProjectsHeader.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import { HeadlineUnderlined } from "@components"; + +interface Props { + className?: string; + title?: string; + text?: string; +} + +const ProjectsHeader: React.FC = ({ className, title, text }: Props) => { + return ( +
+
+ + {title} + +
+ {text} +
+
+
+ ); +}; + +export default ProjectsHeader; diff --git a/src/components/ProjectsHeroImage.tsx b/src/components/ProjectsHeroImage.tsx new file mode 100644 index 00000000..c7fb0633 --- /dev/null +++ b/src/components/ProjectsHeroImage.tsx @@ -0,0 +1,35 @@ +import React from "react"; +import type { IProjectsFrontmatter } from "@interfaces/IProjects"; + +interface Props extends IProjectsFrontmatter { + className?: string; +} + +const ProjectsHeroImage: React.FC = ({ + className, + title, + teaser, + img, +}: Props) => { + return ( +
+
+

+ {title} +

+ {teaser && ( +

+ {teaser} +

+ )} +
+
+ ); +}; + +export default ProjectsHeroImage; diff --git a/src/components/ProjectsSection.astro b/src/components/ProjectsSection.astro new file mode 100644 index 00000000..0dead7b4 --- /dev/null +++ b/src/components/ProjectsSection.astro @@ -0,0 +1,55 @@ +--- +import { IProjectsFrontmatter } from "@interfaces/IProjects"; +import { ProjectCard, ButtonLink } from "@components"; +import { trimAndSortProjects } from "@util/ContentTransformer"; +const rawProjectsContent = await Astro.glob( + "../pages/en/projects/*.mdx" +); +const projectCount = 3; +const trimmedAndSorted = trimAndSortProjects(rawProjectsContent, projectCount); +--- + +
+
+
+ Latest projects +
+
+ Within the Tolocar Project + we support different projects with our equipment, knowledge and + capacities. +
+
+ The projects are in areas like insulation, energy supply, connectivity and + sewage water. +
+
+
+ { + trimmedAndSorted.map((project) => ( + + )) + } +
+
+ +
+
diff --git a/src/components/TableOfContents.tsx b/src/components/TableOfContents.tsx index fd3cafe4..e34966a1 100644 --- a/src/components/TableOfContents.tsx +++ b/src/components/TableOfContents.tsx @@ -1,11 +1,10 @@ -import type { MarkdownHeading } from 'astro'; +import type { MarkdownHeading } from "astro"; interface Props { title: string; headlines: Array; } - const buildTocList = (input: Array) => { // Create a ordered list of depth and remove duplicates let map = new Map( @@ -37,7 +36,9 @@ const TableOfContents: React.FC = ({ title, headlines }) => { const leftPadding = paddingMapping[headline.depth]; return (
  • - {headline.text} + + {headline.text} +
  • ); })} diff --git a/src/components/index.tsx b/src/components/index.tsx index 1d5d7f85..583fcfdc 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -26,4 +26,9 @@ export { default as ImpactListItem } from "@components/ImpactListItem"; export { default as CommunityBanner } from "@components/CommunityBanner"; export { default as CommunityGridCard } from "@components/CommunityGridCard"; export { default as CommunityHeader } from "@components/CommunityHeader"; +export { default as ProjectsHeader } from "@components/ProjectsHeader"; +export { default as ProjectCard } from "@components/ProjectCard"; +export { default as ConditionalLinkWrapper } from "@components/ConditionalLinkWrapper"; +export { default as ProjectsHeroImage } from "@components/ProjectsHeroImage"; export { default as LanguageSwitcher } from "@components/LanguageSwitcher"; +export { default as ProjectsSection } from "@components/ProjectsSection.astro"; diff --git a/src/interfaces/IProjects.ts b/src/interfaces/IProjects.ts new file mode 100644 index 00000000..1c5ff697 --- /dev/null +++ b/src/interfaces/IProjects.ts @@ -0,0 +1,6 @@ +export interface IProjectsFrontmatter { + title: string; + teaser?: string; + img?: string; + order?: number; + } \ No newline at end of file diff --git a/src/layouts/ProjectsIndex.astro b/src/layouts/ProjectsIndex.astro new file mode 100644 index 00000000..e62349ff --- /dev/null +++ b/src/layouts/ProjectsIndex.astro @@ -0,0 +1,52 @@ +--- +import BaseLayout from "./BaseLayout.astro"; +import { IProjectsFrontmatter } from "@interfaces/IProjects"; +import { + ProjectsHeader, + ProjectCard, + ContentSection, + WideCard, +} from "@components"; +import { trimAndSortProjects } from "@util/ContentTransformer"; + +const { frontmatter, url, file, headings } = Astro.props; +const rawProjectsContent = await Astro.glob( + "../pages/en/projects/*.mdx" +); +const trimmedAndSorted = trimAndSortProjects(rawProjectsContent); +--- + + + +
    +
    + { + trimmedAndSorted.map((project) => ( + + )) + } +
    +
    + + +
    +
    +
    diff --git a/src/layouts/ProjectsSingleView.astro b/src/layouts/ProjectsSingleView.astro new file mode 100644 index 00000000..b1029dee --- /dev/null +++ b/src/layouts/ProjectsSingleView.astro @@ -0,0 +1,99 @@ +--- +import BaseLayout from "./BaseLayout.astro"; +import { + ProjectsHeroImage, + BackButton, + ContentSection, + Card, + CardContainer, + TableOfContents, +} from "@components"; +import type { IProjectsFrontmatter } from "@interfaces/IProjects"; +import { getParentPage } from "@util/ContentTransformer"; +import fs from "node:fs"; +import Giscus from "@components/Giscus.astro"; +import CommonUtils from "@util/CommonUtils"; + +const rawProjectsContent = await Astro.glob( + "../pages/en/projects/*.mdx" +); + +const baseUrl = CommonUtils.getBaseUrl(false); +const { frontmatter, url, file, headings } = Astro.props; + +const statsMtime = fs.statSync(file).mtime; +const editDate = new Date(statsMtime); + +const parentPage = getParentPage(rawProjectsContent, url); +--- + + +
    + Back to Project Overview +
    +
    + +
    +
    +
    + +
    + Last updated
    + { + editDate.toLocaleDateString("en", { + timeZone: "Europe/Berlin", + day: "numeric", + month: "long", + year: "numeric", + }) + } + +
    +
    +
    + +
    +
    + {!frontmatter.disableComments && } + + +
    +
    + + Schools, universities, NGOs, Startups and other organizations can reach + out to us to request the Tolocars for projects, workshops and trainings. + We are looking for Makers, FabLabs, Hackerspaces, Makerspaces and other + Communities who wants to partner with us in the Ukraine and + internationally over the internet. + +
    +
    diff --git a/src/pages/en/_menu.mdx b/src/pages/en/_menu.mdx index 3bde0333..22cf1517 100644 --- a/src/pages/en/_menu.mdx +++ b/src/pages/en/_menu.mdx @@ -5,16 +5,19 @@ menu: hideInFooter: true - title: What is a Tolocar? - target: "/en/#what-is-a-tolocar" + target: "en/#what-is-a-tolocar" + + - title: Projects + target: "en/projects" - title: Community - target: "/en/community" + target: "en/community" - title: Makerspace Academy - target: "/en/academy" + target: "en/academy" - title: Jobs - target: "/en/jobs" + target: "en/jobs" hideInHeader: true - title: Contact diff --git a/src/pages/en/index.mdx b/src/pages/en/index.mdx index 2aa0e391..fc881d7f 100644 --- a/src/pages/en/index.mdx +++ b/src/pages/en/index.mdx @@ -21,7 +21,8 @@ import { NewsItem, CommunityCard, WideCard, - ImpactListItem + ImpactListItem, + ProjectsSection } from "@components"; @@ -122,6 +123,10 @@ import {
    + + + +
    diff --git a/src/pages/en/projects/anderesbike.mdx b/src/pages/en/projects/anderesbike.mdx new file mode 100644 index 00000000..baffc978 --- /dev/null +++ b/src/pages/en/projects/anderesbike.mdx @@ -0,0 +1,19 @@ +--- +title: Anderes Bike +img: https://picsum.photos/id/237/640/480 +order: 3 +teaser: The XYZ CARGO BIKE is a two-wheeled cargo-cycle for transporting persons or goods in a fast way. +layout: "@layouts/ProjectsSingleView.astro" +--- + +## Introduction + +In this part you'll learn how a 3D FDM printer works, the different types of FDM printers and the applications 3D printing is used for. + +GitHub Pages has access to your HTTP request, the website request required to view this website or any other website. This request includes your IP address and a user agent, a string with the name of your browser and the version you are using. + +## Security measures + +## Setting up the software + +### Subheadline \ No newline at end of file diff --git a/src/pages/en/projects/index.mdx b/src/pages/en/projects/index.mdx new file mode 100644 index 00000000..5dca6185 --- /dev/null +++ b/src/pages/en/projects/index.mdx @@ -0,0 +1,6 @@ +--- +layout: "@layouts/ProjectsIndex.astro" +title: Projects +darkNavigation: true +footerGrey: true +--- \ No newline at end of file diff --git a/src/pages/en/projects/project4.mdx b/src/pages/en/projects/project4.mdx new file mode 100644 index 00000000..728324d5 --- /dev/null +++ b/src/pages/en/projects/project4.mdx @@ -0,0 +1,19 @@ +--- +title: Projekt 4 +img: https://picsum.photos/id/217/640/480 +order: 4 +teaser: Lorem ipsum +layout: "@layouts/ProjectsSingleView.astro" +--- + +## Introduction + +In this part you'll learn how a 3D FDM printer works, the different types of FDM printers and the applications 3D printing is used for. + +GitHub Pages has access to your HTTP request, the website request required to view this website or any other website. This request includes your IP address and a user agent, a string with the name of your browser and the version you are using. + +## Security measures + +## Setting up the software + +### Subheadline \ No newline at end of file diff --git a/src/pages/en/projects/projekt1.mdx b/src/pages/en/projects/projekt1.mdx new file mode 100644 index 00000000..7285646b --- /dev/null +++ b/src/pages/en/projects/projekt1.mdx @@ -0,0 +1,19 @@ +--- +title: Projekt 1 +img: https://picsum.photos/id/27/640/480 +order: 2 +teaser: Lorem ipsum +layout: "@layouts/ProjectsSingleView.astro" +--- + +## Introduction + +In this part you'll learn how a 3D FDM printer works, the different types of FDM printers and the applications 3D printing is used for. + +GitHub Pages has access to your HTTP request, the website request required to view this website or any other website. This request includes your IP address and a user agent, a string with the name of your browser and the version you are using. + +## Security measures + +## Setting up the software + +### Subheadline \ No newline at end of file diff --git a/src/pages/en/projects/projekt435.mdx b/src/pages/en/projects/projekt435.mdx new file mode 100644 index 00000000..56bf93af --- /dev/null +++ b/src/pages/en/projects/projekt435.mdx @@ -0,0 +1,19 @@ +--- +title: Projekt 435 +img: https://picsum.photos/id/72/640/480 +order: 6 +teaser: Lorem ipsum +layout: "@layouts/ProjectsSingleView.astro" +--- + +## Introduction + +In this part you'll learn how a 3D FDM printer works, the different types of FDM printers and the applications 3D printing is used for. + +GitHub Pages has access to your HTTP request, the website request required to view this website or any other website. This request includes your IP address and a user agent, a string with the name of your browser and the version you are using. + +## Security measures + +## Setting up the software + +### Subheadline \ No newline at end of file diff --git a/src/pages/en/projects/xyzcargobike.mdx b/src/pages/en/projects/xyzcargobike.mdx new file mode 100644 index 00000000..d816f6ad --- /dev/null +++ b/src/pages/en/projects/xyzcargobike.mdx @@ -0,0 +1,19 @@ +--- +title: XYZ Cargobike +img: https://picsum.photos/id/89/640/480 +order: 1 +teaser: The XYZ CARGO BIKE is a two-wheeled cargo-cycle for transporting persons or goods in a fast way. +layout: "@layouts/ProjectsSingleView.astro" +--- + +## Introduction + +In this part you'll learn how a 3D FDM printer works, the different types of FDM printers and the applications 3D printing is used for. + +GitHub Pages has access to your HTTP request, the website request required to view this website or any other website. This request includes your IP address and a user agent, a string with the name of your browser and the version you are using. + +## Security measures + +## Setting up the software + +### Subheadline \ No newline at end of file diff --git a/src/pages/en/projects/xyzcargobike2.mdx b/src/pages/en/projects/xyzcargobike2.mdx new file mode 100644 index 00000000..798b3289 --- /dev/null +++ b/src/pages/en/projects/xyzcargobike2.mdx @@ -0,0 +1,19 @@ +--- +title: XYZ Cargobike +img: https://picsum.photos/id/21/640/480 +order: 5 +teaser: The XYZ CARGO BIKE is a two-wheeled cargo-cycle for transporting persons or goods in a fast way. +layout: "@layouts/ProjectsSingleView.astro" +--- + +## Introduction + +In this part you'll learn how a 3D FDM printer works, the different types of FDM printers and the applications 3D printing is used for. + +GitHub Pages has access to your HTTP request, the website request required to view this website or any other website. This request includes your IP address and a user agent, a string with the name of your browser and the version you are using. + +## Security measures + +## Setting up the software + +### Subheadline \ No newline at end of file diff --git a/src/util/ContentTransformer.ts b/src/util/ContentTransformer.ts index ddf7ae91..7982ba7c 100644 --- a/src/util/ContentTransformer.ts +++ b/src/util/ContentTransformer.ts @@ -3,6 +3,7 @@ import type { AcademyPageFrontmatter, } from "@interfaces/IAcademy"; import type { MDXInstance } from "astro"; +import type { IProjectsFrontmatter } from "@interfaces/IProjects"; export function flatAcademyContentMap( rawAcademyContent: MDXInstance[] @@ -66,3 +67,18 @@ export function transformAcademy(rawAcademyContent) { return coursesAndLessons; } + +export function trimAndSortProjects( + rawProjectsContent: MDXInstance[], + count?: number +) { + const rawSortedProjectsContentWithoutIndex = rawProjectsContent + .filter((project) => !project.file.includes("index.mdx")) + .sort((a, b) => b.frontmatter.order - a.frontmatter.order); + + const trimmedProjects = count + ? rawSortedProjectsContentWithoutIndex.slice(0, count) + : rawSortedProjectsContentWithoutIndex; + + return trimmedProjects; +} diff --git a/tailwind.config.cjs b/tailwind.config.cjs index c8b56a24..09159715 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -4,7 +4,7 @@ module.exports = { theme: { extend: { transitionProperty: { - 'height': 'height', + height: "height", }, opacity: { 15: ".15", @@ -35,6 +35,7 @@ module.exports = { "linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.301) 30.5%, rgba(0, 0, 0, 0.7) 66.96%), url(/images/classroom.jpg)", "community-messages": "linear-gradient(-6.5deg, rgba(0, 150, 100, 1) 0%, rgba(0, 150, 100, 0) 31.54%, rgba(0, 150, 100, 0) 66.78%, rgba(0, 150, 100, 1) 100%), url(/community_messages.svg)", + "illustration-projects": "url('/tolocar_illustration_projects.svg')", }, }, colors: {