Coder Social home page Coder Social logo

kossiitkgp / kwoc-frontend Goto Github PK

View Code? Open in Web Editor NEW
21.0 20.0 39.0 23.7 MB

Frontend Repo for Kharagpur Winter of Code, built in React

Home Page: https://kwoc.kossiitkgp.org/

License: GNU General Public License v3.0

JavaScript 1.18% HTML 1.29% CSS 0.63% TypeScript 96.90%
hacktoberfest reactjs

kwoc-frontend's Introduction


KWoC Logo

KWoC Frontend

The truth redefined, once again.
Get Started »
Kharagpur Winter of Code · Backend

Table of Contents

(back to top)

Development

See also Contributing Guide, Learning Guide.

Setting Up Locally

  • Install NodeJS.
  • Install or enable PNPM.
  • Clone this repository.
  • Run pnpm install in the cloned repository to download all dependencies.
  • Run pnpm start to start a local development server.
  • Optionally set up KWoC Backend locally.

(back to top)

Project Structure

File Structure

.
├── public
└── src
   ├── assets
   ├── components
   ├── data
   ├── hooks
   ├── styles
   ├── utils
   ├── constants.ts
   └── App.tsx
  • public: Contains public files such as index.html.
  • src: Contains source files (JS, SCSS, assets, etc.)
    • assets: Contains assets used in the source, such as images and icons.
    • components: Contains reusable react components.
    • data: Contains raw data.
    • styles: Contains all stylesheets (SCSS).
    • utils: Contains commonly used util functions.
    • pages: Contains views for each of the pages.
    • constants.ts: Contains globally used constants.
    • App.tsx: Contains the top-level App component.

Libraries/Frameworks Used

(back to top)

Archival

See also KWoC Docs.

After KWoC ends, the website is archived. The stats data (including the total PRs, total commits, total contributors, and individual stats) is copied and added to the site source.

The archived source code is committed to a branch named kwoc-xx-archive and hosted on kwocxx.kossiitkgp.org, where xx represents the last two digits of the year. The archive is also hosted on kwoc.kossiitkgp.org until the following year's website is deployed.

The development for the next KWoC website continues in the default branch.

WARNING DO NOT COMMIT ANY PERSONAL DATA TO THE ARCHIVE.

(back to top)

Acknowledgments

(back to top)


Please update this documentation whenever changes are made to this project or any other relevant project that may affect this one. Future humans will praise you.

kwoc-frontend's People

Contributors

aksahmitr avatar alph3ga avatar aniketpathak028 avatar asmitdeb avatar chirag-ghosh avatar dependabot-preview[bot] avatar gautamraj-12 avatar grapheo12 avatar harshkhandeparkar avatar iamananya avatar jaimin25 avatar koss-service avatar mendacium-a11y avatar nafisay avatar parth-paradkar avatar rajivharlalka avatar rakaar avatar rohan-b-84 avatar sachdevjai avatar sadat3332 avatar sahil-shubham avatar samar-1601 avatar sangeet259 avatar souvik34 avatar swaraj-42 avatar utsavmehta19 avatar xypnox avatar yashrsharma44 avatar yoganshsharma avatar zetabug avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kwoc-frontend's Issues

write it

write it

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/887824c2409d7564bbced53b13b1a752a1da59ed/src/views/ProjectEditFom.js#L75

import axios from "axios";
import React, { useEffect, useState } from "react";
import Select from "react-select";
import CreatableSelect from "react-select/creatable";
import ReactTooltip from "react-tooltip";
import InfoIcon from "../assets/info.svg";
import { BACKEND_URL } from "../constants";
import Tags from "../data/tags.js";

const options = Tags.map((item) => {
  return { value: item, label: item };
});

