diff --git a/.gitignore b/.gitignore index 1beaf077f..9b98fff93 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ npm-shrinkwrap.json # Misc .DS_Store +.env .env.local .env.development.local .env.test.local diff --git a/docusaurus.config.js b/docusaurus.config.js index 2b3a7765b..3aaa5fb87 100644 --- a/docusaurus.config.js +++ b/docusaurus.config.js @@ -1,3 +1,4 @@ +require('dotenv').config() const lightCodeTheme = require('prism-react-renderer/themes/github'); const darkCodeTheme = require('prism-react-renderer/themes/dracula'); const year = new Date().getFullYear(); @@ -14,10 +15,10 @@ module.exports = { projectName: "c4gt", themeConfig: { navbar: { - title: "Home", + // title: "DMP", logo: { - alt: "Home", - src: "img/logo.png", + alt: "DMP", + src: "img/C4GT_Logo_Text.png", }, items: [ { @@ -220,6 +221,21 @@ module.exports = { }, ], + }, + { + label: "2024", + position: "left", + to: "/docs/2024/", + items: [ + { + label: "VedantKhairnar", + to: "/docs/2024/org?id=VedantKhairnar", + }, + { + label: "AbhimanyuSamagra", + to: "/docs/2024/org?id=AbhimanyuSamagra", + }, + ] } ], }, @@ -285,4 +301,8 @@ module.exports = { }, ], ], + customFields: { + API_BASE_URL: process.env.API_BASE_URL, // Assuming you have REACT_APP_API_URL set in your environment + API_AUTH_KEY: process.env.API_AUTH_KEY, + }, }; diff --git a/package-lock.json b/package-lock.json index e755f63b2..7c2c2bb73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,9 @@ "react-scripts": "5.0.0", "url-loader": "^4.1.1", "yarn": "^1.22.19" + }, + "devDependencies": { + "dotenv": "^16.4.5" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -12193,11 +12196,15 @@ } }, "node_modules/dotenv": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", - "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "dev": true, "engines": { - "node": ">=10" + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" } }, "node_modules/dotenv-expand": { @@ -24193,6 +24200,14 @@ } } }, + "node_modules/react-scripts/node_modules/dotenv": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", + "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==", + "engines": { + "node": ">=10" + } + }, "node_modules/react-textarea-autosize": { "version": "8.5.3", "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.3.tgz", diff --git a/package.json b/package.json index 215d9402b..422b268db 100644 --- a/package.json +++ b/package.json @@ -41,5 +41,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "dotenv": "^16.4.5" } } diff --git a/src/components/C4GT2024Page.js b/src/components/C4GT2024Page.js new file mode 100644 index 000000000..4d1e9c7d5 --- /dev/null +++ b/src/components/C4GT2024Page.js @@ -0,0 +1,69 @@ +import React from "react"; + +function C4GT2024Page() { + return ( +
+
+
+
+
+ +
+
+

C4GT'24

+
+

+ C4GT Mentoring Program has been conceptualized as a summer + coding program to create a close-knit community that can build + and contribute to global digital public goods. +

+
    +
  • + An opportunity for college students and working + professionals in India to experience the GovTech space +
  • +
  • Organized annually over 2 months (July-August)
  • +
  • + There will be a set of diverse and engaging GovTech problem + statements every year for the participants to work on +
  • +
  • + Shortlisted contributors will receive mentorship from + leading practitioners in GovTech ecosystem +
  • +
+

Thanks for being part of the community. 💚

