diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 6d2520465..2478d5c44 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -98,6 +98,13 @@ const config: Config = { className: "custom_navbar_item", label: "Blog", position: "left", + }, + { + to: "/fundable/", + className: "custom_navbar_item", + label: "Fundable projects", + position: "right", + className:"fundable_projects" }, { to: "/contact/", diff --git a/src/components/footer/Footer.tsx b/src/components/footer/Footer.tsx index 3bff55f91..80960ac69 100644 --- a/src/components/footer/Footer.tsx +++ b/src/components/footer/Footer.tsx @@ -65,6 +65,16 @@ export default function Footer() { +
+ +
diff --git a/src/components/fundable/LargeProjectCard.tsx b/src/components/fundable/LargeProjectCard.tsx new file mode 100644 index 000000000..800d87d2e --- /dev/null +++ b/src/components/fundable/LargeProjectCard.tsx @@ -0,0 +1,29 @@ +import styles from "./styles.module.css"; +import React from "react"; + +export default function LargeProjectCard({ project }) { + return ( +
+
+
+
+
+ {project.category} +
+
{project.title}
+
+
+
+
+
+
Overview
+
+ +
+
+
+ +
+
+ ); +} diff --git a/src/components/fundable/LargeProjectCardPage.tsx b/src/components/fundable/LargeProjectCardPage.tsx new file mode 100644 index 000000000..09a218185 --- /dev/null +++ b/src/components/fundable/LargeProjectCardPage.tsx @@ -0,0 +1,80 @@ +import { useHistory, useLocation } from "@docusaurus/router"; +import { useEffect } from "react"; +import styles from "./styles.module.css"; +import LargeProjectCard from "./LargeProjectCard"; +import { getCategoryFromProjectTitle } from "."; +import FundableProjects from "."; +import Layout from "@theme/Layout"; +import { Route } from 'react-router-dom'; + + +export default function LargeProjectCardPage() { + const location = useLocation(); + const history = useHistory(); + + useEffect(() => { + if (location.state?.fromFundable) { + window.scrollTo({ top: location.state.scrollY ?? 0, behavior: 'auto' }); + } + }, []); + + const handleOverlayClick = () => { + const scrollY = location.state?.scrollY; + setTimeout(() => { + if (scrollY !== undefined) { + window.scrollTo({ top: scrollY, behavior: 'auto' }); + } + }, 0); + history.replace('/fundable'); + }; + + const handleClose = () => { + const scrollY = location.state?.scrollY; + if (location.state?.fromFundable) { + history.replace('/fundable'); + + setTimeout(() => { + if (scrollY !== undefined) { + window.scrollTo({ top: scrollY, behavior: 'auto' }); + } + }, 0); + } else { + history.goBack(); + } + } + return ( + + + { + const { shortTitle } = match.params; /* extract the dynamic part from the url i.e. the shortTitle*/ + const projectsByCategory = getCategoryFromProjectTitle(shortTitle); + console.log('projectsByCategory:', projectsByCategory); + const project = projectsByCategory.find((project) => project.shortTitle.replace(/\s+/g, '') === shortTitle); + if (!project) return null; + + return ( +
+
e.stopPropagation()} + > +
+
+ ); + }} + /> +
+ ) +} \ No newline at end of file diff --git a/src/components/fundable/MenuSideBar.tsx b/src/components/fundable/MenuSideBar.tsx new file mode 100644 index 000000000..6074d8e83 --- /dev/null +++ b/src/components/fundable/MenuSideBar.tsx @@ -0,0 +1,26 @@ +// src/components/CustomSidebar.js +import React from 'react'; +import { useLocation } from '@docusaurus/router'; + + +const menuItems = [ + { label: 'Overview', path: '/fundable' }, + { label: 'Eligibility', path: '/fundable/eligibility' }, + { label: 'Apply', path: '/fundable/apply' }, +]; + +export default function MenuSidebar() { + const location = useLocation(); + + return ( + + ); +} \ No newline at end of file diff --git a/src/components/fundable/ProgressBar.tsx b/src/components/fundable/ProgressBar.tsx new file mode 100644 index 000000000..d43bff8f1 --- /dev/null +++ b/src/components/fundable/ProgressBar.tsx @@ -0,0 +1,25 @@ +import React from "react"; + +export default function ProgressBar({ value = 0, color = '#4caf50' }) { + return ( + +
+ +
+
+ ); +} diff --git a/src/components/fundable/ProjectCategory.tsx b/src/components/fundable/ProjectCategory.tsx new file mode 100644 index 000000000..071ce99d5 --- /dev/null +++ b/src/components/fundable/ProjectCategory.tsx @@ -0,0 +1,22 @@ +import styles from "./styles.module.css"; +import { SmallProjectCard } from "./SmallProjectCard"; + + +export default function ProjectCategory({ projectCategoryName, projectCategory }) { + return ( +
+

{projectCategoryName}

+
+
    + {projectCategory.map((project) => ( +
  • +
    + +
    +
  • + ))} +
+
+
+ ); +} \ No newline at end of file diff --git a/src/components/fundable/SmallProjectCard.tsx b/src/components/fundable/SmallProjectCard.tsx new file mode 100644 index 000000000..8dcdd2a16 --- /dev/null +++ b/src/components/fundable/SmallProjectCard.tsx @@ -0,0 +1,61 @@ +import styles from "./styles.module.css"; +import ProgressBar from "./ProgressBar"; +import { useHistory } from "@docusaurus/router"; + +export function SmallProjectCard({ project }) { +const history = useHistory(); + + function openDialog() { + const shortTitle = project.shortTitle.replace(/\s+/g, ''); + + history.push({ + pathname: `/fundable/${shortTitle}`, + state: { fromFundable: true, scrollY: window.scrollY, }, + }); + } + + + return ( +
+
+
+
+ {project.title} +
+
+
+
+
+
+ {project.catchUpPhrase} + +
+
+ Indicative Price: {project.price} € +
+ +
+ Shareable between {project.maxNbOfFunders} funders. +
+
+ Currently this project is supported by {project.currentNbOfFunders} funders. +
+
+ Financed at {project.currentFundingPercentage} % +
+
+ +
+
+
+
+
+ +
+ ) +} \ No newline at end of file diff --git a/src/components/fundable/descriptions/MambaNewFeature.md b/src/components/fundable/descriptions/MambaNewFeature.md new file mode 100644 index 000000000..da551d2f3 --- /dev/null +++ b/src/components/fundable/descriptions/MambaNewFeature.md @@ -0,0 +1 @@ +To be writen. \ No newline at end of file diff --git a/src/components/fundable/descriptions/ModernizeNbconvert.md b/src/components/fundable/descriptions/ModernizeNbconvert.md new file mode 100644 index 000000000..f972c9cb5 --- /dev/null +++ b/src/components/fundable/descriptions/ModernizeNbconvert.md @@ -0,0 +1,5 @@ +Conversion of Jupyter notebooks to PDF currently relies on nbconvert in the backend, which in turns uses a headless browser for producing the PDF. We propose to directly perform the PDF conversion in the user's browser, which will simplify the architecture and make it function with JupyterLite. + +Nbconvert heavily relies on Jinja2 templates for conversion to different formats. + +We will utilize a JavaScript implementation of Jinja2 covering the required features of Jinja to produce a frontend version of nbconvert that does not require Python but still provides a good coverage of the nbconvert features, including the use of custom templates. \ No newline at end of file diff --git a/src/components/fundable/index.tsx b/src/components/fundable/index.tsx new file mode 100644 index 000000000..b46ef8a40 --- /dev/null +++ b/src/components/fundable/index.tsx @@ -0,0 +1,42 @@ +import styles from "./styles.module.css"; +import { fundableProjectsDetails } from "./projectsDetails"; +import ProjectCategory from "./ProjectCategory"; + +export function getCategoryFromProjectTitle(title: string) { + for (const [categoryName, projectsByCategory] of Object.entries(fundableProjectsDetails)) { + const project = projectsByCategory.find((project) => project.shortTitle.replace(/\s+/g, '').replace(/\s+/g, '') === title); + if (project) { + return projectsByCategory; + } + } + return null; +} + +export default function FundableProjects() { + return ( +
+
+
+
+