export default function ProjectEditForm() {
  const [name, setName] = useState("");
  const [desc, setDesc] = useState("");
  const [tags, setTags] = useState([]);
  const [branch, setBranch] = useState("");
  const [readme, setReadme] = useState("");

  const [branchOpts, setBranchOpts] = useState([]);

  useEffect(() => {
    // TODO - this should be done better
    // check if mentor is logged in
    if (
      localStorage.getItem("mentor_jwt") === null ||
      localStorage.getItem("mentor_jwt") === undefined
    )
      window.history.push("/");

    const window_url_split = window.location.href.split("/");
    const project_id = window_url_split[window_url_split.length - 1];
    console.log("project id is ", project_id);
    const data = {
      id: project_id,
    };
    // TODO Fetch existing details from the project
    const PROJECT_DETAILS_ENDPOINT = `${BACKEND_URL}/project/details`;
    console.log("sending request to ", PROJECT_DETAILS_ENDPOINT);
    fetch(PROJECT_DETAILS_ENDPOINT, {
      method: "POST",
      headers: {
        Bearer: localStorage.getItem("mentor_jwt"),
      },
      body: JSON.stringify(data),
    })
      .then((res) => res.json())
      .then((res) => {
        if (res.status === 200) {
          console.log("project detials i got from bckend ,", res);
        } else {
          alert("Cannot Edit form. Please login from your mentor ID");
        }
      })
      .catch((err) => {
        alert("Server Error Try again");
        console.log(err);
      });
  }, []);

  function handleChangeTagsField(tags, action) {
    const selectedTags = tags.map((item) => item.value);
    setTags(selectedTags);
  }

  function handleChangeBranchField(tag, action) {
    if (tag !== null) {
      const selectedBranch = tag.value;
      setBranch(selectedBranch);
    }
  }

  async function refetchREADME(repo) {
    // TODO write it
    return "todo";
  }

  async function showBranchField(repo) {
    const endpoint = `https://api.github.com/repos/${repo}/branches`;
    const res = await axios.get(endpoint);
    const branches_opts = res.data.map((item) => {
      return { value: item["name"], label: item["name"] };
    });
    setBranchOpts(branches_opts);
    // TODO based on response this should be set.
    // setBranch(branches_opts[0]["value"]); // setting the first as the default selected branch
  }

  return (
    <div className="box">
      <div className="field">
        <label className="label">Project Name</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Description</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={desc}
            onChange={(e) => setDesc(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Tags for the project</label>
        <div className="control">
          <CreatableSelect
            isMulti
            isClearable
            onChange={handleChangeTagsField}
            options={options}
            defaultValue={tags}
            placeholder="Select or Create Tags"
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Select Branch for stats</label>
        <img
          alt=""
          src={InfoIcon}
          data-tip={`We put up a stats board for encouragement, by fetching the contribution data of all students using Github API. 
         <br/>Please select the branch on which students should be contributing. 
         <br/> We will be fetching the contributions data from the branch you have specified. 
         <br/> You can also change the branch in middle of KWoC`}
        />
        <ReactTooltip place="bottom" type="info" effect="float" html />
        <Select
          isClearable
          isSearchable
          onChange={handleChangeBranchField}
          options={branchOpts}
          //   defaultValue={branchOpts[0]}
          placeholder="Select Branch"
        />
      </div>

      <div>
        <a
          className="button is-rounded is-fullWidth column is-full"
          onClick={refetchREADME}
        >
          Re-Fetch README
        </a>
      </div>
    </div>
  );
}

22ab43a685dfd95a947c21fda228834b187f8758

test things by changing redirect uri

test things by changing redirect uri

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/121a45e5adf55fb809955519722d0880043140cb/src/components/OAuth.js#L14

import React, { useEffect } from "react";
import { useAuth } from "../hooks/Auth";

function OAuth() {
  let auth = useAuth();

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const data = {
      code: params.get("code"),
      state: params.get("state"),
    };

    // TODO: test things by changing redirect uri
    auth.login(
      data,
      () => {
        // TODO: use react-hot-toast for login, announcement etc. notifs
        console.log("succex");
      },
      (e) => {
        console.log(e);
        alert("Server Error! Please try again");
      }
    );

    // DOUBT(@rakaar): what is the need for this?
    // if (!res["isNewUser"]) props.history.push("/dashboard/mentor");
  }, []);

  return (

4ec0981b150aedd9151533fda9dd33cf6af60144

Cannot run project setup

I have windows 10 and I am using npm to setup project in my laptop but I am getting error after npm start.
Can anyone tell steps after cloning the repo to run? I have followed - npm install and then npm start.

Allow an option to Edit detail Project form details

There should be an option to edit the following fields during the middle of KWoC

  • Name
  • Description
  • Tags
  • Branch
  • Re Fetch README: It is possible that the mentor might have updated the README after submitting the project for KWoC. A button like Re-fetch README should fetch README again from the specified branch and replace the existing README

There should be an edit details button for each project, on clicking the button, a form showing prefilled details should be shown allowing the user to edit the details and click on the Update button.

Fetch README data after filling the project Link

This time we plan to show the README content in the projects page of KWoC as a modal,so that people can know more about the project without having to change the page. For the fetch the README content after the project link is filled
Example - https://api.github.com/repos/facebook/react/contents/README.md

NOTE: A request to the repo endpoint is already made to check the number of issues and README size and other things, in that request only you can perform the above action

ALSO, make sure to fetch the README from the branch mentioned in the project form rather than from the default branch. The branch can be changed by add the parameter ref=BRANCH_NAME like https://api.github.com/repos/facebook/react/contents/README.md?ref=master

FAQ markdown render and search

Required

Before #79 we used to render the markdown file present in the public folder, but we wanted to search through the faq so that one can easily search their doubt. This required a json data with key and value pair or question and answer. We should aim to have both markdown rendering and search together.

Possible Solution

?

Mentor Dashboard Changes

  • Link to stats page for each individual project of the mentor

  • Announcements on the top:- Last time Announcements were buried at the bottom, let's keep such an important thing on the top

  • Link for Resources rather than complete resources:- We can have a separate page for Student resources and Mentor resources and Just link the button to it in the Dashboard, as they occupy a lot of places (TO BE DISCUSSED)

  • KWoC slack invite link so that the doubts can be resolved easily. Discussions on Slack are easy and convenient!

More suggestions and ideas are welcome!

You are welcome to send Pull Requests for individual Tasks too! 😺

Decide whether we would be using this or not, and please better function name _/...

Decide whether we would be using this or not, and please better function name _/_

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/8560b60c93b35b7ee77e0eee7039944db0233df0/src/components/Part.js#L4

import React from "react";
import Particles from "react-particles-js";

// TODO: Decide whether we would be using this or not, and please better function name _/\_
export default function Part() {
  return (
    <Particles

d212558bce66b578cc88314a1754018ca37c8a26

Re-naming, Re-moving and Removing files

  • For Student Dashboard, there are 2 JS files, Old and New. The New one is being used. Remove the old file and the corresponding CSS file associated with it.

  • Rename the NewStudentDashboard as Student Dashboard and change things accordingly in App.js and other imports, if they exist

In src, some of the files can be categorised(putting them in proper folders for easy access)

  • Putting ProjectForm.js in form folder and change the imports accordingly and also in App.js

  • src/colleges.js can be removed, as it not being used

  • src/Card.js can be removed if it is not being used

If u find any other improvements for code structure, feel free to include in the PR

Add custom auth hooks

Required

Add custom auth hooks to handle the following:

  • registration
  • getting user info (mentor and student)
  • user logging

Shuffle!

We plan to shuffle the projects and stats. Make a separate file named shuffle.js, which includes a function shuffleArray, which takes 2 parameters

  1. Array - the array that needs to be shuffled
  2. n - size of club
    Returns the shuffled array

While shuffling we want a set of things to be together. For example, for projects, while shuffling we shuffle clubs, where each club is a collection of 3 projects. For example in set of projects [p1, p2,p3,p4,p5,p6,p7,p8,p9] when shuffled p1,p2,p3 stay together, p4,p5,p6 stay together , p7,p8,p9 stay together.

You may refer - https://github.com/kossiitkgp/KWoC-21-Frontend/blob/master/src/components/projects/Projects.js#L24

Once the shuffle function is made

  1. Remove the shuffling logic in the function Project.js and import the new shuffle function from shuffle.js and use it. Keep club size as 3.
  2. Import the same shuffle function in this file - https://github.com/kossiitkgp/KWoC-21-Frontend/blob/master/src/components/tables/StudentsTable/StudentsTable.js#L178. And shuffle the rows of a single page, keeping club size 1

Student Dashboard changes

In the student Dashboard, let's make changes such that more important things are accessible via Dashboard

  • Link to Stats page rather than whole Stats:- Detailed stats of a student are already provided in the route /stats/student/USERNAME, keeping the same thing again on the Dashboard seems unnecessary. Instead we can just show the Commits Count, PRs count, Lines of Code count and provide a link which redirects to the detailed stats page.
  • Announcements on the top:- Last time Announcements were buried at the bottom, lets keep such an important thing on the top
  • Link for Resources rather than complete resources:- We can have a separate page for Student resources and Mentor resources and Just link the button to it in the Dashboard, as they occupy a lot of place(TO BE DISCUSSED)
  • KWoC slack invite link so that the student's doubts can be resolved easily. Discussions on Slack are easy and convenient!

More suggestions and ideas are welcome!
You are welcome to send Pull Requests for individual Tasks too! 😺

based on response this should be set.

based on response this should be set.

setBranch(branches_opts[0]["value"]); // setting the first as the default selected branch

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/887824c2409d7564bbced53b13b1a752a1da59ed/src/views/ProjectEditFom.js#L86

import axios from "axios";
import React, { useEffect, useState } from "react";
import Select from "react-select";
import CreatableSelect from "react-select/creatable";
import ReactTooltip from "react-tooltip";
import InfoIcon from "../assets/info.svg";
import { BACKEND_URL } from "../constants";
import Tags from "../data/tags.js";

const options = Tags.map((item) => {
  return { value: item, label: item };
});

export default function ProjectEditForm() {
  const [name, setName] = useState("");
  const [desc, setDesc] = useState("");
  const [tags, setTags] = useState([]);
  const [branch, setBranch] = useState("");
  const [readme, setReadme] = useState("");

  const [branchOpts, setBranchOpts] = useState([]);

  useEffect(() => {
    // TODO - this should be done better
    // check if mentor is logged in
    if (
      localStorage.getItem("mentor_jwt") === null ||
      localStorage.getItem("mentor_jwt") === undefined
    )
      window.history.push("/");

    const window_url_split = window.location.href.split("/");
    const project_id = window_url_split[window_url_split.length - 1];
    console.log("project id is ", project_id);
    const data = {
      id: project_id,
    };
    // TODO Fetch existing details from the project
    const PROJECT_DETAILS_ENDPOINT = `${BACKEND_URL}/project/details`;
    console.log("sending request to ", PROJECT_DETAILS_ENDPOINT);
    fetch(PROJECT_DETAILS_ENDPOINT, {
      method: "POST",
      headers: {
        Bearer: localStorage.getItem("mentor_jwt"),
      },
      body: JSON.stringify(data),
    })
      .then((res) => res.json())
      .then((res) => {
        if (res.status === 200) {
          console.log("project detials i got from bckend ,", res);
        } else {
          alert("Cannot Edit form. Please login from your mentor ID");
        }
      })
      .catch((err) => {
        alert("Server Error Try again");
        console.log(err);
      });
  }, []);

  function handleChangeTagsField(tags, action) {
    const selectedTags = tags.map((item) => item.value);
    setTags(selectedTags);
  }

  function handleChangeBranchField(tag, action) {
    if (tag !== null) {
      const selectedBranch = tag.value;
      setBranch(selectedBranch);
    }
  }

  async function refetchREADME(repo) {
    // TODO write it
    return "todo";
  }

  async function showBranchField(repo) {
    const endpoint = `https://api.github.com/repos/${repo}/branches`;
    const res = await axios.get(endpoint);
    const branches_opts = res.data.map((item) => {
      return { value: item["name"], label: item["name"] };
    });
    setBranchOpts(branches_opts);
    // TODO based on response this should be set.
    // setBranch(branches_opts[0]["value"]); // setting the first as the default selected branch
  }

  return (
    <div className="box">
      <div className="field">
        <label className="label">Project Name</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Description</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={desc}
            onChange={(e) => setDesc(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Tags for the project</label>
        <div className="control">
          <CreatableSelect
            isMulti
            isClearable
            onChange={handleChangeTagsField}
            options={options}
            defaultValue={tags}
            placeholder="Select or Create Tags"
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Select Branch for stats</label>
        <img
          alt=""
          src={InfoIcon}
          data-tip={`We put up a stats board for encouragement, by fetching the contribution data of all students using Github API. 
         <br/>Please select the branch on which students should be contributing. 
         <br/> We will be fetching the contributions data from the branch you have specified. 
         <br/> You can also change the branch in middle of KWoC`}
        />
        <ReactTooltip place="bottom" type="info" effect="float" html />
        <Select
          isClearable
          isSearchable
          onChange={handleChangeBranchField}
          options={branchOpts}
          //   defaultValue={branchOpts[0]}
          placeholder="Select Branch"
        />
      </div>

      <div>
        <a
          className="button is-rounded is-fullWidth column is-full"
          onClick={refetchREADME}
        >
          Re-Fetch README
        </a>
      </div>
    </div>
  );
}

ed3adaeb59d192f2f5d149da8473c51e95ec61f3

- this should be done better

  • this should be done better

check if mentor is logged in

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/887824c2409d7564bbced53b13b1a752a1da59ed/src/views/ProjectEditFom.js#L24

import axios from "axios";
import React, { useEffect, useState } from "react";
import Select from "react-select";
import CreatableSelect from "react-select/creatable";
import ReactTooltip from "react-tooltip";
import InfoIcon from "../assets/info.svg";
import { BACKEND_URL } from "../constants";
import Tags from "../data/tags.js";

const options = Tags.map((item) => {
  return { value: item, label: item };
});

export default function ProjectEditForm() {
  const [name, setName] = useState("");
  const [desc, setDesc] = useState("");
  const [tags, setTags] = useState([]);
  const [branch, setBranch] = useState("");
  const [readme, setReadme] = useState("");

  const [branchOpts, setBranchOpts] = useState([]);

  useEffect(() => {
    // TODO - this should be done better
    // check if mentor is logged in
    if (
      localStorage.getItem("mentor_jwt") === null ||
      localStorage.getItem("mentor_jwt") === undefined
    )
      window.history.push("/");

    const window_url_split = window.location.href.split("/");
    const project_id = window_url_split[window_url_split.length - 1];
    console.log("project id is ", project_id);
    const data = {
      id: project_id,
    };
    // TODO Fetch existing details from the project
    const PROJECT_DETAILS_ENDPOINT = `${BACKEND_URL}/project/details`;
    console.log("sending request to ", PROJECT_DETAILS_ENDPOINT);
    fetch(PROJECT_DETAILS_ENDPOINT, {
      method: "POST",
      headers: {
        Bearer: localStorage.getItem("mentor_jwt"),
      },
      body: JSON.stringify(data),
    })
      .then((res) => res.json())
      .then((res) => {
        if (res.status === 200) {
          console.log("project detials i got from bckend ,", res);
        } else {
          alert("Cannot Edit form. Please login from your mentor ID");
        }
      })
      .catch((err) => {
        alert("Server Error Try again");
        console.log(err);
      });
  }, []);

  function handleChangeTagsField(tags, action) {
    const selectedTags = tags.map((item) => item.value);
    setTags(selectedTags);
  }

  function handleChangeBranchField(tag, action) {
    if (tag !== null) {
      const selectedBranch = tag.value;
      setBranch(selectedBranch);
    }
  }

  async function refetchREADME(repo) {
    // TODO write it
    return "todo";
  }

  async function showBranchField(repo) {
    const endpoint = `https://api.github.com/repos/${repo}/branches`;
    const res = await axios.get(endpoint);
    const branches_opts = res.data.map((item) => {
      return { value: item["name"], label: item["name"] };
    });
    setBranchOpts(branches_opts);
    // TODO based on response this should be set.
    // setBranch(branches_opts[0]["value"]); // setting the first as the default selected branch
  }

  return (
    <div className="box">
      <div className="field">
        <label className="label">Project Name</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Description</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={desc}
            onChange={(e) => setDesc(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Tags for the project</label>
        <div className="control">
          <CreatableSelect
            isMulti
            isClearable
            onChange={handleChangeTagsField}
            options={options}
            defaultValue={tags}
            placeholder="Select or Create Tags"
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Select Branch for stats</label>
        <img
          alt=""
          src={InfoIcon}
          data-tip={`We put up a stats board for encouragement, by fetching the contribution data of all students using Github API. 
         <br/>Please select the branch on which students should be contributing. 
         <br/> We will be fetching the contributions data from the branch you have specified. 
         <br/> You can also change the branch in middle of KWoC`}
        />
        <ReactTooltip place="bottom" type="info" effect="float" html />
        <Select
          isClearable
          isSearchable
          onChange={handleChangeBranchField}
          options={branchOpts}
          //   defaultValue={branchOpts[0]}
          placeholder="Select Branch"
        />
      </div>

      <div>
        <a
          className="button is-rounded is-fullWidth column is-full"
          onClick={refetchREADME}
        >
          Re-Fetch README
        </a>
      </div>
    </div>
  );
}

8913ac54847b7265d28bebc3deffa10caddb5abd

[@sahil-shubham] make custom auth hooks for user operations

make custom auth hooks for user operations

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/8560b60c93b35b7ee77e0eee7039944db0233df0/src/components/Navbar.js#L37

import React, { useEffect, useState } from "react";
import logo from "../assets/circle.svg";
import slack from "../assets/slack.svg";

function Navbar() {
  const [isActive, setIsActive] = useState(false);
  const [mentorLoggedIn, setMentorLoggedIn] = useState(false);
  const [studentLoggedIn, setStudentLoggedIn] = useState(false);
  const [isDown_1, setIsDown_1] = useState(false);
  const [isDown_2, setIsDown_2] = useState(false);

  useEffect(() => {
    if (localStorage.getItem("mentor_jwt")) {
      setMentorLoggedIn(true);
    }

    if (localStorage.getItem("student_jwt")) {
      setStudentLoggedIn(true);
    }
  }, []);

  const navbarNikal = () => {
    isActive ? setIsActive(false) : setIsActive(true);
  };

  const dropdownNikal = (n) => {
    switch (n) {
      case 1:
        setIsDown_1(!isDown_1);
        break;
      case 2:
        setIsDown_2(!isDown_2);
        break;
    }
  };

  // TODO(@sahil-shubham): make custom auth hooks for user operations
  const logoutMentor = () => {
    localStorage.removeItem("mentor_jwt");
    localStorage.removeItem("mentor_username");
    window.location.pathname = "";
  };

  const logoutStudent = () => {
    localStorage.removeItem("student_jwt");
    localStorage.removeItem("student_username");
    window.location.pathname = "";
  };

  return (
    <>
      <nav className="menu">
        <div className="wrapper">
          <div className="logo">
            <a href="/">
              <img src={logo} alt="logo" />
            </a>
          </div>

          <ul>
            <li>
              <a href="/#about">About</a>
            </li>

            <li>
              <a href="/projects">Projects</a>
            </li>

            <li>
              <a href="/FAQ">FAQs</a>
            </li>

            <li>
              <a href="/#tline">Timeline</a>
            </li>

            <li>
              <a href="/testimonial">Testimonials</a>
            </li>

            <li>
              <a
                href="https://github.com/kossiitkgp/kwoc-bugs"
                target="_blank"
                rel="noreferrer noopener"
              >
                Bug Report
              </a>
            </li>

            <li className="dropdown-title">
              Stats
              <ul className="dropdown-content">
                <li>
                  <a href="/stats/students">Students</a>
                </li>
                <li>
                  <a href="/stats/projects">Projects</a>
                </li>
              </ul>
            </li>

            <li>
              <a
                href="https://join.slack.com/t/kwoc-koss/shared_invite/zt-wlftnk75-VoQHEEB9WpkHfza6~GGpWQ"
                target="_blank"
                rel="noreferrer noopener"
              >
                <img src={slack} alt="Join us on slack" />
              </a>
            </li>

            <li className="dropdown-title">
              {mentorLoggedIn === true || studentLoggedIn === true
                ? "Manage Account"
                : "Login"}

              <ul className="dropdown-content">
                {mentorLoggedIn !== true ? (
                  <li>
                    <a
                      className="navbar-item"
                      href="https://github.com/login/oauth/authorize?scope=user:email&client_id=74557dcb91016b10b54b&state=mentor"
                    >
                      Mentor Login
                    </a>
                  </li>
                ) : (
                  <>
                    <li>
                      <a className="navbar-item" href="/dashboard/mentor">
                        Mentor Dashboard
                      </a>
                    </li>

                    <li onClick={logoutMentor}>Logout(Mentor)</li>
                  </>
                )}

                {studentLoggedIn !== true ? (
                  <li>
                    <a
                      className="navbar-item"
                      id="mentee-login"
                      href="https://github.com/login/oauth/authorize?scope=user:email&client_id=74557dcb91016b10b54b&state=student"
                    >
                      Student Login
                    </a>
                  </li>
                ) : (
                  <>
                    <li>
                      <a className="navbar-item" href="/dashboard/student">
                        Student Dashboard
                      </a>
                    </li>
                    <li onClick={logoutStudent}>Logout(Student)</li>
                  </>
                )}
              </ul>
            </li>
          </ul>
        </div>
      </nav>

      <div className="mobile-navbar">
        <div
          className={`mobile-navbar-icon ${isActive ? "out" : "nope"}`}
          onClick={navbarNikal}
        >
          <span></span>
          <span></span>
          <span></span>
        </div>

        <div className={`wrapper ${isActive ? "active" : ""}`}>
          <ul>
            <li>
              <a href="/#about">About</a>
            </li>

            <li>
              <a href="/projects">Projects</a>
            </li>

            <li>
              <a href="/FAQ">FAQs</a>
            </li>

            <li>
              <a href="/#tline">Timeline</a>
            </li>

            <li>
              <a href="/testimonial">Testimonials</a>
            </li>

            <li>
              <a
                href="https://github.com/kossiitkgp/kwoc-bugs"
                target="_blank"
                rel="noreferrer noopener"
              >
                Bug Report
              </a>
            </li>

            <li
              className={`dropdown-title ${isDown_1 ? "down" : ""}`}
              onClick={() => dropdownNikal(1)}
            >
              Stats
              <ul className="dropdown-content">
                <li>
                  <a href="/stats/students">Students</a>
                </li>
                <li>
                  <a href="/stats/projects">Projects</a>
                </li>
              </ul>
            </li>

            <li>
              <a
                href="https://join.slack.com/t/kwoc-koss/shared_invite/zt-wlftnk75-VoQHEEB9WpkHfza6~GGpWQ"
                target="_blank"
                rel="noreferrer noopener"
              >
                <img src={slack} alt="Join us on slack" />
              </a>
            </li>

            <li
              className={`dropdown-title ${isDown_2 ? "down" : ""}`}
              onClick={() => dropdownNikal(2)}
            >
              {mentorLoggedIn === true || studentLoggedIn === true
                ? "Manage Account"
                : "Login"}

              <ul className="dropdown-content">
                {mentorLoggedIn !== true ? (
                  <li>
                    <a
                      className="navbar-item"
                      href="https://github.com/login/oauth/authorize?scope=user:email&client_id=74557dcb91016b10b54b&state=mentor"
                    >
                      Mentor Login
                    </a>
                  </li>
                ) : (
                  <>
                    <li>
                      <a className="navbar-item" href="/dashboard/mentor">
                        Mentor Dashboard
                      </a>
                    </li>

                    <li onClick={logoutMentor}>Logout(Mentor)</li>
                  </>
                )}

                {studentLoggedIn !== true ? (
                  <li>
                    <a
                      className="navbar-item"
                      id="mentee-login"
                      href="https://github.com/login/oauth/authorize?scope=user:email&client_id=74557dcb91016b10b54b&state=student"
                    >
                      Student Login
                    </a>
                  </li>
                ) : (
                  <>
                    <li>
                      <a className="navbar-item" href="/dashboard/student">
                        Student Dashboard
                      </a>
                    </li>
                    <li onClick={logoutStudent}>Logout(Student)</li>
                  </>
                )}
              </ul>
            </li>
          </ul>
        </div>
      </div>
    </>
  );
}

export default Navbar;

7f604aa97a59041054c524f7bfc897d321578252

use react-hot-toast for login, announcement etc. notifs

use react-hot-toast for login, announcement etc. notifs

if (!res["isNewUser"]) props.history.push("/dashboard/mentor");

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/121a45e5adf55fb809955519722d0880043140cb/src/components/OAuth.js#L18

import React, { useEffect } from "react";
import { useAuth } from "../hooks/Auth";

function OAuth() {
  let auth = useAuth();

  useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const data = {
      code: params.get("code"),
      state: params.get("state"),
    };

    // TODO: test things by changing redirect uri
    auth.login(
      data,
      () => {
        // TODO: use react-hot-toast for login, announcement etc. notifs
        console.log("succex");
      },
      (e) => {
        console.log(e);
        alert("Server Error! Please try again");
      }
    );

    // DOUBT(@rakaar): what is the need for this?
    // if (!res["isNewUser"]) props.history.push("/dashboard/mentor");
  }, []);

  return (

57d385dd6a908f99d1244e7c86cf23a3901501c6

Get Branch name for stats

Background:-
Every time, we fetch stats from the default branch. But mentors sometimes want their students to work on a different branch during KWoC. Previously, contributions to those branches were ignored, which was a bad thing.
From this year, we can ask the mentors from what branch do they want to fetch stats from. (Later, in the middle of KWoC also we will provide an option to change branch, if they wish to)

To be done:-
So in the project form, after the project link is filled, fetch all the branch names using GitHub API - https://docs.github.com/en/rest/reference/repos#list-branches. After that provide a dropdown that contains list of all branches, so that mentor can select the branch on which Students can work during KWoC.

Also:-
It will be nice if we provide a small piece of information on why we are asking them to select a branch and tell them that the branch can be changed in the middle of KWoC too. Beside the field title of branch, keep a small icon like "i", which on hovered gives the details like...
We put up a stats board for encouragement, by fetching the contribution data of all students using Github API. Please select the branch on which students should be contributing. We will be fetching the contributions data from the branch you have specified. You can also change the branch in middle of KWoC

Don't use URLs directly

Constants like BACKEND_URL, BACKEND_STATS_API, MID_EVAL_DATE and so on should be kept in src/constants/constants.js. But at some places it is used directly for example in MentorDashboard.js, MentorStats.js, the URLs are used directly without importing from constants.js

At such places, remove the hardcoding of the URL and import the URL from constants.js and use it to fetch the requests

[@sahil-shubham] better way of handling multiple user types

better way of handling multiple user types

is_student: response.type === "student" ? "true" : "false",

is_mentor: response.type === "mentor" ? "true" : "false",

jwt: response.jwt,

authHeader,

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/121a45e5adf55fb809955519722d0880043140cb/src/hooks/Auth.js#L83

import axios from "axios";
import React, { createContext, useContext, useState } from "react";
import { useHistory } from "react-router";
import { BACKEND_URL } from "../constants";

const authConnector = {
  isAuthenticated: false,
  // registerUser(data, cb, cbe) {
  //   authConnector.isAuthenticated = true;
  //   axios
  //     .post(`${BACKEND_URL}/oauth`, data)
  //     .then((response) => {
  //       cb(response.data);
  //     })
  //     .catch((error) => cbe(error));
  // },

  login(data, cb, cbe) {
    authConnector.isAuthenticated = true;
    axios
      .post(`${BACKEND_URL}/oauth`, data)
      .then((response) => {
        cb(response);
      })
      .catch((error) => {
        cbe(error);
      });
  },

  signout(cb) {
    authConnector.isAuthenticated = false;
    cb();
  },
};

export const authContext = createContext(null);

function ProvideAuth(props) {
  const auth = useProvideAuth();
  return (
    <authContext.Provider value={auth}> {props.children} </authContext.Provider>
  );
}

function useAuth() {
  return useContext(authContext);
}

function useProvideAuth() {
  const [user, setUser] = useState(getUserFromLocalStorage());
  let history = useHistory();

  // const registerUser = (data, cb, cbe) => {
  //   return authConnector.registerUser(
  //     data,
  //     (user) => {
  //       setUser(user);
  //       localStorage.setItem("user", JSON.stringify(user));
  //       cb();
  //     },
  //     cbe
  //   );
  // };

  // const authHeader = () => {
  //   if (user !== null) {
  //     return {
  //       headers: {
  //         Authorization: `Bearer ${user?.access_token}`,
  //       },
  //     };
  //   }
  // };

  const login = (data, cb, cbe) => {
    return authConnector.login(
      data,
      (response) => {
        let user = {
          username: response.username,
          name: response.name,
          email: response.email,
          // TODO(@sahil-shubham): better way of handling multiple user types
          // is_student: response.type === "student" ? "true" : "false",
          // is_mentor: response.type === "mentor" ? "true" : "false",
          // jwt: response.jwt,
        };

        // this is only till multiple users types gets sorted, after that user.jwt everywhere
        if (response.type === "student") {
          user.student_jwt = response.jwt;
        } else {
          user.mentor_jwt = response.jwt;
        }
        setUser(user);
        localStorage.setItem("user", JSON.stringify(user));

        history.push(`/dashboard/${response.type}`);
        cb();
      },
      cbe
    );
  };

  const signout = (cb) => {
    return authConnector.signout(() => {
      setUser(null);
      localStorage.removeItem("");
      cb();
    });
  };

  return {
    user,
    login,
    // registerUser,
    // authHeader,
    signout,
  };
}

function getUserFromLocalStorage() {
  let userJSON = localStorage.getItem("user");
  if (userJSON) {
    return JSON.parse(userJSON);
  }

  return null;
}

export { ProvideAuth, useAuth };

c97c8bcf3450c5240a35e2eb7987121c6b39a88a

Project Approval status

Background:-
After submitting their project, the project will be shown on the KWoC projects page after the KWoC team has approved the project. After the mentor submits the project, the status of the project approval should be shown on the Mentor Dashboard.

So basically, the status of project approval can be one of the following 2 things:

  1. Green tick: Approved, the project will appear on the KWoC projects page
  2. Mail has been to [email protected] to request more details

Todo:

<p>{item.ProjectStatus ? "" : "To be Checked"}</p>

A better way to display the project status.

Detailed and Searchable FAQ page

We plan to make our FAQs searchable, so that people don't have to go face the trouble of scrolling through the queries.In faq.js file, there is a list of FAQs. Update the FAQs page with a search box and cards

The page may look something like this. While user types the query, the cards containing question and answer showup
Screenshot from 2021-09-26 17-52-22

For search, you may use fuse.js - https://fusejs.io/

Fetch existing details from the project

Fetch existing details from the project

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/887824c2409d7564bbced53b13b1a752a1da59ed/src/views/ProjectEditFom.js#L38

import axios from "axios";
import React, { useEffect, useState } from "react";
import Select from "react-select";
import CreatableSelect from "react-select/creatable";
import ReactTooltip from "react-tooltip";
import InfoIcon from "../assets/info.svg";
import { BACKEND_URL } from "../constants";
import Tags from "../data/tags.js";

const options = Tags.map((item) => {
  return { value: item, label: item };
});

export default function ProjectEditForm() {
  const [name, setName] = useState("");
  const [desc, setDesc] = useState("");
  const [tags, setTags] = useState([]);
  const [branch, setBranch] = useState("");
  const [readme, setReadme] = useState("");

  const [branchOpts, setBranchOpts] = useState([]);

  useEffect(() => {
    // TODO - this should be done better
    // check if mentor is logged in
    if (
      localStorage.getItem("mentor_jwt") === null ||
      localStorage.getItem("mentor_jwt") === undefined
    )
      window.history.push("/");

    const window_url_split = window.location.href.split("/");
    const project_id = window_url_split[window_url_split.length - 1];
    console.log("project id is ", project_id);
    const data = {
      id: project_id,
    };
    // TODO Fetch existing details from the project
    const PROJECT_DETAILS_ENDPOINT = `${BACKEND_URL}/project/details`;
    console.log("sending request to ", PROJECT_DETAILS_ENDPOINT);
    fetch(PROJECT_DETAILS_ENDPOINT, {
      method: "POST",
      headers: {
        Bearer: localStorage.getItem("mentor_jwt"),
      },
      body: JSON.stringify(data),
    })
      .then((res) => res.json())
      .then((res) => {
        if (res.status === 200) {
          console.log("project detials i got from bckend ,", res);
        } else {
          alert("Cannot Edit form. Please login from your mentor ID");
        }
      })
      .catch((err) => {
        alert("Server Error Try again");
        console.log(err);
      });
  }, []);

  function handleChangeTagsField(tags, action) {
    const selectedTags = tags.map((item) => item.value);
    setTags(selectedTags);
  }

  function handleChangeBranchField(tag, action) {
    if (tag !== null) {
      const selectedBranch = tag.value;
      setBranch(selectedBranch);
    }
  }

  async function refetchREADME(repo) {
    // TODO write it
    return "todo";
  }

  async function showBranchField(repo) {
    const endpoint = `https://api.github.com/repos/${repo}/branches`;
    const res = await axios.get(endpoint);
    const branches_opts = res.data.map((item) => {
      return { value: item["name"], label: item["name"] };
    });
    setBranchOpts(branches_opts);
    // TODO based on response this should be set.
    // setBranch(branches_opts[0]["value"]); // setting the first as the default selected branch
  }

  return (
    <div className="box">
      <div className="field">
        <label className="label">Project Name</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={name}
            onChange={(e) => setName(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Description</label>
        <div className="control">
          <input
            className="input is-rounded"
            type="text"
            placeholder="Edit name of your project"
            value={desc}
            onChange={(e) => setDesc(e.target.value)}
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Tags for the project</label>
        <div className="control">
          <CreatableSelect
            isMulti
            isClearable
            onChange={handleChangeTagsField}
            options={options}
            defaultValue={tags}
            placeholder="Select or Create Tags"
          />
        </div>
      </div>

      <div className="field">
        <label className="label">Select Branch for stats</label>
        <img
          alt=""
          src={InfoIcon}
          data-tip={`We put up a stats board for encouragement, by fetching the contribution data of all students using Github API. 
         <br/>Please select the branch on which students should be contributing. 
         <br/> We will be fetching the contributions data from the branch you have specified. 
         <br/> You can also change the branch in middle of KWoC`}
        />
        <ReactTooltip place="bottom" type="info" effect="float" html />
        <Select
          isClearable
          isSearchable
          onChange={handleChangeBranchField}
          options={branchOpts}
          //   defaultValue={branchOpts[0]}
          placeholder="Select Branch"
        />
      </div>

      <div>
        <a
          className="button is-rounded is-fullWidth column is-full"
          onClick={refetchREADME}
        >
          Re-Fetch README
        </a>
      </div>
    </div>
  );
}

3eff96d23fe61407fb9347227b308a892d797481

don't hardcode tokens below

don't hardcode tokens below

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/8560b60c93b35b7ee77e0eee7039944db0233df0/src/utils/helpers.js#L28

// Module for helper methods

function numFormatter(num) {
  if (num > 999 && num < 1000000) {
    return (num / 1000).toFixed(0) + "K"; // convert to K for number from > 1000 < 1 million
  } else if (num > 1000000) {
    return (num / 1000000).toFixed(0) + "M"; // convert to M for number from > 1 million
  } else if (num < 900) {
    return num; // if value < 1000, nothing to do
  }
}

function trim_message(message) {
  if (message)
    if (message.length > 40) return message.trim(0, 40) + "...";
    else return message;
}

function trim_lines(lines) {
  let num_lines = parseInt(lines);
  if (num_lines > 1000) return parseInt(num_lines / 1000).toString() + "K";
  else return lines;
}

function fetch_calls(link) {
  return fetch(link, {
    headers: {
      // TODO: don't hardcode tokens below
      Authorization: "token ",
    },
  })
    .then((res) => res.json())
    .then((res) => {
      return res;
    })
    .catch((err) => {
      return err;
    });
}
export { numFormatter, trim_message, trim_lines, fetch_calls };

e839b8a82e56dfe73d27e28bad891b7c3bbf121e

Add In code TODO to GitHub issues action

Required

  • Adding TODOs while writing code is a great way of keeping track of things or future goals
  • Todo tree extension is good for keeping track of TODOs in Vs code but it would be better if we can convert those into GitHub issues
  • This action seems like something that can be used for the same

Autofill Tags after filling the Project Link

Basic:-
After the project link is filled, make a request to the Github API to the repo endpoint and from that data fetch the topics value, which serves as an array of tags

Advanced:-
You can keep the parameter - include_all_branches set to true in the request as mentioned here to fetch all the file names, and from the file names one can fetch the languages used. Make a unique list by combining the Topics and the languages used.(As sometimes topics and languages might contain common things. Make sure you don't forget case sensitivity)

NOTE: A request to the repo endpoint is already made to check the number of issues and README size, in that request only you can fetch topics.

update stats api to not ask for mentor projects with request

update stats api to not ask for mentor projects with request

fetch(${BACKEND_URL}/stats/mentor, {

body: JSON.stringify({ projects: repoNames }),

})

.then((res) => res.json())

.then((res) => {

console.log("res. is ", res);

});

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/fa6c1f810d6e12451dc5e5ac805c2fdfb4d33434/src/views/MentorDashboard.js#L116

        alert("Server Error, Please try again");
      });

    // TODO: update stats api to not ask for mentor projects with request
    // fetch(`${BACKEND_URL}/stats/mentor`, {
    //   body: JSON.stringify({ projects: repoNames }),
    // })
    //   .then((res) => res.json())
    //   .then((res) => {
    //     console.log("res. is ", res);
    //   });
  }, []);

  let resourceList = [];

f8f0612f3409b5aedb0d51d423a41c36c94fb68e

Documentation

The README is missing the following documentation:

  • How to set up a local dev environment
  • Conventions
  • Project structure, file structure, libraries used

check this regex because there were some problems previous year

check this regex because there were some problems previous year

https://github.com/kossiitkgp/KWoC-21-Frontend/blob/fec417b3aaaeb968481722de84ceff05623e3ec3/src/views/StudentDashboard.js#L68

  };

  const handleBlogLink = () => {
    // TODO: check this regex because there were some problems previous year
    const urlMatch = new RegExp(
      "^(https?:\\/\\/)?" + // protocol
        "((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|" + // domain name

dc7952b32dbf93231870d55f5aa2098cd8abe424

KWoC 2023 Planning

The winter is coming, and so is KWoC. This winter, the truth will be redefined again. The entire KWoC frontend is being rewritten in the truth-redefined-again branch.

The project is built using React and already has a scaffolding with a router set up. Check out that branch's README file for instructions to get started.

Progress

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.