+
+
+
+
+
+
+ ); +} + +export default C4GT2024Page; diff --git a/src/components/ProjectDescription.js b/src/components/ProjectDescription.js new file mode 100644 index 000000000..8c36a67eb --- /dev/null +++ b/src/components/ProjectDescription.js @@ -0,0 +1,138 @@ +import React, { useEffect, useState } from "react"; +import { useHistory } from "react-router-dom"; +import useParseMarkdown from "../hooks/useParseMarkdown"; + +function ProjectDescription({ + currentIssue, + currentIssueData, + setCurrentTab, + setSelectedProject, + setIssueNumber, + error, + setError +}) { + const history = useHistory(); + const {API_AUTH_KEY,API_BASE_URL} = useParseMarkdown(); + const [description, setDescription] = useState(null); + const [mobile, setMobile] = useState(false); + + useEffect(() => { + setError(()=>null); + fetch(`${API_BASE_URL}/issues/${currentIssue}`, { + method: "GET", + headers: { + "X-Secret-Key": API_AUTH_KEY, + }, + }) + .then((response) => { + if (!response.ok) { + throw new Error(`Error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + setDescription(() => data); + }) + .catch((error) => { + setError(error); + }); + }, [currentIssue]); + + useEffect(() => { + const handleResize = () => { + if (window.innerWidth < 997) { + setMobile(true); + } else { + setMobile(false); + } + }; + handleResize(); + + window.addEventListener("resize", handleResize); + + return () => { + window.removeEventListener("resize", handleResize); + }; + }, []); + return ( + <> + {!error && ( +
+
+
+
+
+ +
+
+

{description?.name}

+
+

{description?.description}

+ {mobile && ( + <> +

+ Following are the list of Issues associated with the + organization +

+ {currentIssueData?.length != 0 && ( + + )} + + )} +
+
+
+
+
+
+ )} + + ); +} + +export default ProjectDescription; diff --git a/src/components/SubDescription.js b/src/components/SubDescription.js new file mode 100644 index 000000000..354a93d31 --- /dev/null +++ b/src/components/SubDescription.js @@ -0,0 +1,224 @@ +import React, { useEffect, useState } from "react"; +import useParseMarkdown from "../hooks/useParseMarkdown"; + +function SubProjectDescription({ selectedProject, issueNumber, currentIssue,error,setError }) { + const {weeklyGoals, weeklyLearnings,API_AUTH_KEY,API_BASE_URL} = useParseMarkdown(); + const [description, setDescription] = useState(null); + + useEffect(() => { + setError(()=>null); + fetch(`${API_BASE_URL}/issues/${currentIssue}/${issueNumber}`, { + method: "GET", + headers: { + "X-Secret-Key": API_AUTH_KEY, + }, + }) + .then((response) => { + if (!response.ok) { + throw new Error(`Error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + setDescription(() => data); + }) + .catch((error) => { + setError(()=>error) + }); + }, [selectedProject]); + + return (<> + {!error &&
+ {description && ( +
+ +
+
+
+
+
+

{selectedProject}

+
+
+ + + +
+
+ {description?.description && ( + <> +

Overview

+

{description?.description}

+ + )} +
+
+ {description?.overall_progress != null && ( + <> +
+
+ {description?.overall_progress > 0 + ? description?.overall_progress + "%" + : ""} +
+
+ + )} + + {description?.contributor_name && ( + + + + + )} + {description?.mentor_name?.length != 0 && ( + <> + + + + + {description?.mentor_name?.length > 1 && ( + <> + {description?.mentor_name?.map((d, i) => { + if (i != 0) { + return ( + + + + ); + } else return <>; + })} + + )} + + )} + {description?.org_name && ( + + + + + )} +
Contributor Name + + {description?.contributor_name} + +
+ Mentor Name + + + {description?.mentor_name[0]} + +
+ + {d} + +
Org Name + + {description?.org_name} + +
+
+
+
+ {description?.weekly_goals_html && ( +
+ )} +
+
+ {description?.weekly_learnings_html && ( +
+ )} +
+

Overall Project PR Table

+ + + + + + + + + + + {description?.pr_details?.map((tdata, i) => { + return ( + + + + + + + ); + })} + +
WeekPR NameLinkStatus
{tdata.week}{tdata.name} + + {tdata.link} + + {tdata.status}
+
+
+ )} +
} + ); +} + +export default SubProjectDescription; diff --git a/src/css/custom.css b/src/css/custom.css index 6bbb300c4..86f6fc9dd 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -15,3 +15,38 @@ margin: 0 calc(-1 * var(--ifm-pre-padding)); padding: 0 var(--ifm-pre-padding); } + + + +@media screen and (max-width: 966px) { + .menu__link--active, .menu__link--active:hover { + color: #1c1e21 !important; + } + .menu__link--active { + background: #ffffff !important; + } +} + +.dropdown__link--active, .dropdown__link--active:hover { + color: #1c1e21; +} +.dropdown__link--active { + background-color: #ffffff; +} + +.progress-bar-container { + width: 100%; + background-color: #e0e0df; + border-radius: 25px; + overflow: hidden; + margin: 20px 0; +} + +.progress-bar { + height: 25px; + background-color: #7DF774; + text-align: center; + line-height: 25px; + color: #1c1e21; + border-radius: 25px 0 0 25px; +} diff --git a/src/hooks/useParseMarkdown.js b/src/hooks/useParseMarkdown.js new file mode 100644 index 000000000..e4c5ad255 --- /dev/null +++ b/src/hooks/useParseMarkdown.js @@ -0,0 +1,72 @@ +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; + +function useParseMarkdown() { + const { siteConfig } = useDocusaurusContext(); + const API_BASE_URL = siteConfig.customFields.API_BASE_URL; + const API_AUTH_KEY = siteConfig.customFields.API_AUTH_KEY; + + const weeklyGoals = (markdown) => { + markdown = markdown.replace(/^### (.*$)/gim, "

$1

"); + markdown = markdown.replace(/^## (.*$)/gim, `

$1

`); + markdown = markdown.replace(/^# (.*$)/gim, `

$1

`); + + markdown = markdown.replace(/\*\*(.*)\*\*/gim, "$1"); + markdown = markdown.replace(/\*(.*)\*/gim, "$1"); + + markdown = markdown.replace( + /- \[ \] (.*$)/gim, + ' $1', + ); + markdown = markdown.replace( + /- \[x\] (.*$)/gim, + ' $1', + ); + + markdown = markdown.replace(/^\s*-\s+(.*$)/gim, "
  • $1
  • "); + markdown = markdown.replace(/(
  • .*<\/li>)/gim, ""); + + markdown = markdown.replace( + /!\[(.*?)\]\((.*?)\)/gim, + "$1", + ); + + markdown = markdown.replace(/\r\n\r\n/g, ""); + markdown = markdown.replace(/(?:\r\n|\r|\n)/g, "
    "); + + return markdown.trim(); + } + const weeklyLearnings = (markdown) => { + markdown = markdown.replace(/^### (.*$)/gim, "

    $1

    "); + markdown = markdown.replace(/^## (.*$)/gim, `

    $1

    `); + markdown = markdown.replace(/^# (.*$)/gim, `

    $1

    `); + + markdown = markdown.replace(/\*\*(.*)\*\*/gim, "$1"); + markdown = markdown.replace(/\*(.*)\*/gim, "$1"); + + markdown = markdown.replace( + /- \[ \] (.*$)/gim, + ' $1', + ); + markdown = markdown.replace( + /- \[x\] (.*$)/gim, + ' $1', + ); + + markdown = markdown.replace(/^\s*-\s+(.*$)/gim, "
  • $1
  • "); + markdown = markdown.replace(/(
  • .*<\/li>)/gim, ""); + + markdown = markdown.replace( + /!\[(.*?)\]\((.*?)\)/gim, + "$1", + ); + + markdown = markdown.replace(/\r\n\r\n/g, ""); + markdown = markdown.replace(/(?:\r\n|\r|\n)/g, ""); + + return markdown.trim(); + } + + return { weeklyGoals, weeklyLearnings,API_BASE_URL,API_AUTH_KEY }; + } + + export default useParseMarkdown; \ No newline at end of file diff --git a/src/pages/docs/2024/index.css b/src/pages/docs/2024/index.css new file mode 100644 index 000000000..bb685f8df --- /dev/null +++ b/src/pages/docs/2024/index.css @@ -0,0 +1,84 @@ +.sidebar-container-2024{ + display: none; +} +.main-container{ +display: flex; +width: 100%; +} +.breadcrumbs-items{ +--ifm-breadcrumb-size-multiplier: 0.7 !important; +background: #f5f6f7; +margin-bottom: .4rem; +} +.table-container{ +max-height: calc(100vh - 5.75rem); +overflow-y: auto; +position: sticky; +top: calc(4.75rem); +} +.right-side-table{ +display: flex; +align-items: center; +flex-direction: column; +justify-content: center; +padding-right: 0; +} +.header-layout{ +width: 100%; +display: flex; +justify-content: space-between; +gap: 28px; +} +.h2-font{ +font-size: 32px; +} + +@media screen and (max-width: 779px){ +.header-layout{ + flex-direction: column; +} +} +@media screen and (min-width: 997px) { +.sidebar-container-2024{ + display: block; + width: 300px; + margin-top: calc(-1* 3.75rem); + will-change: width; + clip-path: inset(0px); + border-right: 1px solid #dadde1; + transition: width 200ms ease; + } +.sidebar-styles{ + display: flex; + flex-direction: column; + height: 100%; + max-height: 100vh; + padding-top: 3.75rem; + position: sticky; + top: 0; + transition: opacity 50ms; + width: 300px; +} +.menu_styles{ + flex-grow: 1; + padding: .5rem; +} +.main-container{ + flex-grow: 1; + max-width: calc(100% - 300px); +} +.width{ + max-width: 75% !important; +} +.breadcrumbs-items{ + --ifm-breadcrumb-size-multiplier: 0.8; +} + +.right-side-table{ +padding-right: 0; +} +.fullwidth-table{ + width: 100%; + display: table; +} +} \ No newline at end of file diff --git a/src/pages/docs/2024/index.js b/src/pages/docs/2024/index.js new file mode 100644 index 000000000..57edee8d2 --- /dev/null +++ b/src/pages/docs/2024/index.js @@ -0,0 +1,107 @@ +import React, { useEffect, useState } from "react"; +import Layout from "@theme/Layout"; +import C4GT2024Page from "../../../components/C4GT2024Page"; +import "./index.css"; +import useParseMarkdown from "../../../hooks/useParseMarkdown"; + +function C4GT2024() { + const {API_AUTH_KEY,API_BASE_URL} = useParseMarkdown(); + const [currentTab, setCurrentTab] = useState("c4gt"); + const [issueData, setIssueData] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + setError(()=>null); + fetch(`${API_BASE_URL}/issues`, { + method: "GET", + headers: { + "X-Secret-Key": API_AUTH_KEY, + }, + }) + .then((response) => { + if (!response.ok) { + throw new Error(`Error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + setIssueData(() => data); + }) + .catch((error) => { + setError(() => error); + }); + }, []); + + return (<> + {error ? ( +

    Oops, something went wrong

    +

    {error.message}

    +
    + ) : ( + +
    +
    + +
    + {currentTab == "c4gt" ? : <>} +
    +
    +
    +
    )} + + ); +} +export default C4GT2024; diff --git a/src/pages/docs/2024/org/index.js b/src/pages/docs/2024/org/index.js new file mode 100644 index 000000000..63fecb012 --- /dev/null +++ b/src/pages/docs/2024/org/index.js @@ -0,0 +1,201 @@ +import React, { useEffect, useState } from "react"; +import Layout from "@theme/Layout"; +import ProjectDescription from "../../../../components/ProjectDescription"; +import SubProjectDescription from "../../../../components/SubDescription"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import "../index.css"; +import { useHistory, useLocation } from "react-router-dom"; +import useParseMarkdown from "../../../../hooks/useParseMarkdown"; + +function C4GT2024() { + const location = useLocation(); + const history = useHistory(); + const {API_AUTH_KEY,API_BASE_URL} = useParseMarkdown(); + const [currentTab, setCurrentTab] = useState("description"); + const [currentIssue, setCurrentIssue] = useState(null); + const [currentIssueData, setCurrentIssueData] = useState(null); + const [issueData, setIssueData] = useState(null); + const [selectedProject, setSelectedProject] = useState(null); + const [issueNumber, setIssueNumber] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + const queryString = location.search; + const urlParams = new URLSearchParams(queryString); + const product = urlParams.get("id") ? urlParams.get("id") : "c4gt"; + setSelectedProject(() => + urlParams.get("issue") ? urlParams.get("issue") : null, + ); + const newUrl = `/docs/2024/org?id=${product}`; + history.push(newUrl); + setCurrentIssue(() => product); + setError(()=>null); + fetch(`${API_BASE_URL}/issues`, { + method: "GET", + headers: { + "X-Secret-Key": API_AUTH_KEY, + }, + }) + .then((response) => { + if (!response.ok) { + throw new Error(`Error! status: ${response.status}`); + } + return response.json(); + }) + .then((data) => { + setIssueData(() => data); + }) + .catch((error) => { + setError(()=>error); + }); + }, []); + + useEffect(() => { + const queryString = location.search; + const urlParams = new URLSearchParams(queryString); + const product = urlParams.get("id") ? urlParams.get("id") : "c4gt"; + setCurrentIssue(() => product); + }, [location]); + + return (<> + {error ? ( +

    Oops, something went wrong

    +

    {error.message}

    +
    + ) : ( + +
    +
    + +
    + {currentTab == "description" && currentIssue != null ? ( + + ) : ( + <> + )} + {currentTab == "subDescription" && selectedProject != null ? ( + + ) : ( + <> + )} +
    +
    +
    +
    )} + + ); +} +export default C4GT2024; diff --git a/static/img/C4GT_Logo_Text.png b/static/img/C4GT_Logo_Text.png new file mode 100644 index 000000000..2bf3e5e9e Binary files /dev/null and b/static/img/C4GT_Logo_Text.png differ diff --git a/static/img/link_icon.svg b/static/img/link_icon.svg new file mode 100644 index 000000000..69c27ae82 --- /dev/null +++ b/static/img/link_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file