Check out our projects available for funding!

+
+
+
+
+ + + +
+
+
+
+ + + ); +} diff --git a/src/components/fundable/projectsDetails.ts b/src/components/fundable/projectsDetails.ts new file mode 100644 index 000000000..e78311eb8 --- /dev/null +++ b/src/components/fundable/projectsDetails.ts @@ -0,0 +1,42 @@ +import ModernizeNbconvertMD from "@site/src/components/fundable/descriptions/ModernizeNbconvert.md" +import MambaNewFeatureMD from "@site/src/components/fundable/descriptions/MambaNewFeature.md" + +export const fundableProjectsDetails = { + jupyterEcosystem: [ + { + category: "Jupyter Ecosystem", + title: "Modernize nbconvert", + shortTitle: "Modern Nbconvert", + catchUpPhrase: "HELP US TO MODERNIZE NBCONVERT", + description: ModernizeNbconvertMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [], + price: 15000, + maxNbOfFunders: 3, + currentNbOfFunders: 2, + currentFundingPercentage: 65, + note: "Note: Costs and features can be further adapted following discussion with the funding organization. Open-source under relevant licenses. The funding organization will be credited in communication about the project.", + repoLink: "https://github.com/jupyter/nbconvert" + }], + packageManagement: [ + { + category: "Package Management", + title: "New feature", + shortTitle: "New Feature", + catchUpPhrase: "WE PROPOSE A NEW FEATURE", + description: MambaNewFeatureMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [], + price: 25000, + maxNbOfFunders: 3, + currentNbOfFunders: 1, + currentFundingPercentage: 33, + note: "Note: Costs and features can be further adapted following discussion with the funding organization. Open-source under relevant licenses. The funding organization will be credited in communication about the project.", + repoLink: "https://github.com/mamba-org/mamba" + }], +} + diff --git a/src/components/fundable/styles.module.css b/src/components/fundable/styles.module.css new file mode 100644 index 000000000..835345290 --- /dev/null +++ b/src/components/fundable/styles.module.css @@ -0,0 +1,106 @@ +.fundable_project_card { + border: solid 0.5px; + width: 1020px; + height: 300px; + /*margin: var(--ifm-spacing-xl) 0;*/ + padding: 30px 60px ; +} + +.category_header { + font-family: var(--ifm-font-family-rubik-one); + font-style: normal; + font-weight: 400; + line-height: 20px; + text-align: center; + margin-bottom: var(--ifm-spacing-xl); + color: var(--ifm-color-secondary-s3); + padding: 20px 0; + text-align: left; +} + +.project_title { + color: var(--ifm-text-color-main-title); + font-family: var(--ifm-font-family-bebas-neue); + font-size: 32px; + font-style: normal; + font-weight: 600; + /*line-height: 150%; /* 72px */ + letter-spacing: 2.112px; + text-align: left; + padding: 0; +} + +.project_catch_up_phrase { + font-family: var(--ifm-font-family-roboto); + font-size: 16px; + font-style: normal; + font-weight: 600; + line-height: 24px; /* 150% */ + letter-spacing: 0.15px; + color: var(--ifm-color-secondary-s3); +} + +.modal_overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.3); + z-index: 1000; +} + +.modal_content { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: white; + border: 1px solid #ccc; + box-shadow: 0 8px 16px rgba(0,0,0,0.2); + border-radius: 20px; + z-index: 4000; +} +.large_project_card { + width: 1000px; + height: 600px; + padding: 40px; + border-radius: 8px; +} +.large_project_card_section_title { + font-family: var(--ifm-font-family-roboto); + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + letter-spacing: 0.15px; + } + + .large_project_card_text p { + font-family: var(--ifm-font-family-roboto); + font-size: 14px; + font-style: normal; + font-weight: 500; + line-height: 24px; /* 150% */ + letter-spacing: 0.15px; + color: var(--ifm-text-color-on-primary-p1); + text-align: justify; +} +.large_project_card_text_container { + background-color: lightgray; +} + +@media only screen and (max-width: 996px) { + /*Mobile*/ + .category_header { + font-size: 20px; +} +} + +@media only screen and (min-width: 996px) { + /*Desktop*/ + .category_header { + /*font-size: var(--ifm-font-size-secondary-title);*/ + font-size: 28px; +} +} \ No newline at end of file diff --git a/src/css/custom.css b/src/css/custom.css index 6a246bc5c..75d338f3b 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -18,6 +18,8 @@ --ifm-color-secondary-s1: #a0c9ff; --ifm-color-secondary-s2: #002646; + --ifm-color-secondary-s3: #00497F; + --ifm-color-neutral-n1: #605e58; --ifm-color-neutral-n2: #371300; @@ -559,6 +561,20 @@ a.menu__link:active { background-color: white; } +.fundable_projects { + background-color: var(--ifm-color-blue-jupyter); + color: white; + border-radius: 4px; + font-style: normal; + margin: var(--ifm-navbar-item-padding-vertical) 20px; +} + +.fundable_projects:hover { + background-color: var(--ifm-color-primary-p1); + color: var(--ifm-color-blue-jupyter) +} + + .custom_navbar_item { font-family: var(--ifm-font-family-roboto); width: 117px; @@ -671,3 +687,10 @@ ul.row { flex-wrap: wrap; margin: 0 0; } + +.custom-progress-bar::-webkit-progress-value { + background-color: var(--ifm-color-primary-p1); +} +.custom-progress-bar::-webkit-progress-bar { + background-color: #eee; +} \ No newline at end of file diff --git a/src/pages/fundable.tsx b/src/pages/fundable.tsx new file mode 100644 index 000000000..8bb5a9295 --- /dev/null +++ b/src/pages/fundable.tsx @@ -0,0 +1,14 @@ +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; +import FundableProjects from '../components/fundable'; +import Footer from "../components/footer/Footer"; + +export default function FundableProjectsPage(): JSX.Element { + const { siteConfig } = useDocusaurusContext(); + return ( + + +