diff --git a/docusaurus.config.ts b/docusaurus.config.ts index fabc5e3b5..372f57df1 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -110,6 +110,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/GetAQuoteForm.tsx b/src/components/fundable/GetAQuoteForm.tsx new file mode 100644 index 000000000..586800d36 --- /dev/null +++ b/src/components/fundable/GetAQuoteForm.tsx @@ -0,0 +1,90 @@ +import styles from "./styles.module.css"; + +export default function GetAQuoteForm() { + return ( + <> +
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ + ); + } \ No newline at end of file diff --git a/src/components/fundable/GetAQuotePage.tsx b/src/components/fundable/GetAQuotePage.tsx new file mode 100644 index 000000000..6c438da93 --- /dev/null +++ b/src/components/fundable/GetAQuotePage.tsx @@ -0,0 +1,69 @@ + +import styles from "./styles.module.css"; +import GetAQuoteForm from "./GetAQuoteForm" +import { LargeProjectCardContent } from "./LargeProjectCard"; +import { useHistory, useLocation } from "@docusaurus/router"; +import Layout from "@theme/Layout"; +import { Route } from 'react-router-dom'; +import { getCategoryFromProjectPageName } from "."; +import FundableProjects from "."; + +function GetAQuoteComponent({ project }) { + return ( +
+
+ +
+ +
+
+

Get a quote

+
+
+
+
+ ) +} +export default function GetAQuotePage() { + const location = useLocation(); + const history = useHistory(); + + const handleClose = () => { + history.push('/fundable'); + + } + return ( + + + { + const { pageName } = match.params; /* extract the dynamic part from the url i.e. the pageName*/ + const projectsByCategory = getCategoryFromProjectPageName(pageName); + const project = projectsByCategory.find((project) => project.pageName === pageName); + if (!project) return null; + + return ( +
+
e.stopPropagation()} + > +
+
+ ); + }} + /> +
+ ) +} \ No newline at end of file diff --git a/src/components/fundable/IconContainer.tsx b/src/components/fundable/IconContainer.tsx new file mode 100644 index 000000000..80714af8e --- /dev/null +++ b/src/components/fundable/IconContainer.tsx @@ -0,0 +1,26 @@ +import styles from "./styles.module.css"; +import Link from "@docusaurus/Link"; +import GHPicture from "@site/static/img/socialmedias/GH.svg"; +import LinkedInPicture from "@site/static/img/socialmedias/LinkedIn.svg"; +import BlueskyPicture from "@site/static/img/socialmedias/Bluesky.svg"; +import MastodonPicture from "@site/static/img/socialmedias/Mastodon.svg"; + +export default function IconContainer({ project }) { + const icons = project.icons + return ( + + +
+ {icons.map((Icon, index) => ( +
+ +
+ ))} +
+ ); + + +} diff --git a/src/components/fundable/LargeProjectCard.tsx b/src/components/fundable/LargeProjectCard.tsx new file mode 100644 index 000000000..e04879a07 --- /dev/null +++ b/src/components/fundable/LargeProjectCard.tsx @@ -0,0 +1,66 @@ +import styles from "./styles.module.css"; +import React from "react"; +import IconContainer from "./IconContainer"; +import LinkToGetAQuote from "./LinkToGetAQuote"; +import { useHistory, useLocation } from "@docusaurus/router"; + +export function LargeProjectCardContent({ project }) { + const history = useHistory(); + const location = useLocation(); + + function openDialog() { + const pageName = project.pageName; + + history.push({ + pathname: `/fundable/${pageName}/GetAQuote`, + state: { from: location.pathname, scrollY: window.scrollY }, + }); + } + return ( +
+
+
+
{project.title}
+
+
+
+
+
+
Overview
+
+
+ +
+
+
Option A
+
+ {project.optionA} +
+
Option B
+
+ {project.optionB} +
+
Custom Option
+
+ {project.customOption} +
+
+
+
+
+ ) +} +export default function LargeProjectCard({ project }) { + return ( +
+ +
+
+
Are you interested in this project? Either entirely or partially, contact us for more information on how to help us fund it.
+
+
+
+
+ + ); +} diff --git a/src/components/fundable/LargeProjectCardPage.tsx b/src/components/fundable/LargeProjectCardPage.tsx new file mode 100644 index 000000000..3dea1aa5b --- /dev/null +++ b/src/components/fundable/LargeProjectCardPage.tsx @@ -0,0 +1,79 @@ +import { useHistory, useLocation } from "@docusaurus/router"; +import { useEffect } from "react"; +import styles from "./styles.module.css"; +import LargeProjectCard from "./LargeProjectCard"; +import { getCategoryFromProjectPageName } 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 { pageName } = match.params; /* extract the dynamic part from the url i.e. the pageName*/ + const projectsByCategory = getCategoryFromProjectPageName(pageName); + const project = projectsByCategory.find((project) => project.pageName === pageName); + if (!project) return null; + + return ( +
+
e.stopPropagation()} + > +
+
+ ); + }} + /> +
+ ) +} \ No newline at end of file diff --git a/src/components/fundable/LinkToGetAQuote.tsx b/src/components/fundable/LinkToGetAQuote.tsx new file mode 100644 index 000000000..db1e14a07 --- /dev/null +++ b/src/components/fundable/LinkToGetAQuote.tsx @@ -0,0 +1,16 @@ +import styles from "./styles.module.css"; +import Link from "@docusaurus/Link"; + +export default function LinkToGetAQuote({label, pageName}) { + const pathname = "/fundable/"+ pageName+ "/GetAQuote" + return ( +
+ + {label} + +
+ ); +} diff --git a/src/components/fundable/LinkToMoreInformation.tsx b/src/components/fundable/LinkToMoreInformation.tsx new file mode 100644 index 000000000..89e17c158 --- /dev/null +++ b/src/components/fundable/LinkToMoreInformation.tsx @@ -0,0 +1,16 @@ +import styles from "./styles.module.css"; +import Link from "@docusaurus/Link"; + +export default function LinkToMoreInformation({label, pageName}) { + const pathname = "/fundable/"+ pageName + return ( +
+ + {label} + +
+ ); +} diff --git a/src/components/fundable/MenuSideBar.tsx b/src/components/fundable/MenuSideBar.tsx new file mode 100644 index 000000000..8ada208c7 --- /dev/null +++ b/src/components/fundable/MenuSideBar.tsx @@ -0,0 +1,48 @@ +// src/components/ScrollSidebar.js +import React, { useEffect, useState } from 'react'; +import styles from "./styles.module.css"; + +const sections = [ + { id: 'jupyter-ecosystem', label: 'Jupyter Ecosystem' }, + { id: 'project-management', label: 'Project Management' }, +]; + +export default function MenuSideBar() { + const [activeSectionId, setActiveSectionId] = useState('jupyter-ecosystem'); + + useEffect(() => { + const handleScroll = () => { + const scrollPosition = window.scrollY + 300; + for (const section of sections) { + const element = document.getElementById(section.id); + if (element && element.offsetTop <= scrollPosition) { + setActiveSectionId(section.id); + } + } + }; + window.addEventListener('scroll', handleScroll); + handleScroll(); + return () => window.removeEventListener('scroll', handleScroll); + }, []); + + return ( +
+ +
+ ); +} diff --git a/src/components/fundable/ProgressBar.tsx b/src/components/fundable/ProgressBar.tsx new file mode 100644 index 000000000..7e961b322 --- /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..7b2c59055 --- /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..775f971cd --- /dev/null +++ b/src/components/fundable/SmallProjectCard.tsx @@ -0,0 +1,117 @@ +import styles from "./styles.module.css"; +import { useHistory } from "@docusaurus/router"; +import BlueCaretIcon from "@site/static/img/icons/BlueCaret.svg"; +import LinkToMoreInformation from "./LinkToMoreInformation"; +import ProgressBar from "./ProgressBar"; +import FundersIcon from "@site/static/img/icons/Funders.svg"; +import DollarIcon from "@site/static/img/icons/Dollar.svg"; + +export function SmallProjectCard({ project }) { + const history = useHistory(); + + function openDialog() { + const pageName = project.pageName; + + history.push({ + pathname: `/fundable/${pageName}`, + state: { fromFundable: true, scrollY: window.scrollY }, + }); + } + + return ( +
+
+
+
+
+
+ {project.title} +
+
+ {project.catchUpPhrase} +
+
+
+ +
+
+
+ {project.shortDescription.length < 250 + ? project.shortDescription + : project.shortDescription.substring(0, 250) + "..."} + +
+
+
+
+ +
+ + +
+
+ +
+
+ Open-source under relevant licenses +
+
+
+
+ +
+
+ The funding organization will be credited in communication about the project +
+
+ +
Note: Costs and features can be further adapted following discussion with the funding organization
+
+
+
+
+ {project.price} +
+
+
+ Indicative price +
+
+
+ Financed at {project.currentFundingPercentage} % +
+
+ +
+
+
+
{project.maxNbOfFunders === 1 + ? 'Not shareable between funders' + : `Shareable between ${project.maxNbOfFunders} funders` + } +
+
+
+
+
+ {project.currentNbOfFunders === 0 + ? 'The project is not supported yet' + : `Supported by ${project.currentNbOfFunders} + ${project.currentNbOfFunders === 1 ? 'funder' : 'funders'} + `} +
+ +
+
+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/fundable/descriptions/EmscriptenForgePackageRequests.md b/src/components/fundable/descriptions/EmscriptenForgePackageRequests.md new file mode 100644 index 000000000..d645aeeca --- /dev/null +++ b/src/components/fundable/descriptions/EmscriptenForgePackageRequests.md @@ -0,0 +1,5 @@ +Emscripten-forge is a conda package distribution specifically designed for WebAssembly. When combined with JupyterLite and the jupyterlite-xeus extension, it enables easy deployment of JupyterLite with a preconfigured conda environment that includes essential packages like NumPy, Pandas, Matplotlib, and more. + +While the number of available emscripten-forge packages is growing quickly, many packages are still missing from the ecosystem. + +We will be working on adding new packages upon request. \ No newline at end of file diff --git a/src/components/fundable/descriptions/JupyterGISRasterProcessing.md b/src/components/fundable/descriptions/JupyterGISRasterProcessing.md new file mode 100644 index 000000000..42923c7aa --- /dev/null +++ b/src/components/fundable/descriptions/JupyterGISRasterProcessing.md @@ -0,0 +1,8 @@ +Similar to QGIS, JupyterGIS currently offers a set of vector processing and conversion tools such as buffer creation, centroid calculation, and convex hull generation. These capabilities are powered by a GDAL WebAssembly (WASM) build running in the browser. + +We will work on extending support to raster processing tools using the same underlying technology. Planned features (non-exhaustive and subject to request needs) include: + +- Clipping by extent +- Clipping by mask layer +- Generating contours +- Polygonizing raster data \ No newline at end of file diff --git a/src/components/fundable/descriptions/JupyterGISToolsForPythonAPI.md b/src/components/fundable/descriptions/JupyterGISToolsForPythonAPI.md new file mode 100644 index 000000000..f541335bf --- /dev/null +++ b/src/components/fundable/descriptions/JupyterGISToolsForPythonAPI.md @@ -0,0 +1,3 @@ +JupyterGIS currently supports several vector processing and conversion tools such as buffer creation, centroid computation, and convex hull generation, similar to what QGIS offers. These features are powered by a GDAL WebAssembly (WASM) build and are currently available only through the JupyterGIS user interface. + +We plan to extend these capabilities to the JupyterGIS Python API, enabling users to access the same processing tools programmatically, just as they would via the UI. This functionality will be implemented using the GDAL Python bindings. \ No newline at end of file diff --git a/src/components/fundable/descriptions/JupyterLabParquetFileViewer.md b/src/components/fundable/descriptions/JupyterLabParquetFileViewer.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/components/fundable/descriptions/NbconvertModernization.md b/src/components/fundable/descriptions/NbconvertModernization.md new file mode 100644 index 000000000..f972c9cb5 --- /dev/null +++ b/src/components/fundable/descriptions/NbconvertModernization.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..d49d0b164 --- /dev/null +++ b/src/components/fundable/index.tsx @@ -0,0 +1,56 @@ +import styles from "./styles.module.css"; +import { fundableProjectsDetails } from "./projectsDetails"; +import ProjectCategory from "./ProjectCategory"; +import MenuSidebar from "./MenuSideBar"; + +export function getCategoryFromProjectPageName(pageName: string) { + for (const [categoryName, projectsByCategory] of Object.entries(fundableProjectsDetails)) { + const project = projectsByCategory.find((project) => project.pageName === pageName); + if (project) { + return projectsByCategory; + } + } + return null; +} + +export function MainAreaFundableProjects() { + return ( +
+

Check out our projects available for funding!

+ +
+ +
+
+ +
+
+ + ) +} + +export default function FundableProjects() { + return ( + +
+
+
+ +
+
+ +
+
+ +
+
+
+ + ); +} diff --git a/src/components/fundable/projectsDetails.ts b/src/components/fundable/projectsDetails.ts new file mode 100644 index 000000000..f4640185f --- /dev/null +++ b/src/components/fundable/projectsDetails.ts @@ -0,0 +1,109 @@ +import NbconvertModernizationMD from "@site/src/components/fundable/descriptions/NbconvertModernization.md" +import JupyterGISRasterProcessingMD from "@site/src/components/fundable/descriptions/JupyterGISRasterProcessing.md" +import JupyterGISToolsForPythonAPIMD from "@site/src/components/fundable/descriptions/JupyterGISToolsForPythonAPI.md" +import EmscriptenForgePackageRequestsMD from "@site/src/components/fundable/descriptions/EmscriptenForgePackageRequests.md" +import JupyterLabParquetFileViewerMD from "@site/src/components/fundable/descriptions/JupyterLabParquetFileViewer.md" +import JupyterGISIcon from "/img/icons/JupyterGIS.svg"; +import ToolsIcon from "/img/icons/Tools.svg"; +import PythonIcon from "/img/icons/Python.svg"; +import GlobeIcon from "/img/icons/Globe.svg"; +import EmptyIcon from "/img/icons/Empty.svg"; +import JupyterIcon from "/img/icons/Jupyter.svg"; +import EmscriptenForgeIcon from "/img/icons/EmscriptenForge.svg"; + +export const fundableProjectsDetails = { + jupyterEcosystem: [ + { + category: "Jupyter Ecosystem", + title: "Modernize nbconvert", + pageName: "NbconvertModernization", + catchUpPhrase: "", + shortDescription: "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.", + description: NbconvertModernizationMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [JupyterIcon, EmptyIcon, EmptyIcon, EmptyIcon, EmptyIcon, EmptyIcon], + 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" + }, + { + category: "Jupyter Ecosystem", + title: "Raster processing tools in JupyterGIS", + pageName: "JupyterGISRasterProcessing", + catchUpPhrase: "", + shortDescription: "JupyterGIS currently offers a set of vector processing and conversion tools. These capabilities are powered by a GDAL WebAssembly (WASM) build running in the browser. We will work on extending support to raster processing tools using the same underlying technology.", + description: JupyterGISRasterProcessingMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [JupyterIcon, JupyterGISIcon, ToolsIcon, PythonIcon, GlobeIcon, EmptyIcon], + price: "15000 €", + maxNbOfFunders: 4, + currentNbOfFunders: 2, + currentFundingPercentage: 45, + 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/geojupyter/jupytergis" + }, + { + category: "Jupyter Ecosystem", + title: "Bringing processing tools to the JupyterGIS Python API", + pageName: "JupyterGISToolsForPythonAPI", + catchUpPhrase: "", + shortDescription: "JupyterGIS currently supports several vector processing and conversion tools, currently available only through the JupyterGIS user interface. We plan to extend these capabilities to the JupyterGIS Python API, enabling users to access the same processing tools programmatically. ", + description: JupyterGISToolsForPythonAPIMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [JupyterIcon, JupyterGISIcon, ToolsIcon, PythonIcon, GlobeIcon, EmptyIcon], + price: "10000 €", + maxNbOfFunders: 2, + currentNbOfFunders: 0, + currentFundingPercentage: 15, + 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/geojupyter/jupytergis" + }, + { + category: "Jupyter Ecosystem", + title: "Parquet File Viewer For JupyterLab", + pageName: "JupyterLabParquetFileViewer", + catchUpPhrase: "", + shortDescription: "", + description: JupyterLabParquetFileViewerMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [JupyterIcon, EmptyIcon, EmptyIcon, EmptyIcon, EmptyIcon, EmptyIcon], + price: "10000 €", + maxNbOfFunders: 3, + currentNbOfFunders: 1, + currentFundingPercentage: 15, + 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/jupyterlab/jupyterlab" + } + ], + packageManagement: [ + { + category: "Package Management", + title: "Package requests for emscripten-forge", + pageName: "EmscriptenForgePackageRequests", + catchUpPhrase: "", + shortDescription: "Emscripten-forge is a conda package distribution specifically designed for WebAssembly. While the number of available emscripten-forge packages is growing quickly, many packages are still missing from the ecosystem. We will be working on adding new packages upon request.", + description: EmscriptenForgePackageRequestsMD, + optionA: "This is option A", + optionB: "This is option B", + customOption: "This is custom option", + icons: [EmscriptenForgeIcon, EmptyIcon, EmptyIcon, EmptyIcon, EmptyIcon, EmptyIcon], + price: "TBD", + maxNbOfFunders: 1, + currentNbOfFunders: 0, + currentFundingPercentage: 0, + 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..ab6f91d4a --- /dev/null +++ b/src/components/fundable/styles.module.css @@ -0,0 +1,407 @@ + + +.small_project_card:hover { + box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1); +} + +.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); + padding: 10px 0 +} + +.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_title { + font-family: var(--ifm-font-family-roboto); + font-size: 32px; + font-style: normal; + font-weight: 400; + line-height: 40px; /* 125% */ + margin: var(--ifm-spacing-md) 0; + + } + + .large_project_card_text { + 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_section_title { + font-weight: 600; +} + +.large_project_card_description_container { + background-color: #F1F1F1 +} +.large_project_card_description p { + font-family: var(--ifm-font-family-roboto); + /*background-color: #F1F1F1;*/ + font-size: 16px; +} + +.large_project_card_option { + background-color: #F1F1F1; + font-size: 16px; + height: 32px; +} + +.large_project_card_contact_text { + font-family: var(--ifm-font-family-roboto); + font-size: 14px; + font-style: normal; + font-weight: 600; + line-height: 20px; /* 142.857% */ + letter-spacing: 0.1px; + text-align: center; + padding: var(--ifm-spacing-xl) 0 var(--ifm-spacing-md) 0 +} + + .link_to_get_a_quote { + background-color: var(--ifm-color-orange-jupyter); + color: white; + width: 358px; + font-weight: 700; + } + +.icon_container { + display: flex; + gap: 10px; + margin: var(--ifm-spacing-md) 0; +} + +.menu_sidebar { + padding: 1rem; + overflow-y: auto; +} + +.menu_sidebar_item { + font-family: var(--ifm-font-family-roboto); + font-size: 16px; + font-style: normal; + font-weight: 500; + line-height: 48px; /* 300% */ + letter-spacing: 0.15px; +} + +.menu_sidebar_container { + position: fixed; + display: flex; + height: auto; +} + +.indicator { + display: inline-block; + width: 6px; + height: 20px; + border-radius: 4px; + background-color: transparent; + margin-right: 10px; + transition: background-color 0.3s ease; + vertical-align: middle; +} + +.active_section .indicator { + background-color: #D9D9D9; +} + +.send_button { + width: 258px; + height: 59px; + background: var(--ifm-color-blue-jupyter); +} + +.contact_form { + margin-top: var(--ifm-spacing-xl); +} + +.form_label { + font-size: 12px; + color: var(--ifm-text-color); + background-color: var(--ifm-background-color); +} + + +.get_a_quote_dialog { + width: 100vw; + height: 100vh; + padding: 40px; + overflow-y: auto; +} + +.project_information_container { + display: flex; + align-items: center; +} + +.project_information { + font-family: var(--ifm-font-family-roboto); + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 20px; /* 142.857% */ + letter-spacing: 0.25px; + padding: 10px; + text-align: justify; +} + +.note { + font-family: var(--ifm-font-family-roboto); + font-size: 12px; + font-style: normal; + font-weight: 600; + line-height: 16px; /* 145.455% */ + letter-spacing: 0.5px; + margin: 12px 0; + text-align: justify; +} + +.price_container { + display: flex; + justify-content: center; + align-items: center; + padding: 8px 0; +} + +.price { + font-size: 20px; + padding: 8px 0; + background: var(--ifm-color-secondary-s1); + font-family: var(--ifm-font-family-roboto); + border-radius: 24px; + font-weight: 700; + width: 190px; + padding: 10px; + height: 56px; + text-align: center; + margin: 46px 0 4px 0; +} + +.indicative_price_text { + text-align: center; + font-family: var(--ifm-font-family-roboto); + font-size: 12px; + font-style: normal; + font-weight: 600; + line-height: 150%; /* 18px */ + letter-spacing: -0.132px; + text-transform: uppercase; +} + +.financed_at_text { + font-family: var(--ifm-font-family-roboto); + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 36px; +} + +.shareable_container { + display: flex; + align-items: center; +} + +.shareable_text { + font-family: var(--ifm-font-family-roboto); + font-size: 16px; + font-style: normal; + font-weight: 700; + line-height: 150%; /* 18px */ + letter-spacing: -0.132px; + text-transform: uppercase; + padding: 12px +} + + .link_to_more_information { + background-color: var(--ifm-color-secondary-s1); + color: black; + width: 150px; + height: 24px; + font-size: 14px; + font-family: var(--ifm-font-family-roboto); + display: flex; + align-items: center; + justify-content: center; + margin: 12px 0 0 0; + font-family: var(--ifm-font-family-roboto); + border-radius: 35px; + font-style: normal; + font-weight: 600; + line-height: 150%; + letter-spacing: -0.176px; + border: none; + text-align: center; + } + +@media only screen and (max-width: 500px) { + /*Mobile*/ + .category_header { + font-size: 20px; +} +ul { + display: flex; + justify-content: center; +} +.main_area_desktop { +display: none +} + +.menu_sidebar { + display: none +} + +.small_project_card { + width: 90vw; + margin: var(--ifm-spacing-2xl) 0; + border: 1px solid #ccc; + cursor: pointer; + padding: 18px; +} + +.large_project_card { + width: 90vw; + padding: 40px; + overflow-y: auto; + border-radius: 8px; + padding: var(--ifm-spacing-xl) var(--ifm-spacing-xl); +} + + +.small_input { + width: 300px; + height: 56px; + border-radius: 4px; + } + + .large_input { + width: 300px; + height: 160px; + border-radius: 4px; + } +} + +@media (min-width: 500px) and (max-width: 996px) { + /*Tablet*/ + + .small_project_card { + width: 80vw; + margin: var(--ifm-spacing-2xl) 0; + border: 1px solid #ccc; + cursor: pointer; +} + .large_project_card { + width: 80vw; + padding: 40px; + overflow-y: auto; + border-radius: 8px; + padding: var(--ifm-spacing-xl) var(--ifm-spacing-xl); +} +.main_area_desktop { +display: none +} + +.menu_sidebar { + display: none +} + +} + +@media only screen and (min-width: 996px) { + /*Desktop*/ + .category_header { + font-size: 28px; +} +.small_project_card { + width: 920px; + margin: var(--ifm-spacing-2xl) 0; + border: 1px solid #ccc; + cursor: pointer; +} + +.large_project_card { + width: 1000px; + height: 900px; + padding: 40px; + overflow-y: auto; + border-radius: 8px; +} +.main_area_mobile { + display: none; +} +.small_input { + width: 508px; + height: 56px; + border-radius: 4px; + } + + .large_input { + width: 508px; + height: 160px; + border-radius: 4px; + } + .send_button_container { + height: 59px; + width: 508px; + margin: var(--ifm-spacing-xl) 0; + } + +} \ No newline at end of file diff --git a/src/css/custom.css b/src/css/custom.css index 79a3da9e2..05b290b90 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,19 @@ a.menu__link:active { background-color: white; } +.fundable_projects { + background-color: var(--ifm-color-secondary-s1); + color: black; + border-radius: 4px; + font-style: normal; + margin: var(--ifm-navbar-item-padding-vertical) 20px; +} + +.fundable_projects:hover { + background-color: var(--ifm-color-primary-p0); +} + + .custom_navbar_item { font-family: var(--ifm-font-family-roboto); width: 117px; @@ -688,3 +703,9 @@ ul.row { .items-list { list-style-type: none; } +.custom-progress-bar::-webkit-progress-value { + background-color: var(--ifm-color-primary-p1); +} +.custom-progress-bar::-webkit-progress-bar { + background-color: #eee; +} 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 ( + + +