From 96b8989867f13f8536e39b044b98ba8d318a42f6 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 12:45:35 +0200 Subject: [PATCH 001/312] Add Calendar2D Component The chart for the 2D calendar has been added. It is not displayed yet. --- .../atoms/charts/Calendar2D/calendar2d.scss | 28 ++ .../atoms/charts/Calendar2D/index.jsx | 243 ++++++++++++++++++ src/components/atoms/index.js | 5 +- 3 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 src/components/atoms/charts/Calendar2D/calendar2d.scss create mode 100644 src/components/atoms/charts/Calendar2D/index.jsx diff --git a/src/components/atoms/charts/Calendar2D/calendar2d.scss b/src/components/atoms/charts/Calendar2D/calendar2d.scss new file mode 100644 index 0000000..9fbb86f --- /dev/null +++ b/src/components/atoms/charts/Calendar2D/calendar2d.scss @@ -0,0 +1,28 @@ +#calendar2d { + .col-months { + max-width: 7.655%; + flex: 0 0 7.655%; + } + svg { + width: 100%; + overflow: visible; + rect { + stroke-width: 3; + stroke: #fafafa; + transition: all 0.2s ease; + cursor: pointer; + &:hover { + stroke-width: 1; + } + &:focus { + outline: none; + fill: #f44336; + } + } + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx new file mode 100644 index 0000000..425f79a --- /dev/null +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -0,0 +1,243 @@ +//#region > Imports +// Contains all the functionality necessary to define React components +import React from "react"; + +//> Additional +// Used to display popovers on contrib chart items +import tippy from "tippy.js"; +import "tippy.js/dist/tippy.css"; +// Used to display the time in a readable format +import moment from "moment"; + +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { MDBRow, MDBCol } from "mdbreact"; + +//> CSS +import "./calendar2d.scss"; +//#endregion + +const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; + +//#region > Components +class Calender2D extends React.Component { + constructor(props) { + super(props); + this.myInput = React.createRef(); + + this.state = { + width: 0, + hue: 0, + items: 54, + }; + } + + componentDidMount = () => { + // Fill calendar + this.setCalendar(this.props); + + // Add resize listener + window.addEventListener("resize", this.updateDimensions); + + // We could implement color RGB cycling here + }; + + componentWillUnmount() { + // Remove listener to prevent memory leak + window.removeEventListener("resize", this.updateDimensions); + } + + componentWillReceiveProps(nextProps) { + for (const index in nextProps) { + if (nextProps[index] !== this.props[index]) { + this.setCalendar(nextProps); + } + } + } + + updateDimensions = () => { + this.setState({ + width: this.myInput.current.offsetWidth, + }); + }; + + setCalendar = async (props) => { + if (props.platformData) { + // Get contribution data + let contribData; + + if (props.year) { + contribData = props.platformData.statistic.years.find( + (element) => element.year === props.year + ); + } else { + contribData = props.platformData.statistic.current; + } + + let contributions = contribData.calendar; + + this.setState({ + width: this.myInput.current.offsetWidth, + contributionsList: contributions, + }); + } + }; + + countContribs = () => { + if (this.state.contributionsList) { + return this.state.contributionsList.total; + } else { + return null; + } + }; + + getEachMonth = (pos) => { + // Create new empty array + let month = new Array(); + + // Get current month + let current; + if (this.props.year) { + current = 0; + } else { + current = new Date().getMonth(); + } + + // Have each month two times + month[0] = "Jan"; + month[1] = "Feb"; + month[2] = "Mar"; + month[3] = "Apr"; + month[4] = "May"; + month[5] = "Jun"; + month[6] = "Jul"; + month[7] = "Aug"; + month[8] = "Sep"; + month[9] = "Oct"; + month[10] = "Nov"; + month[11] = "Dec"; + month[12] = "Jan"; + month[13] = "Feb"; + month[14] = "Mar"; + month[15] = "Apr"; + month[16] = "May"; + month[17] = "Jun"; + month[18] = "Jul"; + month[19] = "Aug"; + month[20] = "Sep"; + month[21] = "Oct"; + month[22] = "Nov"; + month[23] = "Dec"; + + return month[current + pos]; + }; + + displayDailyInfo = (day, wkey, dkey) => { + let cname = "item-" + wkey + "-" + dkey; + if (day.total > 0 && day.total !== 1) { + tippy(`.${cname}`, { + content: `${day.total} contributions on ${moment(day.date).format( + "MMM DD, YYYY" + )}`, + }); + } else if (day.total === 1) { + tippy(`.${cname}`, { + content: `${day.total} contribution on ${moment(day.date).format( + "MMM DD, YYYY" + )}`, + }); + } else { + tippy(`.${cname}`, { + content: `No contributions on ${moment(day.date).format( + "MMM DD, YYYY" + )}`, + }); + } + }; + + render() { + if (this.props.platformData) { + return ( +
+
+

+ {this.countContribs()} +

+ contributions in the last year +
+ + {months.map((month, key) => { + return ( + + {this.getEachMonth(key)} + + ); + })} + +
+ + {this.state.contributionsList && + this.state.contributionsList.weeks.map((week, wkey) => { + return week.days.map((day, dkey) => { + if (wkey === 0) { + return ( + + this.displayDailyInfo(day, wkey, dkey) + } + onClick={() => this.props.selectDay(day, wkey, dkey)} + fill={day.color} + > + ); + } else { + return ( + + this.displayDailyInfo(day, wkey, dkey) + } + onClick={() => this.props.selectDay(day, wkey, dkey)} + fill={day.color} + > + ); + } + }); + })} + +
+
+ ); + } else { + return null; + } + } +} +//#endregion + +//#region > Exports +export default Calender2D; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index a5b1410..07ebfa5 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -1,11 +1,12 @@ //#region > Imports //> Atoms // Import all components to export them for easy access from parent components -//import Atom from "./Atom"; +//>> User profile +import Calendar2D from "./charts/Calendar2D"; //#endregion //#region > Exports -//export { Atom }; +export { Calendar2D }; //#endregion /** From f4975aae3c2ad362d66b16db1e363b431b6a3f31 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 12:47:53 +0200 Subject: [PATCH 002/312] Add Calendar3D Component The chart for the 3D calendar has been added. It is not displayed yet. --- .../atoms/charts/Calendar3D/calendar3d.scss | 92 +++++ .../atoms/charts/Calendar3D/index.jsx | 369 ++++++++++++++++++ src/components/atoms/index.js | 3 +- 3 files changed, 463 insertions(+), 1 deletion(-) create mode 100644 src/components/atoms/charts/Calendar3D/calendar3d.scss create mode 100644 src/components/atoms/charts/Calendar3D/index.jsx diff --git a/src/components/atoms/charts/Calendar3D/calendar3d.scss b/src/components/atoms/charts/Calendar3D/calendar3d.scss new file mode 100644 index 0000000..fd3d7b0 --- /dev/null +++ b/src/components/atoms/charts/Calendar3D/calendar3d.scss @@ -0,0 +1,92 @@ +#calendar3d { + position: relative; + width: 80%; + margin: auto; + display: block; + + .ic-stats-block { + position: absolute; + } + + .ic-stats-top { + top: 8px; + right: 20px; + } + + .ic-stats-bottom { + top: 225px; + left: 20px; + } + + .ic-stats-table { + display: table; + } + + .ic-stats-row { + display: table-row; + } + + .ic-stats-label { + display: table-cell; + padding-bottom: 12px; + font-size: 14px; + color: #777; + text-align: right; + vertical-align: bottom; + } + + .ic-stats-count { + display: block; + font-size: 32px; + font-weight: 600; + line-height: 1; + color: #1e6823; + } + + .ic-stats-meta { + display: table-cell; + padding-bottom: 12px; + padding-left: 8px; + text-align: left; + line-height: 1.2; + vertical-align: bottom; + } + + .ic-stats-total-meta { + vertical-align: middle; + } + + .ic-stats-average { + font-size: 12px; + font-weight: bold; + color: #24292e; + } + + .ic-stats-unit { + display: block; + font-size: 14px; + } + + .ic-stats-date { + display: block; + color: #999; + font-size: 12px; + } + + .ic-footer { + position: absolute; + top: 380px; + left: 20px; + font-size: 11px; + color: #999; + } + + .ic-footer a { + color: #777; + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx new file mode 100644 index 0000000..1bbe2c2 --- /dev/null +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -0,0 +1,369 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; + +//> Additional packages +// Used to display the time in a readable format +import moment from "moment"; + +//> CSS +import "./calendar3d.scss"; +//#endregion + +//#region > Components +class Calendar3D extends React.Component { + constructor(props) { + super(props); + + this.myInput = React.createRef(); + + this.state = { + width: 0, + hue: 0, + }; + } + + componentDidMount = () => { + if (this.props.platformData) { + // Add resize listener + window.addEventListener("resize", this.updateDimensions); + this.setState( + { + width: this.myInput.current.offsetWidth, + loading: true, + }, + () => this.checkCache() + ); + } + }; + + componentDidUpdate = () => { + this.checkCache(); + }; + + componentWillUnmount() { + window.removeEventListener("resize", this.updateDimensions); + } + + componentWillReceiveProps = (nextProps) => { + // Use caching for year change + //console.log(this.props.year); + //console.log(nextProps.year); + }; + + updateDimensions = () => { + this.setState( + { + width: this.myInput.current.offsetWidth, + }, + () => this.checkCache() + ); + }; + + renderTopStats() { + let countTotal, averageCount, datesTotal, maxCount, dateBest, contribData; + if (this.props.year) { + contribData = this.props.platformData.statistic.years.find( + (element) => element.year === this.props.year + ); + } else { + contribData = this.props.platformData.statistic.current; + } + + let contributionCalendar = contribData.calendar; + + countTotal = contribData.contributions.total; + averageCount = + Math.round( + (contribData.contributions.total / 365 + Number.EPSILON) * 100 + ) / 100; + datesTotal = + moment(contributionCalendar.startDate).format("MMM DD, YYYY") + + " - " + + moment(contributionCalendar.endDate).format("MMM DD, YYYY"); + /* Busiest day */ + maxCount = contribData.busiestDay.total; + dateBest = moment(contribData.busiestDay.date); + dateBest = dateBest.isValid() ? dateBest.format("MMM DD") : "-"; + + let html; + + html = `
\n + \n + \n + 1 year total\n + ${countTotal}\n + ${averageCount} per day\n + \n + \n + contributions\n + ${datesTotal}\n + \n + \n + \n + Busiest day\n + ${maxCount}\n + \n + \n + contributions\n + ${dateBest}\n + \n + \n + \n + \n +
`; + return { __html: html }; + } + + renderBottomStats() { + let streakLongest, datesLongest, streakCurrent, datesCurrent, contribData; + if (this.props.year) { + contribData = this.props.platformData.statistic.years.find( + (element) => element.year === this.props.year + ); + } else { + contribData = this.props.platformData.statistic.current; + } + + let contributionCalendar = contribData.calendar; + + if (contribData.streak.longest) { + streakLongest = contribData.streak.longest.totalDays; + datesLongest = + moment(contribData.streak.longest.startDate).format("MMM DD, YYYY") + + " - " + + moment(contribData.streak.longest.endDate).format("MMM DD, YYYY"); + } else { + streakLongest = "0"; + datesLongest = "-"; + } + if (contribData.streak.current.id !== -1) { + streakCurrent = contribData.streak.current.totalDays; + datesCurrent = + moment(contribData.streak.current.startDate).format("MMM DD, YYYY") + + " - " + + moment(contribData.streak.current.endDate).format("MMM DD, YYYY"); + } else { + streakCurrent = "0"; + datesCurrent = "-"; + } + + let html; + + html = `
\n + \n + \n + Longest streak\n + ${streakLongest}\n + \n + \n + days\n + ${datesLongest}\n + \n + \n + \n + Current streak\n + ${streakCurrent}\n + \n + \n + days\n + ${datesCurrent}\n + \n + \n + \n +
`; + return { __html: html }; + } + + renderIsometrics = () => { + if (this.context) { + const obelisk = require("obelisk.js"); + + // Create a canvas 2D point for pixel view world + let point = new obelisk.Point(70, 70); + + // Create view instance to nest everything + // Canvas could be either DOM or jQuery element + let pixelView = new obelisk.PixelView(this.context, point); + pixelView.clear(); + + // Get contributions of the selected year + let contribData; + if (this.props.year) { + contribData = this.props.platformData.statistic.years.find( + (element) => element.year === this.props.year + ); + } else { + contribData = this.props.platformData.statistic.current; + } + + let contributions = contribData.calendar; + + // Define basic variables + let SIZE = 2 * Math.round(this.state.width / 80 / 2); + if (SIZE <= 8) { + SIZE = 8; + } + let MAXHEIGHT = 100; + let x = 0; + let y = 0; + let maxCount = 0; // Max number of contributions / day in the last year + + let values = []; + + contributions.weeks.map((week, wkey) => { + values[wkey] = []; + week.days.map((day, dkey) => { + // Get max number of contributions + if (day.total > maxCount) { + maxCount = day.total; + } + values[wkey][dkey] = day; + }); + }); + + values.map((week, wi) => { + week.map((day, di) => { + // Normalize the values to achieve even distribution + let cubeHeight = 3; + if (maxCount > 0) { + cubeHeight += parseInt((MAXHEIGHT / maxCount) * day.total); + } + + // Offsets + let x = wi; + let y = di; + + // Create cube dimension and color instance + let fill = day.color; + let color = new obelisk.CubeColor().getByHorizontalColor( + parseInt("0x" + fill.replace("#", "")) + ); + + // ANIMATION TOGGLE for kleberbaum to play with + const animated = false; + + if (animated) { + var animHeight = 3; + + function draw() { + let dimension = new obelisk.CubeDimension(SIZE, SIZE, animHeight); + let p3d = new obelisk.Point3D(SIZE * x, SIZE * y, 0); + let cube = new obelisk.Cube(dimension, color, false); + + // Render cube primitive into view + pixelView.renderObject(cube, p3d); + if (animHeight < cubeHeight) { + if (parseInt((MAXHEIGHT / maxCount) * day.total) > 0) { + animHeight += 1; + } else { + animHeight = 1; + } + } + // Animations + requestAnimationFrame(draw); + } + draw(); + } else { + let dimension = new obelisk.CubeDimension(SIZE, SIZE, cubeHeight); + let p3d = new obelisk.Point3D(SIZE * x, SIZE * y, 0); + let cube = new obelisk.Cube(dimension, color, false); + + // Render cube primitive into view + pixelView.renderObject(cube, p3d); + + this.cacheChart(); + } + }); + }); + if (this.state.loading) { + this.setState({ + loading: false, + }); + } + } + }; + + cacheChart = async () => { + if (!localStorage.getItem("3dChart")) { + window.setTimeout( + () => + localStorage.setItem( + "3dChart", + JSON.stringify({ + data: this.context.toDataURL(), + timestamp: new Date().getTime(), + }) + ), + 0 + ); + } + }; + + checkCache = () => { + const cache = localStorage.getItem("3dChart"); + if (cache) { + const cacheObject = JSON.parse(cache); + if (cacheObject.timestamp > new Date().getTime() - 3600000) { + //this.renderCache(); + window.setTimeout(() => this.renderIsometrics(), 0); + } else { + window.setTimeout(() => this.renderIsometrics(), 0); + } + } else { + window.setTimeout(() => this.renderIsometrics(), 0); + } + }; + + renderCache = () => { + const data = localStorage.getItem("3dChart"); + const dataObject = JSON.parse(data); + const context = this.context.getContext("2d"); + let img = new Image(); + + img.src = dataObject.data; + + if (context !== null) { + img.onload = () => { + context.drawImage(img, 0, 0); + }; + } + /*if (!this.state.cache) { + this.setState({ + cache: img.src, + }); + }*/ + }; + + render() { + return ( +
+ {this.props.platformData && this.state.width > 500 && ( + <> +
+
+ + )} +
+ (this.context = c)} + width={this.state.width} + height="350" + > +
+ {this.state.cache && } +
+ ); + } +} +//#endregion + +//#region > Exports +export default Calendar3D; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index 07ebfa5..7ced9fd 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -3,10 +3,11 @@ // Import all components to export them for easy access from parent components //>> User profile import Calendar2D from "./charts/Calendar2D"; +import Calendar3D from "./charts/Calendar3D"; //#endregion //#region > Exports -export { Calendar2D }; +export { Calendar2D, Calendar3D }; //#endregion /** From cfd25b031667965097b08928292d65e5d6b19b46 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 12:48:41 +0200 Subject: [PATCH 003/312] Add ContribRadar Component The chart for the contribution radar has been added. It is not displayed yet. --- .../atoms/charts/ContribRadar/index.jsx | 183 ++++++++++++++++++ src/components/atoms/index.js | 3 +- 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 src/components/atoms/charts/ContribRadar/index.jsx diff --git a/src/components/atoms/charts/ContribRadar/index.jsx b/src/components/atoms/charts/ContribRadar/index.jsx new file mode 100644 index 0000000..400d8e6 --- /dev/null +++ b/src/components/atoms/charts/ContribRadar/index.jsx @@ -0,0 +1,183 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; + +//> Additional +// Charts for displaying user contribution distribution (Chart.js 2) +import { Radar } from "react-chartjs-2"; +//#endregion + +//#region > Components +class ChartsPage extends React.Component { + state = { + dataRadarOptions: { + responsive: true, + elements: { + line: { + tension: 0, + }, + }, + tooltips: { + enabled: false, + }, + legend: { + display: false, + }, + elements: { + point: { + radius: 0, + }, + }, + scale: { + pointLabels: { + fontSize: 11, + color: "grey", + }, + gridLines: { + display: false, + }, + ticks: { + display: false, + }, + }, + scales: { + yAxes: [ + { + gridLines: { + display: false, + drawBorder: false, + }, + ticks: { + display: false, + }, + }, + ], + xAxes: [ + { + gridLines: { + display: false, + drawBorder: false, + }, + ticks: { + beginAtZero: true, + display: false, + }, + }, + ], + }, + }, + }; + + componentDidMount = () => { + // First render chart with current year + this.calculateSources(null); + }; + + componentWillReceiveProps(nextProps) { + // Update chart + this.calculateSources(nextProps.year); + } + + fillChart = (results) => { + console.log(results); + if (results) { + this.setState({ + dataRadar: { + labels: [ + `Code Review ${results[0].data[0]}%`, + `Issues ${results[0].data[1]}%`, + `Pull Request ${results[0].data[2]}%`, + `Commits ${results[0].data[3]}% `, + ], + datasets: results, + }, + }); + } else { + this.setState({ dataRadar: null }); + } + }; + + calculateSources = (nextPropsYear) => { + const { statistic } = this.props; + let totalReviews = 0, + totalIssues = 0, + totalRequests = 0, + totalCommits = 0, + totalSources = 1, + year, + results = []; + + if (nextPropsYear === null) { + year = this.props.year; + } else { + year = nextPropsYear; + } + + if (year) { + let selectedYear = statistic.years.find( + (element) => element.year === year + ); + + totalIssues = selectedYear.contributions.issue.share; + totalRequests = selectedYear.contributions.pullRequest.share; + totalCommits = selectedYear.contributions.commit.share; + totalReviews = selectedYear.contributions.pullRequestReview.share; + } else { + let contributions = statistic.current.contributions; + + totalIssues = contributions.issue.share; + totalRequests = contributions.pullRequest.share; + totalCommits = contributions.commit.share; + totalReviews = contributions.pullRequestReview.share; + } + + let values = [totalReviews, totalIssues, totalRequests, totalCommits]; + + // Check if the values are valid + if (values.includes(undefined)) { + this.fillChart(null); + } else { + results.push({ + label: "GitHub", + backgroundColor: "rgba(123, 201, 111,.4)", + borderColor: "rgba(123, 201, 111)", + data: values, + }); + + // Calculate averages + let avgReviews, avgIssues, avgRequests, avgCommits; + + avgReviews = parseInt(totalReviews) / parseInt(totalSources); + avgIssues = parseInt(totalIssues) / parseInt(totalSources); + avgRequests = parseInt(totalRequests) / parseInt(totalSources); + avgCommits = parseInt(totalCommits) / parseInt(totalSources); + + this.fillChart(results); + } + }; + + render() { + if (this.state.dataRadar) { + return ( + + ); + } else { + return null; + } + } +} +//#endregion + +//#region > Exports +export default ChartsPage; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index 7ced9fd..9edd431 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -4,10 +4,11 @@ //>> User profile import Calendar2D from "./charts/Calendar2D"; import Calendar3D from "./charts/Calendar3D"; +import ContribRadar from "./charts/ContribRadar"; //#endregion //#region > Exports -export { Calendar2D, Calendar3D }; +export { Calendar2D, Calendar3D, ContribRadar }; //#endregion /** From 5a2787de08fb0844b5dc12c0ec9c867fef5f0e9d Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:10:44 +0200 Subject: [PATCH 004/312] Add LatestActivity Component The chart for the latest activity has been added. It is not displayed yet. --- .../atoms/charts/LatestActivity/index.jsx | 167 ++++++++++++++++++ src/components/atoms/index.js | 3 +- 2 files changed, 169 insertions(+), 1 deletion(-) create mode 100644 src/components/atoms/charts/LatestActivity/index.jsx diff --git a/src/components/atoms/charts/LatestActivity/index.jsx b/src/components/atoms/charts/LatestActivity/index.jsx new file mode 100644 index 0000000..39365e8 --- /dev/null +++ b/src/components/atoms/charts/LatestActivity/index.jsx @@ -0,0 +1,167 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; + +//> Additional +// Charts for displaying user contribution distribution (Chart.js 2) +import { Line } from "react-chartjs-2"; +// Used to display the time in a readable format +import moment from "moment"; +//#endregion + +//#region > Components +class LatestActivity extends React.Component { + state = { + dataLineOptions: { + responsive: true, + scales: { + xAxes: [ + { + gridLines: { + display: false, + }, + }, + ], + yAxes: [ + { + ticks: { + display: false, + }, + gridLines: { + color: "#ededed", + }, + }, + ], + }, + }, + }; + + componentDidMount = () => { + // First render chart with current week + this.calculateSources(undefined, undefined); + }; + + componentWillReceiveProps(nextProps) { + // Update chart + this.calculateSources(nextProps.year, nextProps.activity); + } + + fillChart = (results, lastWeek) => { + console.log(results, lastWeek); + if (results) { + this.setState({ + dataLine: { + labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + datasets: [ + { + label: "This week", + fill: true, + lineTension: 0.3, + backgroundColor: "rgba(255,255,255, 0)", + borderColor: "rgb(123, 201, 111)", + borderCapStyle: "butt", + borderDash: [], + borderDashOffset: 0.0, + borderJoinStyle: "miter", + pointBackgroundColor: "rgb(255, 255, 255)", + pointRadius: 4, + pointHitRadius: 10, + data: results, + }, + { + label: "Last week", + fill: true, + lineTension: 0.3, + backgroundColor: "rgba(255,255,255, 0)", + borderColor: "rgba(123, 201, 111, .2)", + borderCapStyle: "butt", + borderDash: [], + borderDashOffset: 0.0, + borderJoinStyle: "miter", + pointBackgroundColor: "rgb(255, 255, 255)", + pointRadius: 4, + pointHitRadius: 10, + data: lastWeek, + }, + ], + }, + }); + } else { + this.setState({ dataLine: null }); + } + }; + + calculateSources = (year, activity) => { + const { statistic } = this.props; + + let contribData, week, lastWeek, lastWeekValues; + + if (!year) { + contribData = statistic.current; + } else { + contribData = statistic.years.find((element) => element.year === year); + } + + const weeks = contribData.calendar.weeks; + + if (!activity) { + week = weeks[weeks.length - 1]; + lastWeek = weeks[weeks.length - 2]; + } else { + week = weeks[activity.wkey]; + lastWeek = weeks[activity.wkey - 1]; + } + + const values = week.days.map((day, i) => { + return day.total; + }); + + if (lastWeek) { + lastWeekValues = lastWeek.days.map((day, i) => { + return day.total; + }); + } + + this.setState( + { + startDate: week.days[0]?.date, + endDate: week.days[6]?.date, + }, + () => this.fillChart(values, lastWeekValues) + ); + }; + + render() { + if (this.state.dataLine) { + return ( + <> +

+ + {moment(this.state.startDate).format("DD.MM.YYYY")} + {" - "} + {moment(this.state.endDate).format("DD.MM.YYYY")} + +

+ + + ); + } else { + return null; + } + } +} +//#endregion + +//#region > Exports +export default LatestActivity; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index 9edd431..f61c52a 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -5,10 +5,11 @@ import Calendar2D from "./charts/Calendar2D"; import Calendar3D from "./charts/Calendar3D"; import ContribRadar from "./charts/ContribRadar"; +import LatestActivity from "./charts/LatestActivity"; //#endregion //#region > Exports -export { Calendar2D, Calendar3D, ContribRadar }; +export { Calendar2D, Calendar3D, ContribRadar, LatestActivity }; //#endregion /** From 15db39dcbd556b8d4454c6e583ff33e288b4ca0d Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:13:02 +0200 Subject: [PATCH 005/312] Add Atom Descriptions Descriptions for the usage of all atoms have been added. --- src/components/atoms/charts/Calendar2D/index.jsx | 1 + src/components/atoms/charts/Calendar3D/index.jsx | 4 ++++ src/components/atoms/charts/ContribRadar/index.jsx | 8 ++++++-- src/components/atoms/charts/LatestActivity/index.jsx | 4 ++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index 425f79a..c7c4fa9 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -20,6 +20,7 @@ import "./calendar2d.scss"; const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; //#region > Components +/** @class A two dimensional calendar which displays each days contributions */ class Calender2D extends React.Component { constructor(props) { super(props); diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx index 1bbe2c2..030d1ae 100644 --- a/src/components/atoms/charts/Calendar3D/index.jsx +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -12,6 +12,10 @@ import "./calendar3d.scss"; //#endregion //#region > Components +/** + * @class A three dimensional calendar which displays each days contributions, + * and contribution related statistics e.g. busiest days and streaks + */ class Calendar3D extends React.Component { constructor(props) { super(props); diff --git a/src/components/atoms/charts/ContribRadar/index.jsx b/src/components/atoms/charts/ContribRadar/index.jsx index 400d8e6..4a09e61 100644 --- a/src/components/atoms/charts/ContribRadar/index.jsx +++ b/src/components/atoms/charts/ContribRadar/index.jsx @@ -9,7 +9,11 @@ import { Radar } from "react-chartjs-2"; //#endregion //#region > Components -class ChartsPage extends React.Component { +/** + * @class A contribution statistic which displays the the ratio of + * commits, issues, pull requests and code reviews. + */ +class ContribRadar extends React.Component { state = { dataRadarOptions: { responsive: true, @@ -174,7 +178,7 @@ class ChartsPage extends React.Component { //#endregion //#region > Exports -export default ChartsPage; +export default ContribRadar; //#endregion /** diff --git a/src/components/atoms/charts/LatestActivity/index.jsx b/src/components/atoms/charts/LatestActivity/index.jsx index 39365e8..4e479f7 100644 --- a/src/components/atoms/charts/LatestActivity/index.jsx +++ b/src/components/atoms/charts/LatestActivity/index.jsx @@ -11,6 +11,10 @@ import moment from "moment"; //#endregion //#region > Components +/** + * @class A week calendar which compares the contributions of a selectable week + * with the current week. + */ class LatestActivity extends React.Component { state = { dataLineOptions: { From 1e1daf3d66c189e99ffd70dfce861310ff51f34d Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 12:57:40 +0200 Subject: [PATCH 006/312] Add ScrollToTop Component The scroll to top fix has been added. It is not displayed yet. --- src/components/atoms/ScrollToTop/index.jsx | 32 ++++++++++++++++++++++ src/components/atoms/index.js | 5 ++-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 src/components/atoms/ScrollToTop/index.jsx diff --git a/src/components/atoms/ScrollToTop/index.jsx b/src/components/atoms/ScrollToTop/index.jsx new file mode 100644 index 0000000..007125e --- /dev/null +++ b/src/components/atoms/ScrollToTop/index.jsx @@ -0,0 +1,32 @@ +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// DOM bindings for React Router +import { withRouter } from "react-router-dom"; + +/** + * @class ScrollToTop Component + * @description When reloading or switching a page, ReactJS now starts at the + * top of the page, and no longer on the last position. + */ +class ScrollToTop extends React.Component { + componentDidUpdate(prevProps) { + const { location } = this.props; + + if (location !== prevProps.location) { + // Scroll to top of viewport + window.scrollTo(0, 0); + } + } + + render() { + return this.props.children; + } +} + +export default withRouter(ScrollToTop); + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index a5b1410..3f9f2a8 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -1,11 +1,12 @@ //#region > Imports //> Atoms // Import all components to export them for easy access from parent components -//import Atom from "./Atom"; +//> Generic +import ScrollToTop from "./ScrollToTop"; //#endregion //#region > Exports -//export { Atom }; +export { ScrollToTop }; //#endregion /** From 5d1cdb1488f883bea9917297ec91e737304fd690 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:01:41 +0200 Subject: [PATCH 007/312] Add Project Component The project component has been added. It is not displayed yet. --- src/components/atoms/Project/index.jsx | 76 ++++++++++++++++++++++++++ src/components/atoms/index.js | 4 +- 2 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 src/components/atoms/Project/index.jsx diff --git a/src/components/atoms/Project/index.jsx b/src/components/atoms/Project/index.jsx new file mode 100644 index 0000000..408cd89 --- /dev/null +++ b/src/components/atoms/Project/index.jsx @@ -0,0 +1,76 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// React PropTypes +import PropTypes from "prop-types"; + +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBContainer, + MDBRow, + MDBCol, + MDBAlert, + MDBInput, + MDBBtn, + MDBIcon, +} from "mdbreact"; +//#endregion + +//#region > Components +class Project extends React.Component { + render() { + const { repo } = this.props; + + return ( + + +
  • +
    +

    + {repo.name.length > 25 + ? repo.name.substring(0, 25) + "..." + : repo.name} +

    + {repo.languages.length > 0 && ( + + + {repo.languages[0].name} + + )} +
    +
    +
    + {repo.name} + Owned by {repo.owner.username} +
    +
    + +
    +
  • +
    +
    + ); + } +} +//#endregion + +//#region > PropTypes +Project.propTypes = { + repo: PropTypes.object.isRequired, +}; +//#endregion + +//#region > Exports +export default Project; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index 3f9f2a8..77254cb 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -3,10 +3,12 @@ // Import all components to export them for easy access from parent components //> Generic import ScrollToTop from "./ScrollToTop"; +//> User profile +import Project from "./Project"; //#endregion //#region > Exports -export { ScrollToTop }; +export { ScrollToTop, Project }; //#endregion /** From a36857ba7b5666207f853bebc37a3cdfc183a4d5 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:02:43 +0200 Subject: [PATCH 008/312] Add Pinned Component The pinned component has been added. It is not displayed yet. --- src/components/atoms/Pinned/index.jsx | 77 +++++++++++++++++++++++++ src/components/atoms/Pinned/pinned.scss | 11 ++++ src/components/atoms/index.js | 3 +- 3 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 src/components/atoms/Pinned/index.jsx create mode 100644 src/components/atoms/Pinned/pinned.scss diff --git a/src/components/atoms/Pinned/index.jsx b/src/components/atoms/Pinned/index.jsx new file mode 100644 index 0000000..7116f33 --- /dev/null +++ b/src/components/atoms/Pinned/index.jsx @@ -0,0 +1,77 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// React PropTypes +import PropTypes from "prop-types"; + +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBContainer, + MDBRow, + MDBCol, + MDBCard, + MDBCardBody, + MDBIcon, +} from "mdbreact"; + +//> CSS +import "./pinned.scss"; +//#endregion + +//#region > Components +class Pinned extends React.Component { + render() { + const { category, link, pinned } = this.props; + + return ( + + +
    + +
    +

    {pinned?.description}

    +
    +
    + + + + {pinned?.views} + + + {link && ( + + + + More + + + + )} + +
    +
    + + + ); + } +} +//#endregion + +//#region > PropTypes +Pinned.propTypes = { + category: PropTypes.object.isRequired, + link: PropTypes.string, + pinned: PropTypes.object.isRequired, +}; +//#endregion + +//#region > Exports +export default Pinned; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/Pinned/pinned.scss b/src/components/atoms/Pinned/pinned.scss new file mode 100644 index 0000000..729eeed --- /dev/null +++ b/src/components/atoms/Pinned/pinned.scss @@ -0,0 +1,11 @@ +.pinned-item { + .pinned-header { + width: 100%; + padding: 0.2rem; + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index 77254cb..1b42259 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -5,10 +5,11 @@ import ScrollToTop from "./ScrollToTop"; //> User profile import Project from "./Project"; +import Pinned from "./Pinned"; //#endregion //#region > Exports -export { ScrollToTop, Project }; +export { ScrollToTop, Project, Pinned }; //#endregion /** From 148677538974aaa409fe3e08a3e4ad97e9fb57f1 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:16:49 +0200 Subject: [PATCH 009/312] Add Atom Descriptions Descriptions for the usage of all atoms have been added. --- src/components/atoms/Pinned/index.jsx | 3 +++ src/components/atoms/Project/index.jsx | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/components/atoms/Pinned/index.jsx b/src/components/atoms/Pinned/index.jsx index 7116f33..8c046c2 100644 --- a/src/components/atoms/Pinned/index.jsx +++ b/src/components/atoms/Pinned/index.jsx @@ -21,6 +21,9 @@ import "./pinned.scss"; //#endregion //#region > Components +/** + * @class Displays pinned projects + */ class Pinned extends React.Component { render() { const { category, link, pinned } = this.props; diff --git a/src/components/atoms/Project/index.jsx b/src/components/atoms/Project/index.jsx index 408cd89..d6f11e0 100644 --- a/src/components/atoms/Project/index.jsx +++ b/src/components/atoms/Project/index.jsx @@ -19,6 +19,9 @@ import { //#endregion //#region > Components +/** + * @class A project which contains repository data + */ class Project extends React.Component { render() { const { repo } = this.props; From 094a5f75fd71aa27dafc06117ff4ec75f2310c36 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:23:32 +0200 Subject: [PATCH 010/312] Add Footer Component The footer component has been added. It is not displayed yet. --- src/components/molecules/Footer/footer.scss | 95 +++++++ src/components/molecules/Footer/index.jsx | 265 ++++++++++++++++++++ src/components/molecules/index.js | 4 +- 3 files changed, 362 insertions(+), 2 deletions(-) create mode 100644 src/components/molecules/Footer/footer.scss create mode 100644 src/components/molecules/Footer/index.jsx diff --git a/src/components/molecules/Footer/footer.scss b/src/components/molecules/Footer/footer.scss new file mode 100644 index 0000000..0242074 --- /dev/null +++ b/src/components/molecules/Footer/footer.scss @@ -0,0 +1,95 @@ +footer { + transition: all 0.5s ease; + + // Footer link items + ul { + padding: 0; + li { + background: rgba(255, 255, 255, 0.05); + transition: all 0.1s ease; + padding: 1rem !important; + align-items: center; + i { + width: 30px; + text-align: center; + padding-right: 0.5rem; + } + &:hover { + background: rgba(255, 255, 255, 0.1); + } + .badge { + box-shadow: none; + } + } + } + + // Custom pulsating heart + .pulse { + -webkit-animation: pulse 1s infinite; + animation: pulse 1s infinite; + } + + // Footer column headers + .title { + text-transform: uppercase; + font-weight: bold; + } + + // Column header separator + .col-md-3, + .col-md-4 { + hr { + width: 60px; + height: 1px; + } + } + + // Social tab + .social { + padding: 2rem 0 2rem 0; + margin: 0; + background-color: rgba(0, 0, 0, 0.1); + } + + // Company img + svg { + width: 80%; + } + + // Light Mode + &.white { + ul li { + background: rgba(0, 0, 0, 0.05); + &:hover { + background: rgba(0, 0, 0, 0.1); + } + } + .footer-copyright { + background: rgba(0, 0, 0, 0.1); + color: #212121 !important; + } + ul { + i { + color: #212121 !important; + } + a { + color: #212121 !important; + } + } + } + .madeby { + a { + color: #212121; + border-bottom: solid #77bd43 2px; + transition: border-bottom 0.2s ease; + &:hover { + border-bottom: solid #0366d6 2px; + } + } + } +} + +/** +* SPDX-License-Identifier: (EUPL-1.2) +* Copyright © Simon Prast +*/ diff --git a/src/components/molecules/Footer/index.jsx b/src/components/molecules/Footer/index.jsx new file mode 100644 index 0000000..029d036 --- /dev/null +++ b/src/components/molecules/Footer/index.jsx @@ -0,0 +1,265 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// DOM bindings for React Router +import { Link, withRouter } from "react-router-dom"; + +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBFooter, + MDBSmoothScroll, + MDBRow, + MDBCol, + MDBContainer, + MDBIcon, + MDBBtn, +} from "mdbreact"; + +//> CSS +import "./footer.scss"; + +//> Images +// SNEK Logo +import Logo from "../../../assets/navigation/logo.png"; +//#endregion + +//> Local data +// Slogans +/** @todo Change to uppercase */ +//#region > Constant Variables +const slogans = [ + "Become a snek!", + "Connect with your colleges!", + "Show the world what you can do!", + "What are you waiting for?!", +]; +//#endregion + +//#region > Components +/** @class The footer for all pages */ +class Footer extends React.PureComponent { + state = { + slogan: "", + }; + + componentDidMount = () => { + this.getSlogan(); + }; + + getSlogan = () => { + this.setState({ + slogan: slogans[Math.floor(Math.random() * slogans.length)], + }); + }; + + render() { + return ( + + + +

    Connect with us!

    +
    + + + + + + + + + + + + + + + + + + + + +
    + + + + SNEK Logo +

    + Social Network, +
    + built for engineers. +

    +
    + +
    Legal
    +
    +
      + +
    • + + About +
    • + + +
    • + + Privacy +
    • + + +
    • + + Terms of Service +
    • + +
    +
    + +
    Useful links
    +
    + +
    + +
    Contact
    +
    + +
    + +

    {this.state.slogan}

    + {this.props.location.pathname === "/" ? ( + + + Join now + + + ) : ( + + + Join now + + + )} +
    +
    +
    +
    + + Copyright © 2019 - {new Date().getFullYear()} Simon Prast +
    + + v{process.env.REACT_APP_VERSION} + +

    + Made with{" "} +

    +
    +
    +
    + ); + } +} +//#endregion + +//#region > Exports +export default withRouter(Footer); +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/index.js b/src/components/molecules/index.js index 7427f8b..c9bf0ac 100644 --- a/src/components/molecules/index.js +++ b/src/components/molecules/index.js @@ -1,11 +1,11 @@ //#region > Imports //> Molecules // Import all components to export them for easy access from parent components -//import Molecule from "./Molecule"; +import Footer from "./Footer"; //#endregion //#region > Exports -//export { Molecule }; +export { Footer }; //#endregion /** From b964cdae8c9c60aa2b3271cc8459efcd5a7ea481 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:26:31 +0200 Subject: [PATCH 011/312] Add Navbar Component The navbar component has been added. It is not displayed yet. --- src/components/molecules/Navbar/index.jsx | 165 ++++++++++++++++++++ src/components/molecules/Navbar/navbar.scss | 72 +++++++++ src/components/molecules/index.js | 3 +- 3 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 src/components/molecules/Navbar/index.jsx create mode 100644 src/components/molecules/Navbar/navbar.scss diff --git a/src/components/molecules/Navbar/index.jsx b/src/components/molecules/Navbar/index.jsx new file mode 100644 index 0000000..2552f33 --- /dev/null +++ b/src/components/molecules/Navbar/index.jsx @@ -0,0 +1,165 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// DOM bindings for React Router +import { Link, withRouter } from "react-router-dom"; +// React PropTypes +import PropTypes from "prop-types"; + +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBNavbar, + MDBNavbarBrand, + MDBNavbarNav, + MDBNavItem, + MDBNavbarToggler, + MDBCollapse, + MDBContainer, + MDBDropdown, + MDBDropdownItem, + MDBDropdownToggle, + MDBDropdownMenu, + MDBSmoothScroll, + MDBBtn, +} from "mdbreact"; + +//> Images +import SNEKLogo from "../../../assets/navigation/logo.png"; + +//> CSS +import "./navbar.scss"; +//#endregion + +//#region > Components +/** + * @class The navbar for all pages. Contains a login button and a profile menu + * depending on whether you are logged in or not. + */ +class Navbar extends React.Component { + state = { + isOpen: false, + }; + + toggleCollapse = () => { + this.setState({ isOpen: !this.state.isOpen }); + }; + + render() { + const { globalState, globalFunctions, location } = this.props; + + return ( + + + {location.pathname === "/" ? ( + + + SNEK Logo + SNEK + + + ) : ( + <> + {!globalState.loading && globalState.loggedUser ? ( + + + SNEK Logo + SNEK + + + ) : ( + + + SNEK Logo + SNEK + + + )} + + )} + + + + {/* SEARCH */} + + + {!globalState.loading && globalState.loggedUser ? ( + <> +
    + + + + {globalState.loggedUser.username} + + + + My profile + + + Sign Out + + + + + + ) : ( + <> + {location.pathname !== "/" && ( + + Sign In + + )} + + )} + + + + + ); + } +} +//#endregion + +//#region > PropTypes +Navbar.propTypes = { + globalState: PropTypes.object, + globalFunctions: PropTypes.object, + location: PropTypes.object, +}; +//#endregion + +//#region > Exports +export default withRouter(Navbar); +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/Navbar/navbar.scss b/src/components/molecules/Navbar/navbar.scss new file mode 100644 index 0000000..40f97c8 --- /dev/null +++ b/src/components/molecules/Navbar/navbar.scss @@ -0,0 +1,72 @@ +// Import variables +@import "../../../utilities/variables"; + +.navbar { + box-shadow: none; + background: #f0f0f0; + li { + align-self: center; + .dropdown { + img { + max-height: 30px; + width: auto; + border-radius: 0.2em; + } + .dropdown-toggle::after { + vertical-align: initial; + } + .dropdown-menu { + padding: 0; + .dropdown-item { + transition: all 0.2s ease; + box-shadow: none !important; + &:focus { + box-shadow: none !important; + background-color: lightgrey !important; + color: red !important; + } + &:hover { + box-shadow: none !important; + background-color: #f0f0f0 !important; + color: initial !important; + } + } + } + } + a { + font-weight: bold; + } + &.active { + a { + background-color: inherit !important; + border-bottom: solid $snekGreen 2px; + } + } + } + input[type="search"] { + &:focus { + color: #495057; + background-color: #fff; + border-color: $snekGreen; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); + } + } + // Remove search field delete button + input[type="search"]::-webkit-search-decoration, + input[type="search"]::-webkit-search-cancel-button, + input[type="search"]::-webkit-search-results-button, + input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; + } + .spacer { + margin-left: 1rem; + padding-left: 1rem; + border-left: solid $snekGreen 2px; + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/index.js b/src/components/molecules/index.js index c9bf0ac..ec0d4d5 100644 --- a/src/components/molecules/index.js +++ b/src/components/molecules/index.js @@ -2,10 +2,11 @@ //> Molecules // Import all components to export them for easy access from parent components import Footer from "./Footer"; +import Navbar from "./Navbar"; //#endregion //#region > Exports -export { Footer }; +export { Footer, Navbar }; //#endregion /** From a3becbbe3775090dc800a3c75d153a8d3d421b72 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:34:51 +0200 Subject: [PATCH 012/312] Add LoginForm Component The login form component has been added. It is not displayed yet. --- package.json | 3 +- .../molecules/forms/LoginForm/index.jsx | 234 ++++++++++++++++++ src/components/molecules/index.js | 3 +- 3 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 src/components/molecules/forms/LoginForm/index.jsx diff --git a/package.json b/package.json index 451b14f..2d3c089 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,8 @@ "react": "^16.8.6", "react-dom": "^16.8.6", "react-router-dom": "^5.0.1", - "react-scripts": "3.0.1" + "react-scripts": "3.0.1", + "react-text-loop": "^2.3.0" }, "repository": { "type": "git", diff --git a/src/components/molecules/forms/LoginForm/index.jsx b/src/components/molecules/forms/LoginForm/index.jsx new file mode 100644 index 0000000..5004092 --- /dev/null +++ b/src/components/molecules/forms/LoginForm/index.jsx @@ -0,0 +1,234 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// DOM bindings for React Router +import { Link } from "react-router-dom"; +// React PropTypes +import PropTypes from "prop-types"; +//> Additional +// Text animations +import TextLoop from "react-text-loop"; +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBRow, + MDBCol, + MDBAlert, + MDBBtn, + MDBPopover, + MDBPopoverBody, + MDBPopoverHeader, + MDBIcon, + MDBModal, + MDBModalBody, + MDBModalHeader, + MDBModalFooter, + MDBSelect, + MDBProgress, + MDBSelectInput, + MDBSelectOptions, + MDBSelectOption, + MDBListGroup, + MDBListGroupItem, +} from "mdbreact"; +//#endregion + +//#region > Components +/** @class A login form which contains a username and password field */ +class LoginForm extends React.Component { + state = { + login_username: "", + login_password: "", + }; + + testForError = (id) => { + if (this.state.errors) { + let rtn = this.state.errors.map((error, i) => { + if (!Array.isArray(id)) { + if (error.code === id) { + return true; + } else { + return false; + } + } else { + let innerRtn = id.map((item, ikey) => { + if (error.code === item) { + return true; + } else { + return false; + } + }); + if (innerRtn.includes(true)) { + return true; + } else { + return false; + } + } + }); + if (rtn.includes(true)) { + return true; + } else { + return false; + } + } else { + return false; + } + }; + + handleChange = (e, id) => { + this.setState({ + [e.target.name]: e.target.value, + }); + }; + + handleChangeManual = (name, value, id) => { + this.setState({ + [name]: value, + }); + }; + + removeError = (id) => { + // Preset errors to local variable + let errors = this.state.errors; + + if (errors) { + if (!Array.isArray(id)) { + errors = errors.filter(function (obj) { + return obj.code !== id; + }); + } else { + id.map((item) => { + errors = errors.filter(function (obj) { + return obj.code !== item; + }); + }); + } + + this.setState({ + errors, + }); + } + }; + + login = async (event) => { + // Prevent page from reloading + event.preventDefault(); + event.stopPropagation(); + + let errors = []; + + if (this.state.login_username === "") { + errors.push({ + code: 20, + weight: 10, + }); + } + if (this.state.login_password === "") { + errors.push({ + code: 21, + weight: 10, + }); + } + + // Check if there are any errors + if (errors.length > 0) { + this.setState({ + errors, + }); + } else { + // Proceed to login + const result = await this.props.globalFunctions.login( + this.state.login_username, + this.state.login_password + ); + console.log(result); + if (result) { + this.setState( + { + loginFail: false, + }, + () => this.props.handleLogin(result) + ); + } else { + // Login fail + //handleLogin(false); + this.setState({ + loginFail: true, + }); + } + } + }; + + render() { + const { goTo } = this.props; + + return ( + <> +
    + goTo(0)}> + + Back + +
    +

    Login to SNEK

    + {this.state.loginFail && ( + + Can not perform login. Please check your username and password. + + )} +
    + + this.handleChangeManual("login_username", e.target.value, 20) + } + value={this.state.login_username} + /> + + this.handleChangeManual("login_password", e.target.value, 21) + } + value={this.state.login_password} + /> + + Login + + +
    + + ); + } +} +//#endregion + +//#region > PropTypes +LoginForm.propTypes = { + globalFunctions: PropTypes.object, + goTo: PropTypes.func, +}; +//#endregion + +//#region > Exports +export default LoginForm; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/index.js b/src/components/molecules/index.js index ec0d4d5..9d83f5b 100644 --- a/src/components/molecules/index.js +++ b/src/components/molecules/index.js @@ -3,10 +3,11 @@ // Import all components to export them for easy access from parent components import Footer from "./Footer"; import Navbar from "./Navbar"; +import LoginForm from "./forms/LoginForm"; //#endregion //#region > Exports -export { Footer, Navbar }; +export { Footer, Navbar, LoginForm }; //#endregion /** From 8b72dfdac249cf9df3751f58381f834fc4533158 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:41:17 +0200 Subject: [PATCH 013/312] Add RegisterForm Component The login form component has been added. It is not displayed yet. snek-intel has been added but currently only as local package. --- package.json | 3 +- .../molecules/forms/RegisterForm/index.jsx | 808 ++++++++++++++++++ src/components/molecules/index.js | 3 +- 3 files changed, 812 insertions(+), 2 deletions(-) create mode 100644 src/components/molecules/forms/RegisterForm/index.jsx diff --git a/package.json b/package.json index 2d3c089..e9fcf9d 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "react-dom": "^16.8.6", "react-router-dom": "^5.0.1", "react-scripts": "3.0.1", - "react-text-loop": "^2.3.0" + "react-text-loop": "^2.3.0", + "snek-intel": "file:snek-intel-1.0.0.tgz" }, "repository": { "type": "git", diff --git a/src/components/molecules/forms/RegisterForm/index.jsx b/src/components/molecules/forms/RegisterForm/index.jsx new file mode 100644 index 0000000..ba761b1 --- /dev/null +++ b/src/components/molecules/forms/RegisterForm/index.jsx @@ -0,0 +1,808 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// DOM bindings for React Router +import { Link } from "react-router-dom"; +// React PropTypes +import PropTypes from "prop-types"; +//> Intel +import RSA, { GithubProvider } from "snek-intel/lib/utils/oauth"; +//> Additional +// Text animations +import TextLoop from "react-text-loop"; +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBRow, + MDBCol, + MDBAlert, + MDBBtn, + MDBPopover, + MDBPopoverBody, + MDBPopoverHeader, + MDBIcon, + MDBModal, + MDBModalBody, + MDBModalHeader, + MDBModalFooter, + MDBSelect, + MDBProgress, + MDBSelectInput, + MDBSelectOptions, + MDBSelectOption, + MDBListGroup, + MDBListGroupItem, +} from "mdbreact"; +//#endregion + +//#region > Components +/** + * @class A registration form. Contains all fields required for registration + * including OAuth and a selectable list of GitLab servers. + */ +class RegisterForm extends React.Component { + state = { + loading: false, + firstname: "", + lastname: "", + email: "", + password1: "", + password2: "", + username: "", + gitlab_username: "", + gitlab_servers: undefined, + gitlab_server: "Choose your organisation", + sourceList: [], + usernames: [], + promoCode: true, + code: "", + }; + + componentDidMount = () => { + this.getGitLabServers(); + }; + + toggle = () => { + if (!this.state.modalGitLab) { + this.setState({ + modalGitLab: true, + }); + } else { + this.setState({ + modalGitLab: false, + }); + } + }; + + getGitLabServers = async () => { + // Check if GitLab Servers have already been set + if (this.state.gitlab_servers === undefined) { + // Retrieve GitLab servers + const gitlab_servers = await this.props.globalFunctions.fetchGitLabServers(); + + this.setState({ + gitlab_servers, + }); + } + }; + + addGitLab = () => { + const username = this.state.gitlab_username; + const server = this.state.gitlab_server; + + console.log(username, server); + + if (username.trim() && server.trim()) { + if (server !== "Choose your organisation") { + this.connectGitLab(username, "https://" + server); + } + } + }; + + connectGitLab = async (username, platformUrl) => { + this.setState( + { + modalGitLab: false, + gitlab_username: "", + gitlab_server: "Choose your organisation", + }, + () => this.pushToSourceList("gitlab", username, platformUrl) + ); + }; + + connectGitHub = () => { + this.setState( + { + loadingGitHub: true, + }, + async () => { + const data = await RSA.acquireTokenAsync(GithubProvider); + + this.pushToSourceList( + "github", + data.username, + "https://api.github.com/graphql", + data.accessToken + ); + } + ); + }; + + pushToSourceList = (platformName, username, platformUrl, token) => { + let sourceList = this.state.sourceList; + + this.addToUsernames(username, platformName); + + sourceList.push({ + id: username.length + platformName.length + username + platformName, + user: username, + authorization: token ? "token " + token : null, + platform: { + name: platformName, + url: platformUrl, + }, + }); + + if (platformName === "github") { + this.setState({ + username, + hasGitHub: true, + sourceList, + loadingGitHub: false, + }); + } else { + // Set the new list of user information + this.setState({ + sourceList, + }); + } + }; + + addToUsernames = (username, source) => { + let usernames = this.state.usernames; + let found = false; + + for (let i = 0; i < usernames.length; i++) { + if ( + usernames[i].username === username && + usernames[i].source === source + ) { + found = true; + break; + } + } + + if (!found) { + // Make sure that only GitHub usernames are available for selection + // This aims to prevent name abuse in the first versions of this application + usernames.push({ + id: username.length + source.length + username + source, + username, + source, + verified: source === "github" ? true : false, + }); + this.setState({ + usernames, + }); + } + }; + + removeSource = (id) => { + let sourceList = this.state.sourceList.filter(function (obj) { + return obj.id !== id; + }); + let usernames = this.state.usernames.filter(function (obj) { + return obj.id !== id; + }); + this.setState({ + sourceList, + usernames, + }); + }; + + handleUserNamePick = (username) => { + this.setState({ + username, + }); + }; + + handleSelectChange = (e) => { + this.setState({ + gitlab_server: e[0], + }); + }; + + testForError = (id) => { + if (this.state.errors) { + let rtn = this.state.errors.map((error, i) => { + if (!Array.isArray(id)) { + if (error.code === id) { + return true; + } else { + return false; + } + } else { + let innerRtn = id.map((item, ikey) => { + if (error.code === item) { + return true; + } else { + return false; + } + }); + if (innerRtn.includes(true)) { + return true; + } else { + return false; + } + } + }); + if (rtn.includes(true)) { + return true; + } else { + return false; + } + } else { + return false; + } + }; + + handleChange = (e, id) => { + this.setState( + { + [e.target.name]: e.target.value, + }, + () => this.removeError(id) + ); + }; + + handleChangeManual = (name, value, id) => { + this.setState( + { + [name]: value, + }, + () => this.removeError(id) + ); + }; + + removeError = (id) => { + // Preset errors to local variable + let errors = this.state.errors; + + if (errors) { + if (!Array.isArray(id)) { + errors = errors.filter(function (obj) { + return obj.code !== id; + }); + } else { + id.map((item) => { + errors = errors.filter(function (obj) { + return obj.code !== item; + }); + }); + } + + this.setState({ + errors, + }); + } + }; + + // Handle sumbit of register form + handleSubmit = async () => { + console.log("Handle submit"); + // CHANGE TO CONST + let { + password1, + password2, + firstname, + lastname, + email, + sourceList, + username, + promoCode, + code, + } = this.state; + + // Error + let errors = []; + + // Check if passwords match + if (password1 !== "" && password2 !== "" && password1 !== password2) { + errors.push({ + code: 1, + msg: "Your passwords do not match.", + weight: 10, + }); + } + if (sourceList.length === 0) { + errors.push({ + code: 2, + msg: "No platforms are connected.", + weight: 10, + }); + } + if (firstname === "") { + errors.push({ + code: 3, + msg: "Please enter your first name.", + weight: 8, + }); + } + if (lastname === "") { + errors.push({ + code: 4, + msg: "Please enter your last name.", + weight: 8, + }); + } + if (email === "") { + errors.push({ + code: 5, + msg: "Please enter your email.", + weight: 9, + }); + } + if (username === "") { + errors.push({ + code: 6, + msg: "Please select a username from the list above.", + weight: 10, + }); + } + if (password1 === "") { + errors.push({ + code: 7, + msg: "Please enter a password.", + weight: 10, + }); + } + if (password2 === "") { + errors.push({ + code: 8, + msg: "Please repeat your password.", + weight: 10, + }); + } + if (code === "") { + errors.push({ + code: 9, + msg: "Please enter your promo code or contact us to receive one.", + weight: 5, + }); + } + + if (errors.length === 0) { + this.setState( + { + loading: true, + }, + () => { + // Cache data + let cache = {}; + console.log("Register", this.state); + let registrationData = { + sources: sourceList, + username, + email, + first_name: firstname, + last_name: lastname, + gift_code: promoCode && code !== "" ? code : null, + password: password1, + }; + this.props.globalFunctions.registerUser(registrationData); + } + ); + } else { + this.setState({ + errors, + }); + } + }; + + handleCodeChange = (e) => { + let code = e.target.value; + + if (code.length <= 14) { + if (code.length === 4 || code.length === 9) { + code = code + "-"; + } + this.setState( + { + code: code.toUpperCase(), + }, + () => this.removeError(9) + ); + } else { + return false; + } + }; + + render() { + const { goTo } = this.props; + + return ( + <> + {!this.state.loading ? ( + <> +
    + this.setState({ errors: [] }, () => goTo(0))} + > + + Back + +
    +

    So you're a Software Engineer...

    +

    + We just need a bit more information to get you started. +

    +
    + + + this.handleChange(e, 3)} + value={this.state.firstname} + /> + + + this.handleChange(e, 4)} + value={this.state.lastname} + /> + + + this.handleChange(e, 5)} + value={this.state.email} + /> + + + this.handleChange(e, [7, 1])} + value={this.state.password1} + /> + + + this.handleChange(e, [8, 1])} + value={this.state.password2} + /> + + +
    +
    + + this.setState({ promoCode: !this.state.promoCode }) + } + > + {!this.state.promoCode + ? "I have a promo code" + : "I don't have a promo code"} + +
    + {this.state.promoCode && ( + + )} +

    Connect your work

    + + You need to connect at least one account to continue. + +
    + + + + Why do I need to connect my accounts? + +
    + + + Connecting accounts + + + To generate your expressive and meaningful profile, we + require data about your work, which we acquire by fetching + it from platforms like GitHub, GitLab and BitBucket. It also + helps us verify your data. +
    + + Learn more + +
    +
    +
    +
    +
    + this.setState({ modalGitLab: true })} + disabled={ + !this.state.gitlab_servers || + (this.state.gitlab_server && + this.state.gitlab_server.length < 1) + } + > + + + + + + + + +
    +
    + + {this.state.loadingGitHub && } + {this.state.usernames.map((source, i) => { + return ( + +
    + + {source.username} + {source.verified ? ( + + + + +
    + Verified + + + + + + + This source has been{" "} + + verified + {" "} + by logging into it. + + + +
    +
    + ) : ( + + + + +
    + Not verified + + + + + + + We can not verify your identity with GitLab. + Your data is still being included. + + + +
    +
    + )} +
    + this.removeSource(source.id)} + /> +
    + ); + })} +
    +
    + + Join now + +

    + + Don't worry, you can easily connect further accounts in the + future. + +

    + + ) : ( +
    +

    + Hey, {this.state.firstname}! +

    +

    Your profile is being generated.

    +
    +
    +
    + +
    + )} + {this.state.modalGitLab && ( + + + + Add GitLab profile + + + + this.setState({ [e.target.name]: e.target.value }) + } + value={this.state.gitlab_username} + /> + + + + + Choose your organisation + + {this.state.gitlab_servers && + this.state.gitlab_servers.map((source, i) => { + return ( + + {source.organisation} + + ); + })} + + + + + + + Add + + + Cancel + + + + )} + + ); + } +} +//#endregion + +//#region > PropTypes +RegisterForm.propTypes = { + globalState: PropTypes.object, + globalFunctions: PropTypes.object, + goto: PropTypes.func, +}; +//#endregion + +//#region > Exports +export default RegisterForm; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/index.js b/src/components/molecules/index.js index 9d83f5b..d0bf7f5 100644 --- a/src/components/molecules/index.js +++ b/src/components/molecules/index.js @@ -4,10 +4,11 @@ import Footer from "./Footer"; import Navbar from "./Navbar"; import LoginForm from "./forms/LoginForm"; +import RegisterForm from "./forms/RegisterForm"; //#endregion //#region > Exports -export { Footer, Navbar, LoginForm }; +export { Footer, Navbar, LoginForm, RegisterForm }; //#endregion /** From 63efd539cb733f285b0a362d73234f6cb71900c7 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:43:49 +0200 Subject: [PATCH 014/312] Add UploadModal Component The upload modal component has been added. It is not displayed yet. --- src/components/molecules/index.js | 3 +- .../molecules/modals/UploadModal/index.jsx | 142 ++++++++++++++++++ 2 files changed, 144 insertions(+), 1 deletion(-) create mode 100644 src/components/molecules/modals/UploadModal/index.jsx diff --git a/src/components/molecules/index.js b/src/components/molecules/index.js index d0bf7f5..05feaa0 100644 --- a/src/components/molecules/index.js +++ b/src/components/molecules/index.js @@ -5,10 +5,11 @@ import Footer from "./Footer"; import Navbar from "./Navbar"; import LoginForm from "./forms/LoginForm"; import RegisterForm from "./forms/RegisterForm"; +import UploadModal from "./modals/UploadModal"; //#endregion //#region > Exports -export { Footer, Navbar, LoginForm, RegisterForm }; +export { Footer, Navbar, LoginForm, RegisterForm, UploadModal }; //#endregion /** diff --git a/src/components/molecules/modals/UploadModal/index.jsx b/src/components/molecules/modals/UploadModal/index.jsx new file mode 100644 index 0000000..7b5b5a1 --- /dev/null +++ b/src/components/molecules/modals/UploadModal/index.jsx @@ -0,0 +1,142 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// Contains the functionality for uploading a file +import Dropzone from "react-dropzone"; + +import { + MDBModal, + MDBModalHeader, + MDBIcon, + MDBModalBody, + MDBProgress, +} from "mdbreact"; +//#endregion + +//#region > Components +class UploadModal extends React.Component { + state = { + loading: false, + error: [], + }; + + onDrop = async (files) => { + if (files.length > 0) { + this.setState({ + error: [], + loading: true, + }); + this.props.uploadTalk(files[0]).then(() => { + this.setState({ + loading: false, + }); + this.props.closeModal(); + }); + } else { + this.setState({ error: ["Only PDF files can be uploaded!"] }); + } + }; + + render() { + return ( + + + Upload + + +
    + + {({ getRootProps, getInputProps, acceptedFiles }) => ( +
    + + {this.state.error.length > 0 || acceptedFiles.length > 0 ? ( +
    +
      + {acceptedFiles.length > 0 && + acceptedFiles.map((acceptedFile, i) => ( +
    • + +

      +

      {acceptedFile.name}

      +
    • + ))} +
    + {this.state.loading && ( + + Uploading file + + )} +
      + {this.state.error.length > 0 && + this.state.error.map((error, i) => ( +
    • + +

      +

      {error}

      +
    • + ))} +
    +
    + ) : ( +
    + +

    +

    Click here or drop a file to upload!

    +
    + )} +
    + )} +
    +
    +
    +
    + ); + } +} +//#endregion + +//#region > Exports +export default UploadModal; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ From 7fe6de34bb282c6695f61ebba6dd829b181a394b Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:47:53 +0200 Subject: [PATCH 015/312] Add UserActionCard Component The useractioncard modal component has been added. It is not displayed yet. --- .../molecules/UserActionCard/index.jsx | 149 ++++++++++++++ .../UserActionCard/useractioncard.scss | 182 ++++++++++++++++++ src/components/molecules/index.js | 3 +- 3 files changed, 333 insertions(+), 1 deletion(-) create mode 100644 src/components/molecules/UserActionCard/index.jsx create mode 100644 src/components/molecules/UserActionCard/useractioncard.scss diff --git a/src/components/molecules/UserActionCard/index.jsx b/src/components/molecules/UserActionCard/index.jsx new file mode 100644 index 0000000..9c79faa --- /dev/null +++ b/src/components/molecules/UserActionCard/index.jsx @@ -0,0 +1,149 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// DOM bindings for React Router +import { Link, withRouter } from "react-router-dom"; +// React PropTypes +import PropTypes from "prop-types"; + +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBRow, + MDBCol, + MDBAlert, + MDBBtn, + MDBPopover, + MDBPopoverBody, + MDBPopoverHeader, + MDBIcon, + MDBModal, + MDBModalBody, + MDBModalHeader, + MDBModalFooter, + MDBSelect, + MDBSelectInput, + MDBSelectOptions, + MDBSelectOption, + MDBListGroup, + MDBListGroupItem, +} from "mdbreact"; + +//> Components +import { RegisterForm, LoginForm } from "../forms"; + +//> Images +import { ReactComponent as SvgSoftware } from "../../../assets/header/dev.svg"; +import { ReactComponent as SvgMedia } from "../../../assets/header/media.svg"; + +//> CSS +import "./useractioncard.scss"; +//#endregion + +//#region > Components +class UserActionCard extends React.Component { + state = { + activeItem: 0, + }; + + goTo = (item) => { + this.setState({ + activeItem: item, + }); + }; + + render() { + const { globalState, globalFunctions } = this.props; + const { activeItem } = this.state; + + return ( +
    + {activeItem === 0 && ( + <> + this.setState({ activeItem: 1 })} + > + Login to SNEK + +
    +
    + + or + +
    +
    +

    Choose your snek

    +

    What is your main profession?

    + + +
    this.setState({ activeItem: 2 })} + > +

    Software Engineer

    + +
    +
    + +
    this.setState({ activeItem: 3 })} + > +

    Media Engineer

    + +
    +
    +
    + + )} + {activeItem === 1 && ( + + )} + {activeItem === 2 && ( + + )} + {activeItem === 3 && ( + <> +
    + this.goTo(0)} + > + + Back + +
    + +

    + + Media Engineer profiles are not yet supported +

    + this.goTo(2)}> + Create Software Engineer profile + +
    + + )} +
    + ); + } +} +//#endregion + +//#region > PropTypes +UserActionCard.propTypes = { + globalState: PropTypes.object, + globalFunctions: PropTypes.object, +}; +//#endregion + +//#region > Exports +export default UserActionCard; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/UserActionCard/useractioncard.scss b/src/components/molecules/UserActionCard/useractioncard.scss new file mode 100644 index 0000000..f06258a --- /dev/null +++ b/src/components/molecules/UserActionCard/useractioncard.scss @@ -0,0 +1,182 @@ +#useractionscard { + // Register selection + svg { + padding-top: 0.5rem; + max-width: 60%; + height: auto; + transition: all 0.2s ease; + filter: saturate(0.5); + transition: all 0.2s ease; + } + .selectType { + transition: all 0.2s ease; + p.lead { + border-top: none; + transition: all 0.2s ease; + } + cursor: pointer; + &:hover { + transform: scale(1.1); + svg { + filter: saturate(1); + } + & > p.lead { + color: #77bd43; + font-weight: bold; + } + } + } + input { + &[name="code"] { + letter-spacing: 1px; + } + &:focus { + color: #495057; + border-color: #77bd43; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); + } + &.error { + color: #495057; + border-color: lightcoral; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(240, 128, 128, 0.25); + } + } + .connect { + .btn { + padding: 10px 13px 10px 13px; + &.disabled { + i { + &:after { + color: lightgrey !important; + } + } + } + i { + &.fab { + &:after { + transition: all 0.1s ease; + position: absolute; + font-family: "Font Awesome 5 Free"; + content: "\f055"; + font-weight: 900; + font-size: 10px; + color: #77bd43; + right: 5px; + bottom: 5px; + } + } + } + &:hover { + i { + &:after { + color: lighten(#77bd43, 15%); + transform: scale(1.5); + } + } + } + } + } + .btn { + &.text-muted { + color: lighten(#6c757d, 25%) !important; + } + } + + // Modal + .modal-dialog.modal-notify.modal-orange .modal-header { + background-color: #ff8910 !important; + } + .modal-orange { + .select-wrapper { + &:focus { + color: #495057; + border-color: #77bd43; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); + } + input { + color: lighten(#495057, 20%); + margin-bottom: 0; + } + li:not(.disabled) { + span { + color: #495057; + } + } + li { + margin-bottom: 0 !important; + } + } + } + .list-group-item { + $borderRadius: 6px; + + display: flex; + justify-content: space-between; + align-items: center; + transition: all 0.2s ease; + &.list-item-github { + border-left: 5px #333 solid; + } + &.list-item-gitlab { + border-left: 5px #f57c00 solid; + } + &.list-item-bitbucket { + border-left: 5px #1976d2 solid; + } + .company-icon { + margin-right: 0.4rem; + &.fa-github { + color: #333; + } + &.fa-gitlab { + color: #f57c00; + } + &.fa-bitbucket { + color: #1976d2; + } + } + .close-icon { + color: lightgray; + cursor: pointer; + transition: color 0.2s ease; + &:hover { + color: lightcoral; + } + } + &:first-of-type { + border-top-left-radius: $borderRadius; + border-top-right-radius: $borderRadius; + } + &:last-of-type { + border-bottom-left-radius: $borderRadius; + border-bottom-right-radius: $borderRadius; + } + .username-icon { + color: lightgray; + cursor: pointer; + transition: color 0.2s ease; + &:hover { + color: #77bd43; + } + } + &:first-of-type { + border-top-left-radius: $borderRadius; + border-top-right-radius: $borderRadius; + } + &:last-of-type { + border-bottom-left-radius: $borderRadius; + border-bottom-right-radius: $borderRadius; + } + } + .progress { + height: 10px; + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/index.js b/src/components/molecules/index.js index 05feaa0..2b9a29a 100644 --- a/src/components/molecules/index.js +++ b/src/components/molecules/index.js @@ -6,10 +6,11 @@ import Navbar from "./Navbar"; import LoginForm from "./forms/LoginForm"; import RegisterForm from "./forms/RegisterForm"; import UploadModal from "./modals/UploadModal"; +import UserActionCard from "./UserActionCard"; //#endregion //#region > Exports -export { Footer, Navbar, LoginForm, RegisterForm, UploadModal }; +export { Footer, Navbar, LoginForm, RegisterForm, UploadModal, UserActionCard }; //#endregion /** From 35e72a75cbd47fdde116316dbbb85a3ecdae611a Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:54:38 +0200 Subject: [PATCH 016/312] Adjust newlines There are only newlines to separate internal and external imports in the import section now. --- src/components/atoms/charts/Calendar2D/index.jsx | 2 -- src/components/atoms/charts/Calendar3D/index.jsx | 1 - src/components/atoms/charts/ContribRadar/index.jsx | 1 - src/components/atoms/charts/LatestActivity/index.jsx | 1 - 4 files changed, 5 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index c7c4fa9..3aa8b09 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -1,14 +1,12 @@ //#region > Imports // Contains all the functionality necessary to define React components import React from "react"; - //> Additional // Used to display popovers on contrib chart items import tippy from "tippy.js"; import "tippy.js/dist/tippy.css"; // Used to display the time in a readable format import moment from "moment"; - //> MDB // "Material Design for Bootstrap" is a great UI design framework import { MDBRow, MDBCol } from "mdbreact"; diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx index 030d1ae..574d302 100644 --- a/src/components/atoms/charts/Calendar3D/index.jsx +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -2,7 +2,6 @@ //> React // Contains all the functionality necessary to define React components import React from "react"; - //> Additional packages // Used to display the time in a readable format import moment from "moment"; diff --git a/src/components/atoms/charts/ContribRadar/index.jsx b/src/components/atoms/charts/ContribRadar/index.jsx index 4a09e61..f5b2b4b 100644 --- a/src/components/atoms/charts/ContribRadar/index.jsx +++ b/src/components/atoms/charts/ContribRadar/index.jsx @@ -2,7 +2,6 @@ //> React // Contains all the functionality necessary to define React components import React from "react"; - //> Additional // Charts for displaying user contribution distribution (Chart.js 2) import { Radar } from "react-chartjs-2"; diff --git a/src/components/atoms/charts/LatestActivity/index.jsx b/src/components/atoms/charts/LatestActivity/index.jsx index 4e479f7..d6f5399 100644 --- a/src/components/atoms/charts/LatestActivity/index.jsx +++ b/src/components/atoms/charts/LatestActivity/index.jsx @@ -2,7 +2,6 @@ //> React // Contains all the functionality necessary to define React components import React from "react"; - //> Additional // Charts for displaying user contribution distribution (Chart.js 2) import { Line } from "react-chartjs-2"; From 22cee596b9752a615b00a924641a592bb14f4f4b Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 13:56:15 +0200 Subject: [PATCH 017/312] Adjust newlines There are only newlines to separate internal and external imports in the import section now. --- src/components/atoms/Pinned/index.jsx | 1 - src/components/atoms/Project/index.jsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/atoms/Pinned/index.jsx b/src/components/atoms/Pinned/index.jsx index 8c046c2..988fa62 100644 --- a/src/components/atoms/Pinned/index.jsx +++ b/src/components/atoms/Pinned/index.jsx @@ -4,7 +4,6 @@ import React from "react"; // React PropTypes import PropTypes from "prop-types"; - //> MDB // "Material Design for Bootstrap" is a great UI design framework import { diff --git a/src/components/atoms/Project/index.jsx b/src/components/atoms/Project/index.jsx index d6f11e0..95c53f4 100644 --- a/src/components/atoms/Project/index.jsx +++ b/src/components/atoms/Project/index.jsx @@ -4,7 +4,6 @@ import React from "react"; // React PropTypes import PropTypes from "prop-types"; - //> MDB // "Material Design for Bootstrap" is a great UI design framework import { From 79f5fc54f43a4199e79b6344ba8abd78ef2ff69e Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 14:04:10 +0200 Subject: [PATCH 018/312] Remove unused imports All imports which are currently not used are removed now. --- .../molecules/UserActionCard/index.jsx | 23 +----------------- .../molecules/forms/LoginForm/index.jsx | 24 +------------------ .../molecules/forms/RegisterForm/index.jsx | 3 --- 3 files changed, 2 insertions(+), 48 deletions(-) diff --git a/src/components/molecules/UserActionCard/index.jsx b/src/components/molecules/UserActionCard/index.jsx index 9c79faa..854aba8 100644 --- a/src/components/molecules/UserActionCard/index.jsx +++ b/src/components/molecules/UserActionCard/index.jsx @@ -2,33 +2,12 @@ //> React // Contains all the functionality necessary to define React components import React from "react"; -// DOM bindings for React Router -import { Link, withRouter } from "react-router-dom"; // React PropTypes import PropTypes from "prop-types"; //> MDB // "Material Design for Bootstrap" is a great UI design framework -import { - MDBRow, - MDBCol, - MDBAlert, - MDBBtn, - MDBPopover, - MDBPopoverBody, - MDBPopoverHeader, - MDBIcon, - MDBModal, - MDBModalBody, - MDBModalHeader, - MDBModalFooter, - MDBSelect, - MDBSelectInput, - MDBSelectOptions, - MDBSelectOption, - MDBListGroup, - MDBListGroupItem, -} from "mdbreact"; +import { MDBRow, MDBCol, MDBAlert, MDBBtn, MDBIcon } from "mdbreact"; //> Components import { RegisterForm, LoginForm } from "../forms"; diff --git a/src/components/molecules/forms/LoginForm/index.jsx b/src/components/molecules/forms/LoginForm/index.jsx index 5004092..e60b858 100644 --- a/src/components/molecules/forms/LoginForm/index.jsx +++ b/src/components/molecules/forms/LoginForm/index.jsx @@ -2,8 +2,6 @@ //> React // Contains all the functionality necessary to define React components import React from "react"; -// DOM bindings for React Router -import { Link } from "react-router-dom"; // React PropTypes import PropTypes from "prop-types"; //> Additional @@ -11,27 +9,7 @@ import PropTypes from "prop-types"; import TextLoop from "react-text-loop"; //> MDB // "Material Design for Bootstrap" is a great UI design framework -import { - MDBRow, - MDBCol, - MDBAlert, - MDBBtn, - MDBPopover, - MDBPopoverBody, - MDBPopoverHeader, - MDBIcon, - MDBModal, - MDBModalBody, - MDBModalHeader, - MDBModalFooter, - MDBSelect, - MDBProgress, - MDBSelectInput, - MDBSelectOptions, - MDBSelectOption, - MDBListGroup, - MDBListGroupItem, -} from "mdbreact"; +import { MDBAlert, MDBBtn, MDBIcon } from "mdbreact"; //#endregion //#region > Components diff --git a/src/components/molecules/forms/RegisterForm/index.jsx b/src/components/molecules/forms/RegisterForm/index.jsx index ba761b1..be69cdf 100644 --- a/src/components/molecules/forms/RegisterForm/index.jsx +++ b/src/components/molecules/forms/RegisterForm/index.jsx @@ -2,8 +2,6 @@ //> React // Contains all the functionality necessary to define React components import React from "react"; -// DOM bindings for React Router -import { Link } from "react-router-dom"; // React PropTypes import PropTypes from "prop-types"; //> Intel @@ -16,7 +14,6 @@ import TextLoop from "react-text-loop"; import { MDBRow, MDBCol, - MDBAlert, MDBBtn, MDBPopover, MDBPopoverBody, From e4ab597f7bf510793c406bcf2460f11b1bcea504 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 14:00:44 +0200 Subject: [PATCH 019/312] Remove unused imports All imports which are currently not used are removed now. --- src/components/atoms/Pinned/index.jsx | 9 +-------- src/components/atoms/Project/index.jsx | 10 +--------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/components/atoms/Pinned/index.jsx b/src/components/atoms/Pinned/index.jsx index 988fa62..e348cf4 100644 --- a/src/components/atoms/Pinned/index.jsx +++ b/src/components/atoms/Pinned/index.jsx @@ -6,14 +6,7 @@ import React from "react"; import PropTypes from "prop-types"; //> MDB // "Material Design for Bootstrap" is a great UI design framework -import { - MDBContainer, - MDBRow, - MDBCol, - MDBCard, - MDBCardBody, - MDBIcon, -} from "mdbreact"; +import { MDBRow, MDBCol, MDBCard, MDBCardBody, MDBIcon } from "mdbreact"; //> CSS import "./pinned.scss"; diff --git a/src/components/atoms/Project/index.jsx b/src/components/atoms/Project/index.jsx index 95c53f4..a8c0eae 100644 --- a/src/components/atoms/Project/index.jsx +++ b/src/components/atoms/Project/index.jsx @@ -6,15 +6,7 @@ import React from "react"; import PropTypes from "prop-types"; //> MDB // "Material Design for Bootstrap" is a great UI design framework -import { - MDBContainer, - MDBRow, - MDBCol, - MDBAlert, - MDBInput, - MDBBtn, - MDBIcon, -} from "mdbreact"; +import { MDBCol, MDBIcon } from "mdbreact"; //#endregion //#region > Components From b4efab60ca1f7ed3728e4de6d106b28999371761 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 14:38:33 +0200 Subject: [PATCH 020/312] Add assets Assests for the footer, navbar and userActionCard has been added. --- src/assets/header/dev.svg | 62 +++++ src/assets/header/media.svg | 472 +++++++++++++++++++++++++++++++++ src/assets/navigation/logo.png | Bin 0 -> 4744 bytes 3 files changed, 534 insertions(+) create mode 100644 src/assets/header/dev.svg create mode 100644 src/assets/header/media.svg create mode 100644 src/assets/navigation/logo.png diff --git a/src/assets/header/dev.svg b/src/assets/header/dev.svg new file mode 100644 index 0000000..f2fb85b --- /dev/null +++ b/src/assets/header/dev.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/header/media.svg b/src/assets/header/media.svg new file mode 100644 index 0000000..135e7a6 --- /dev/null +++ b/src/assets/header/media.svg @@ -0,0 +1,472 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/navigation/logo.png b/src/assets/navigation/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..148da9231cf8b1ae113e57ff307826ef34f23907 GIT binary patch literal 4744 zcmd5=2~ZQ~9*!8*&&?i?nu~0Jpp_?3Lqi)CmXalv5?a9HdK??pN) zXpvtqv1lQIlKjb^@>~rVt3XBRah^e?R5O^tjo+ykW1o%30zR*kMZeIEFEbkCh4}{X z+%-Cihd7G?0)i2q1a*eQA{a%TctQ}83P7m<5&@7HgF#FvH6cvC%flvsr8~_uq*5d|1&5Z5Q;6X8jPNCH+G-{qv zBQDp(=-v3Nr(Geaw7qK8OgBs{U;+cK6+q6QF{DmLZIni@VWKqeVDBZrAw&|r%C#{% zWv9m^A)u6$ic;$tmKW+Zz(VWm+spn|UsS4IZbt7J%ZAYn$XmIY;CL-12&5QIjE+6g8s2M%3CMX{dH$EGy zvqC{)FeQaxSV#gWA&~-7AuIu;au^0siBL>aB3J~=$sTzR4H09kF{6A}kCGaK)$z(X zl%{AJfgnIc3Q+(iVKE?;;6gwI<6?pWNeBdmJ=*+r3U*B3%Gb3Ty&_qSw3tLG1f&2; zDgpsi1k(VHLpXq-xEN)9f)PZ*=NT&lW7V)O;l^HcGs@fY&)6Fr4Uul`wV}#TG}`vEnVo z^nK?yoAnRrYQekwXYklR_nshNIY`qKz}6fJ&;(2X zs8|jIa-kR((-0vf<R3wmT7_wG9nRhe zC>`U*r*#??57%my3Zk?11+i+fd(rk5IZv1nDc8xf} zAE#f}yGK`Xcp1yB^L~T9ZO(mYXR#L^j9r=US)x)>go{LCl1)8A0E7r;Hy}#08=8cr zh@2+nppY=;->6OV-!4&OTXe$k+MTxNh`lHqAA4`;>`U(*pHj2aNXOpb2NZEc98Ui+ zJ|42*u;SLu3zfq{hLxHJ?8u`!c4S;XCd$oq>8s!ddJI#Td3&$=ZqW5*sptD;?DKNp zG0cgpnwVn!$kSu;jbY zx}7>dR#L!J{-Y9on#l-`=jDBWZo~_J(;v8>o!OH-bODy#$3JO&5g!~;*Y9*`ZtO1Z zw8Y5sW4^acxp`h4VBUZJ;KZlNg{{k1dRf^nLHb!It+BG$`}mWKKTk+BpPzW^W|4p6 z8ry^pGutiMMIo)W`J9@hwgna!O}6mN>o|^yF^%#J#PQon+L#Q_HEDCNAHO2n>-l^M zaN7CWuCrS^!oS$WrI#{8Yeq6(b0a;6UNgnY&Rt8kxO?*AwX1tSEd+#9t)D#pF=ONB z8$Me1;^x%+yRKGveZtW}Ee@V_&%_sIUYqftURCaW^c%yRwREBK`#Kfo_UMeP@3Pbh zDLkxn_@UswF|D~r2f5nI<|x93r5^D=(P~IH88Tr|Ri2GmL|cki%m5^!?qJnp!tQEI zb#~r`JuUhh&#hV%6I-4dYO~e;jbEDH{v7itXG^R1g35!jwMJ!8M^`*`opsDAxQlVQ8xef^qhXSZZMcZu*U)A!jV8yq&Woqn=UU5g6B_hf94mHbrV z&6OCIFQlVQB+KjtNahbw=Q|FEx_((U(}uf+!q;VPXHGO#>@9mhUE0~Ozt%a>#4-6u zaAH1MGi+wf%%a=y=q!r7W>z%=Cwjv9U$dxtqq_&>Z0Ii#K(xr0yO@9q;=& zo~hkso1QB4Gq1SyP4kfQCfvnjp5ds^u_Xb+!xX$%_8JsHivkv!GUukCP2^Xvs<4S?T?rM{Wfmp)R!OA2K_ zjyQ4SWZxRg`0)q0+uJQpB|BWM$jLk%`V>7=yJx_HM&BIAKH{YznQ4P3|M1O%sEb1< zt{!+OX#FQS74D6YbM~Cv>GW2=6|$GlGU~UOrkn|1S)N=$Cl)S?LZ7WooiZ9*{A*Lj z236H=jcwjQiacyqeBabK0s;*TTQ8=Haq^0Yuy3 z#^v(0lh1MItue_sq-v_pf4b8J<(f5TxWd`oC5`J-i>}P!8oV1nb=}#Zin)+x{|mFe z$nB_gbV5R#dZx?bS>|b(_Ibk#iVGv^_j-%$Y^pC0i<>t2%oAVl??}j;*b06c7U_CmX6#N_gV8PDm%Gt<7k(~+55x^_u9$!lTqbN zeN7w-~LGtj5*mZ75LcaM?Ev4N%MDrd%2 zemp1YzWVB@oh?=Orqx@=E;+h*L3!EdSz*DkKDS@?d*0UIq)oa1@kjBakYc93N#VG$ z0(nr=CcA(6c5}PACZ){AX1Xpa&8qOL@JZJD1J2!>Gj z2iC6}6;pr&IlV|eHSST#Gkb@c@k#U(aPR0Em)kE^6`%3X_alxp3|zL98*TL&-#KfZ zWlE@Z`++ZB7Dm`?9yfh`>4gyxa&KkUQ! e);zar6ihVLF$J~(TaEuK^6~WZI6QSh(tiLivFx${ literal 0 HcmV?d00001 From d5fb25d160d0649581437d94418e2facb7cc452e Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 15:08:01 +0200 Subject: [PATCH 021/312] Improve documentation quality The documentation quality has been improved due to a request by @pinterid. --- src/components/atoms/ScrollToTop/index.jsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/atoms/ScrollToTop/index.jsx b/src/components/atoms/ScrollToTop/index.jsx index 007125e..156f42d 100644 --- a/src/components/atoms/ScrollToTop/index.jsx +++ b/src/components/atoms/ScrollToTop/index.jsx @@ -1,12 +1,15 @@ +//#region > Imports //> React // Contains all the functionality necessary to define React components import React from "react"; // DOM bindings for React Router import { withRouter } from "react-router-dom"; +//#endregion +//#region > Components /** * @class ScrollToTop Component - * @description When reloading or switching a page, ReactJS now starts at the + * @description When reloading or switching a page, ReactJS now starts at the * top of the page, and no longer on the last position. */ class ScrollToTop extends React.Component { @@ -23,8 +26,11 @@ class ScrollToTop extends React.Component { return this.props.children; } } +//#endregion +//#region > Exports export default withRouter(ScrollToTop); +//#endregion /** * SPDX-License-Identifier: (EUPL-1.2) From 03e03e9060cfcd61bc19b562ff263fafad37fd12 Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 15:15:09 +0200 Subject: [PATCH 022/312] Apply suggestions from code review Most of the suggestions have been applied. All other comments will be resolved imidiately. Co-authored-by: Pinterics David <55298934+pinterid@users.noreply.github.com> --- .../atoms/charts/Calendar2D/index.jsx | 1 + .../atoms/charts/Calendar3D/index.jsx | 26 +++++++++++-------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index 3aa8b09..e7ab55a 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -133,6 +133,7 @@ class Calender2D extends React.Component { displayDailyInfo = (day, wkey, dkey) => { let cname = "item-" + wkey + "-" + dkey; + if (day.total > 0 && day.total !== 1) { tippy(`.${cname}`, { content: `${day.total} contributions on ${moment(day.date).format( diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx index 574d302..4ae70ee 100644 --- a/src/components/atoms/charts/Calendar3D/index.jsx +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -13,14 +13,13 @@ import "./calendar3d.scss"; //#region > Components /** * @class A three dimensional calendar which displays each days contributions, - * and contribution related statistics e.g. busiest days and streaks + * and contribution related statistics e.g. busiest days and streaks. */ class Calendar3D extends React.Component { constructor(props) { super(props); this.myInput = React.createRef(); - this.state = { width: 0, hue: 0, @@ -31,6 +30,8 @@ class Calendar3D extends React.Component { if (this.props.platformData) { // Add resize listener window.addEventListener("resize", this.updateDimensions); + + this.setState( this.setState( { width: this.myInput.current.offsetWidth, @@ -49,12 +50,6 @@ class Calendar3D extends React.Component { window.removeEventListener("resize", this.updateDimensions); } - componentWillReceiveProps = (nextProps) => { - // Use caching for year change - //console.log(this.props.year); - //console.log(nextProps.year); - }; - updateDimensions = () => { this.setState( { @@ -66,6 +61,8 @@ class Calendar3D extends React.Component { renderTopStats() { let countTotal, averageCount, datesTotal, maxCount, dateBest, contribData; + + if (this.props.year) { if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -81,10 +78,12 @@ class Calendar3D extends React.Component { Math.round( (contribData.contributions.total / 365 + Number.EPSILON) * 100 ) / 100; + datesTotal = moment(contributionCalendar.startDate).format("MMM DD, YYYY") + " - " + moment(contributionCalendar.endDate).format("MMM DD, YYYY"); + /* Busiest day */ maxCount = contribData.busiestDay.total; dateBest = moment(contribData.busiestDay.date); @@ -121,6 +120,7 @@ class Calendar3D extends React.Component { renderBottomStats() { let streakLongest, datesLongest, streakCurrent, datesCurrent, contribData; + if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -182,17 +182,17 @@ class Calendar3D extends React.Component { renderIsometrics = () => { if (this.context) { const obelisk = require("obelisk.js"); - // Create a canvas 2D point for pixel view world let point = new obelisk.Point(70, 70); - // Create view instance to nest everything // Canvas could be either DOM or jQuery element let pixelView = new obelisk.PixelView(this.context, point); + pixelView.clear(); // Get contributions of the selected year let contribData; + if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -205,18 +205,20 @@ class Calendar3D extends React.Component { // Define basic variables let SIZE = 2 * Math.round(this.state.width / 80 / 2); + if (SIZE <= 8) { SIZE = 8; } + let MAXHEIGHT = 100; let x = 0; let y = 0; let maxCount = 0; // Max number of contributions / day in the last year - let values = []; contributions.weeks.map((week, wkey) => { values[wkey] = []; + week.days.map((day, dkey) => { // Get max number of contributions if (day.total > maxCount) { @@ -230,6 +232,7 @@ class Calendar3D extends React.Component { week.map((day, di) => { // Normalize the values to achieve even distribution let cubeHeight = 3; + if (maxCount > 0) { cubeHeight += parseInt((MAXHEIGHT / maxCount) * day.total); } @@ -308,6 +311,7 @@ class Calendar3D extends React.Component { const cache = localStorage.getItem("3dChart"); if (cache) { const cacheObject = JSON.parse(cache); + if (cacheObject.timestamp > new Date().getTime() - 3600000) { //this.renderCache(); window.setTimeout(() => this.renderIsometrics(), 0); From 3181a53cc9383c9461efbe1e01ae840193500617 Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 15:21:54 +0200 Subject: [PATCH 023/312] Apply suggestions from code review All other suggestions are implemented now. --- src/components/atoms/charts/Calendar2D/index.jsx | 7 ++----- src/components/atoms/charts/Calendar3D/index.jsx | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index e7ab55a..ce0274e 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -22,8 +22,8 @@ const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; class Calender2D extends React.Component { constructor(props) { super(props); + this.myInput = React.createRef(); - this.state = { width: 0, hue: 0, @@ -34,11 +34,8 @@ class Calender2D extends React.Component { componentDidMount = () => { // Fill calendar this.setCalendar(this.props); - // Add resize listener window.addEventListener("resize", this.updateDimensions); - - // We could implement color RGB cycling here }; componentWillUnmount() { @@ -93,9 +90,9 @@ class Calender2D extends React.Component { getEachMonth = (pos) => { // Create new empty array let month = new Array(); - // Get current month let current; + if (this.props.year) { current = 0; } else { diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx index 4ae70ee..2dc14d8 100644 --- a/src/components/atoms/charts/Calendar3D/index.jsx +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -61,8 +61,8 @@ class Calendar3D extends React.Component { renderTopStats() { let countTotal, averageCount, datesTotal, maxCount, dateBest, contribData; + - if (this.props.year) { if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -309,6 +309,7 @@ class Calendar3D extends React.Component { checkCache = () => { const cache = localStorage.getItem("3dChart"); + if (cache) { const cacheObject = JSON.parse(cache); From 96f32fbf708230a985c0139f21321fcbc3cfbe1d Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 15:42:52 +0200 Subject: [PATCH 024/312] Improve code quality The quality of the code has been improved. --- .../atoms/charts/Calendar2D/index.jsx | 6 +- .../atoms/charts/Calendar3D/index.jsx | 65 +++++++++---------- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index ce0274e..eec1093 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -22,7 +22,7 @@ const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; class Calender2D extends React.Component { constructor(props) { super(props); - + this.myInput = React.createRef(); this.state = { width: 0, @@ -92,7 +92,7 @@ class Calender2D extends React.Component { let month = new Array(); // Get current month let current; - + if (this.props.year) { current = 0; } else { @@ -130,7 +130,7 @@ class Calender2D extends React.Component { displayDailyInfo = (day, wkey, dkey) => { let cname = "item-" + wkey + "-" + dkey; - + if (day.total > 0 && day.total !== 1) { tippy(`.${cname}`, { content: `${day.total} contributions on ${moment(day.date).format( diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx index 2dc14d8..6322686 100644 --- a/src/components/atoms/charts/Calendar3D/index.jsx +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -30,8 +30,7 @@ class Calendar3D extends React.Component { if (this.props.platformData) { // Add resize listener window.addEventListener("resize", this.updateDimensions); - - this.setState( + this.setState( { width: this.myInput.current.offsetWidth, @@ -62,7 +61,6 @@ class Calendar3D extends React.Component { renderTopStats() { let countTotal, averageCount, datesTotal, maxCount, dateBest, contribData; - if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -78,20 +76,19 @@ class Calendar3D extends React.Component { Math.round( (contribData.contributions.total / 365 + Number.EPSILON) * 100 ) / 100; - + datesTotal = moment(contributionCalendar.startDate).format("MMM DD, YYYY") + " - " + moment(contributionCalendar.endDate).format("MMM DD, YYYY"); - + /* Busiest day */ maxCount = contribData.busiestDay.total; dateBest = moment(contribData.busiestDay.date); dateBest = dateBest.isValid() ? dateBest.format("MMM DD") : "-"; - let html; - - html = `
    \n + return { + __html: `
    \n \n \n 1 year total\n @@ -114,13 +111,13 @@ class Calendar3D extends React.Component { \n \n \n -
    `; - return { __html: html }; +
    `, + }; } renderBottomStats() { let streakLongest, datesLongest, streakCurrent, datesCurrent, contribData; - + if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -152,9 +149,8 @@ class Calendar3D extends React.Component { datesCurrent = "-"; } - let html; - - html = `
    \n + return { + __html: `
    \n \n \n Longest streak\n @@ -175,8 +171,8 @@ class Calendar3D extends React.Component { \n \n \n -
    `; - return { __html: html }; +
    `, + }; } renderIsometrics = () => { @@ -187,12 +183,12 @@ class Calendar3D extends React.Component { // Create view instance to nest everything // Canvas could be either DOM or jQuery element let pixelView = new obelisk.PixelView(this.context, point); - + pixelView.clear(); // Get contributions of the selected year let contribData; - + if (this.props.year) { contribData = this.props.platformData.statistic.years.find( (element) => element.year === this.props.year @@ -204,13 +200,13 @@ class Calendar3D extends React.Component { let contributions = contribData.calendar; // Define basic variables - let SIZE = 2 * Math.round(this.state.width / 80 / 2); - - if (SIZE <= 8) { - SIZE = 8; + const size = 2 * Math.round(this.state.width / 80 / 2); + + if (size <= 8) { + size = 8; } - - let MAXHEIGHT = 100; + + const maxHight = 100; let x = 0; let y = 0; let maxCount = 0; // Max number of contributions / day in the last year @@ -218,7 +214,7 @@ class Calendar3D extends React.Component { contributions.weeks.map((week, wkey) => { values[wkey] = []; - + week.days.map((day, dkey) => { // Get max number of contributions if (day.total > maxCount) { @@ -232,9 +228,9 @@ class Calendar3D extends React.Component { week.map((day, di) => { // Normalize the values to achieve even distribution let cubeHeight = 3; - + if (maxCount > 0) { - cubeHeight += parseInt((MAXHEIGHT / maxCount) * day.total); + cubeHeight += parseInt((maxHight / maxCount) * day.total); } // Offsets @@ -254,14 +250,14 @@ class Calendar3D extends React.Component { var animHeight = 3; function draw() { - let dimension = new obelisk.CubeDimension(SIZE, SIZE, animHeight); - let p3d = new obelisk.Point3D(SIZE * x, SIZE * y, 0); + let dimension = new obelisk.CubeDimension(size, size, animHeight); + let p3d = new obelisk.Point3D(size * x, size * y, 0); let cube = new obelisk.Cube(dimension, color, false); // Render cube primitive into view pixelView.renderObject(cube, p3d); if (animHeight < cubeHeight) { - if (parseInt((MAXHEIGHT / maxCount) * day.total) > 0) { + if (parseInt((maxHight / maxCount) * day.total) > 0) { animHeight += 1; } else { animHeight = 1; @@ -272,8 +268,8 @@ class Calendar3D extends React.Component { } draw(); } else { - let dimension = new obelisk.CubeDimension(SIZE, SIZE, cubeHeight); - let p3d = new obelisk.Point3D(SIZE * x, SIZE * y, 0); + let dimension = new obelisk.CubeDimension(size, size, cubeHeight); + let p3d = new obelisk.Point3D(size * x, size * y, 0); let cube = new obelisk.Cube(dimension, color, false); // Render cube primitive into view @@ -283,6 +279,7 @@ class Calendar3D extends React.Component { } }); }); + if (this.state.loading) { this.setState({ loading: false, @@ -309,10 +306,10 @@ class Calendar3D extends React.Component { checkCache = () => { const cache = localStorage.getItem("3dChart"); - + if (cache) { const cacheObject = JSON.parse(cache); - + if (cacheObject.timestamp > new Date().getTime() - 3600000) { //this.renderCache(); window.setTimeout(() => this.renderIsometrics(), 0); From dfe5ccb512f97fa3924814ed0717c7cc5a992602 Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 15:47:50 +0200 Subject: [PATCH 025/312] Improve documentation quality The documentation quality was improved due to a request by Codacy. --- src/components/atoms/Pinned/pinned.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/atoms/Pinned/pinned.scss b/src/components/atoms/Pinned/pinned.scss index 729eeed..946b4f5 100644 --- a/src/components/atoms/Pinned/pinned.scss +++ b/src/components/atoms/Pinned/pinned.scss @@ -5,7 +5,7 @@ } } -/** +/** * SPDX-License-Identifier: (EUPL-1.2) * Copyright © Simon Prast */ From c164d876c10ac82a737976a0a814b3ec54355b0e Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 15:49:20 +0200 Subject: [PATCH 026/312] Improve code quality The code quality has been improved due to a request of Codacy. --- src/components/molecules/Footer/footer.scss | 18 +++++++-- src/components/molecules/Navbar/navbar.scss | 12 ++++++ .../UserActionCard/useractioncard.scss | 38 ++++++++++++++++++- 3 files changed, 63 insertions(+), 5 deletions(-) diff --git a/src/components/molecules/Footer/footer.scss b/src/components/molecules/Footer/footer.scss index 0242074..f891586 100644 --- a/src/components/molecules/Footer/footer.scss +++ b/src/components/molecules/Footer/footer.scss @@ -4,19 +4,23 @@ footer { // Footer link items ul { padding: 0; + li { background: rgba(255, 255, 255, 0.05); transition: all 0.1s ease; padding: 1rem !important; align-items: center; + i { width: 30px; text-align: center; padding-right: 0.5rem; } + &:hover { background: rgba(255, 255, 255, 0.1); } + .badge { box-shadow: none; } @@ -60,28 +64,34 @@ footer { &.white { ul li { background: rgba(0, 0, 0, 0.05); + &:hover { background: rgba(0, 0, 0, 0.1); } } + .footer-copyright { background: rgba(0, 0, 0, 0.1); color: #212121 !important; } + ul { i { color: #212121 !important; } + a { color: #212121 !important; } } } + .madeby { a { color: #212121; border-bottom: solid #77bd43 2px; transition: border-bottom 0.2s ease; + &:hover { border-bottom: solid #0366d6 2px; } @@ -89,7 +99,7 @@ footer { } } -/** -* SPDX-License-Identifier: (EUPL-1.2) -* Copyright © Simon Prast -*/ +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/molecules/Navbar/navbar.scss b/src/components/molecules/Navbar/navbar.scss index 40f97c8..3bc9e06 100644 --- a/src/components/molecules/Navbar/navbar.scss +++ b/src/components/molecules/Navbar/navbar.scss @@ -4,27 +4,34 @@ .navbar { box-shadow: none; background: #f0f0f0; + li { align-self: center; + .dropdown { img { max-height: 30px; width: auto; border-radius: 0.2em; } + .dropdown-toggle::after { vertical-align: initial; } + .dropdown-menu { padding: 0; + .dropdown-item { transition: all 0.2s ease; box-shadow: none !important; + &:focus { box-shadow: none !important; background-color: lightgrey !important; color: red !important; } + &:hover { box-shadow: none !important; background-color: #f0f0f0 !important; @@ -33,9 +40,11 @@ } } } + a { font-weight: bold; } + &.active { a { background-color: inherit !important; @@ -43,6 +52,7 @@ } } } + input[type="search"] { &:focus { color: #495057; @@ -52,6 +62,7 @@ box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); } } + // Remove search field delete button input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-cancel-button, @@ -59,6 +70,7 @@ input[type="search"]::-webkit-search-results-decoration { -webkit-appearance: none; } + .spacer { margin-left: 1rem; padding-left: 1rem; diff --git a/src/components/molecules/UserActionCard/useractioncard.scss b/src/components/molecules/UserActionCard/useractioncard.scss index f06258a..558e1c7 100644 --- a/src/components/molecules/UserActionCard/useractioncard.scss +++ b/src/components/molecules/UserActionCard/useractioncard.scss @@ -1,4 +1,5 @@ #useractionscard { + // Register selection svg { padding-top: 0.5rem; @@ -8,34 +9,43 @@ filter: saturate(0.5); transition: all 0.2s ease; } + .selectType { transition: all 0.2s ease; + p.lead { border-top: none; transition: all 0.2s ease; } + cursor: pointer; + &:hover { transform: scale(1.1); + svg { filter: saturate(1); } - & > p.lead { + + &>p.lead { color: #77bd43; font-weight: bold; } } } + input { &[name="code"] { letter-spacing: 1px; } + &:focus { color: #495057; border-color: #77bd43; outline: 0; box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); } + &.error { color: #495057; border-color: lightcoral; @@ -43,9 +53,11 @@ box-shadow: 0 0 0 0.2rem rgba(240, 128, 128, 0.25); } } + .connect { .btn { padding: 10px 13px 10px 13px; + &.disabled { i { &:after { @@ -53,6 +65,7 @@ } } } + i { &.fab { &:after { @@ -68,6 +81,7 @@ } } } + &:hover { i { &:after { @@ -78,6 +92,7 @@ } } } + .btn { &.text-muted { color: lighten(#6c757d, 25%) !important; @@ -88,6 +103,7 @@ .modal-dialog.modal-notify.modal-orange .modal-header { background-color: #ff8910 !important; } + .modal-orange { .select-wrapper { &:focus { @@ -96,20 +112,24 @@ outline: 0; box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); } + input { color: lighten(#495057, 20%); margin-bottom: 0; } + li:not(.disabled) { span { color: #495057; } } + li { margin-bottom: 0 !important; } } } + .list-group-item { $borderRadius: 6px; @@ -117,60 +137,76 @@ justify-content: space-between; align-items: center; transition: all 0.2s ease; + &.list-item-github { border-left: 5px #333 solid; } + &.list-item-gitlab { border-left: 5px #f57c00 solid; } + &.list-item-bitbucket { border-left: 5px #1976d2 solid; } + .company-icon { margin-right: 0.4rem; + &.fa-github { color: #333; } + &.fa-gitlab { color: #f57c00; } + &.fa-bitbucket { color: #1976d2; } } + .close-icon { color: lightgray; cursor: pointer; transition: color 0.2s ease; + &:hover { color: lightcoral; } } + &:first-of-type { border-top-left-radius: $borderRadius; border-top-right-radius: $borderRadius; } + &:last-of-type { border-bottom-left-radius: $borderRadius; border-bottom-right-radius: $borderRadius; } + .username-icon { color: lightgray; cursor: pointer; transition: color 0.2s ease; + &:hover { color: #77bd43; } } + &:first-of-type { border-top-left-radius: $borderRadius; border-top-right-radius: $borderRadius; } + &:last-of-type { border-bottom-left-radius: $borderRadius; border-bottom-right-radius: $borderRadius; } } + .progress { height: 10px; } From 8a3c509281f30cd98d599fc07b9e63dd1b340e08 Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 15:51:11 +0200 Subject: [PATCH 027/312] Improve code quality The code quality was improved due to a request by Codacy. --- src/components/atoms/charts/Calendar2D/calendar2d.scss | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/atoms/charts/Calendar2D/calendar2d.scss b/src/components/atoms/charts/Calendar2D/calendar2d.scss index 9fbb86f..49eee25 100644 --- a/src/components/atoms/charts/Calendar2D/calendar2d.scss +++ b/src/components/atoms/charts/Calendar2D/calendar2d.scss @@ -3,17 +3,21 @@ max-width: 7.655%; flex: 0 0 7.655%; } + svg { width: 100%; overflow: visible; + rect { stroke-width: 3; stroke: #fafafa; transition: all 0.2s ease; cursor: pointer; + &:hover { stroke-width: 1; } + &:focus { outline: none; fill: #f44336; @@ -22,7 +26,7 @@ } } -/** +/** * SPDX-License-Identifier: (EUPL-1.2) * Copyright © Simon Prast */ From 5b8e8aa79cb04b742daef4cdf9a114bccd8e023a Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 15:58:14 +0200 Subject: [PATCH 028/312] Apply suggestions from code review All suggestions are implemented now. --- src/components/molecules/Footer/index.jsx | 2 -- src/components/molecules/Navbar/index.jsx | 2 -- src/components/molecules/UserActionCard/index.jsx | 3 --- src/components/molecules/modals/UploadModal/index.jsx | 3 ++- 4 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/components/molecules/Footer/index.jsx b/src/components/molecules/Footer/index.jsx index 029d036..edc0509 100644 --- a/src/components/molecules/Footer/index.jsx +++ b/src/components/molecules/Footer/index.jsx @@ -4,7 +4,6 @@ import React from "react"; // DOM bindings for React Router import { Link, withRouter } from "react-router-dom"; - //> MDB // "Material Design for Bootstrap" is a great UI design framework import { @@ -19,7 +18,6 @@ import { //> CSS import "./footer.scss"; - //> Images // SNEK Logo import Logo from "../../../assets/navigation/logo.png"; diff --git a/src/components/molecules/Navbar/index.jsx b/src/components/molecules/Navbar/index.jsx index 2552f33..97499d0 100644 --- a/src/components/molecules/Navbar/index.jsx +++ b/src/components/molecules/Navbar/index.jsx @@ -6,7 +6,6 @@ import React from "react"; import { Link, withRouter } from "react-router-dom"; // React PropTypes import PropTypes from "prop-types"; - //> MDB // "Material Design for Bootstrap" is a great UI design framework import { @@ -27,7 +26,6 @@ import { //> Images import SNEKLogo from "../../../assets/navigation/logo.png"; - //> CSS import "./navbar.scss"; //#endregion diff --git a/src/components/molecules/UserActionCard/index.jsx b/src/components/molecules/UserActionCard/index.jsx index 854aba8..a4bad99 100644 --- a/src/components/molecules/UserActionCard/index.jsx +++ b/src/components/molecules/UserActionCard/index.jsx @@ -4,18 +4,15 @@ import React from "react"; // React PropTypes import PropTypes from "prop-types"; - //> MDB // "Material Design for Bootstrap" is a great UI design framework import { MDBRow, MDBCol, MDBAlert, MDBBtn, MDBIcon } from "mdbreact"; //> Components import { RegisterForm, LoginForm } from "../forms"; - //> Images import { ReactComponent as SvgSoftware } from "../../../assets/header/dev.svg"; import { ReactComponent as SvgMedia } from "../../../assets/header/media.svg"; - //> CSS import "./useractioncard.scss"; //#endregion diff --git a/src/components/molecules/modals/UploadModal/index.jsx b/src/components/molecules/modals/UploadModal/index.jsx index 7b5b5a1..3cda11b 100644 --- a/src/components/molecules/modals/UploadModal/index.jsx +++ b/src/components/molecules/modals/UploadModal/index.jsx @@ -4,7 +4,6 @@ import React from "react"; // Contains the functionality for uploading a file import Dropzone from "react-dropzone"; - import { MDBModal, MDBModalHeader, @@ -27,10 +26,12 @@ class UploadModal extends React.Component { error: [], loading: true, }); + this.props.uploadTalk(files[0]).then(() => { this.setState({ loading: false, }); + this.props.closeModal(); }); } else { From eab6a68176ae2d43e22464722ea5ba482da6eb0d Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 16:00:27 +0200 Subject: [PATCH 029/312] Improve code quality Some newlines have been added. --- src/components/molecules/modals/UploadModal/index.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/molecules/modals/UploadModal/index.jsx b/src/components/molecules/modals/UploadModal/index.jsx index 3cda11b..ecc1332 100644 --- a/src/components/molecules/modals/UploadModal/index.jsx +++ b/src/components/molecules/modals/UploadModal/index.jsx @@ -26,12 +26,12 @@ class UploadModal extends React.Component { error: [], loading: true, }); - + this.props.uploadTalk(files[0]).then(() => { this.setState({ loading: false, }); - + this.props.closeModal(); }); } else { From c44d2b54bcb0b57200253aab7a4b22e6ce2232ae Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 16:11:48 +0200 Subject: [PATCH 030/312] Improve code quality The code quality has been improved due to a request by Codacy. --- src/components/molecules/Footer/footer.scss | 22 ++++----- src/components/molecules/Navbar/navbar.scss | 16 +++---- .../UserActionCard/useractioncard.scss | 45 +++++++------------ 3 files changed, 36 insertions(+), 47 deletions(-) diff --git a/src/components/molecules/Footer/footer.scss b/src/components/molecules/Footer/footer.scss index f891586..9a0cc45 100644 --- a/src/components/molecules/Footer/footer.scss +++ b/src/components/molecules/Footer/footer.scss @@ -75,17 +75,6 @@ footer { color: #212121 !important; } - ul { - i { - color: #212121 !important; - } - - a { - color: #212121 !important; - } - } - } - .madeby { a { color: #212121; @@ -97,6 +86,17 @@ footer { } } } + + ul { + i { + color: #212121 !important; + } + + a { + color: #212121 !important; + } + } + } } /** diff --git a/src/components/molecules/Navbar/navbar.scss b/src/components/molecules/Navbar/navbar.scss index 3bc9e06..1a9d545 100644 --- a/src/components/molecules/Navbar/navbar.scss +++ b/src/components/molecules/Navbar/navbar.scss @@ -53,6 +53,14 @@ } } + // Remove search field delete button + input[type="search"]::-webkit-search-decoration, + input[type="search"]::-webkit-search-cancel-button, + input[type="search"]::-webkit-search-results-button, + input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; + } + input[type="search"] { &:focus { color: #495057; @@ -63,14 +71,6 @@ } } - // Remove search field delete button - input[type="search"]::-webkit-search-decoration, - input[type="search"]::-webkit-search-cancel-button, - input[type="search"]::-webkit-search-results-button, - input[type="search"]::-webkit-search-results-decoration { - -webkit-appearance: none; - } - .spacer { margin-left: 1rem; padding-left: 1rem; diff --git a/src/components/molecules/UserActionCard/useractioncard.scss b/src/components/molecules/UserActionCard/useractioncard.scss index 558e1c7..3dd1891 100644 --- a/src/components/molecules/UserActionCard/useractioncard.scss +++ b/src/components/molecules/UserActionCard/useractioncard.scss @@ -7,7 +7,6 @@ height: auto; transition: all 0.2s ease; filter: saturate(0.5); - transition: all 0.2s ease; } .selectType { @@ -27,7 +26,7 @@ filter: saturate(1); } - &>p.lead { + & > p.lead { color: #77bd43; font-weight: bold; } @@ -54,24 +53,22 @@ } } + .btn { + &.text-muted { + color: lighten(#6c757d, 25%) !important; + } + } + .connect { .btn { padding: 10px 13px 10px 13px; - &.disabled { - i { - &:after { - color: lightgrey !important; - } - } - } - i { &.fab { &:after { transition: all 0.1s ease; position: absolute; - font-family: "Font Awesome 5 Free"; + font-family: "Font Awesome 5 Free", sans-serif; content: "\f055"; font-weight: 900; font-size: 10px; @@ -82,6 +79,14 @@ } } + &.disabled { + i { + &::after { + color: lightgrey !important; + } + } + } + &:hover { i { &:after { @@ -93,12 +98,6 @@ } } - .btn { - &.text-muted { - color: lighten(#6c757d, 25%) !important; - } - } - // Modal .modal-dialog.modal-notify.modal-orange .modal-header { background-color: #ff8910 !important; @@ -176,16 +175,6 @@ } } - &:first-of-type { - border-top-left-radius: $borderRadius; - border-top-right-radius: $borderRadius; - } - - &:last-of-type { - border-bottom-left-radius: $borderRadius; - border-bottom-right-radius: $borderRadius; - } - .username-icon { color: lightgray; cursor: pointer; @@ -212,7 +201,7 @@ } } -/** +/** * SPDX-License-Identifier: (EUPL-1.2) * Copyright © Simon Prast */ From 141c3dda29208b5b01c002dae6a011a939b994ad Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 16:42:05 +0200 Subject: [PATCH 031/312] Apply suggestions from code review All suggestions are implemented now. Co-authored-by: Pinterics David <55298934+pinterid@users.noreply.github.com> --- src/components/atoms/charts/Calendar2D/index.jsx | 2 ++ src/components/atoms/charts/ContribRadar/index.jsx | 3 ++- src/components/atoms/charts/LatestActivity/index.jsx | 3 +-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index eec1093..823f0ea 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -15,7 +15,9 @@ import { MDBRow, MDBCol } from "mdbreact"; import "./calendar2d.scss"; //#endregion +//#region > Constant Variables const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; +//#endregion //#region > Components /** @class A two dimensional calendar which displays each days contributions */ diff --git a/src/components/atoms/charts/ContribRadar/index.jsx b/src/components/atoms/charts/ContribRadar/index.jsx index f5b2b4b..85b7762 100644 --- a/src/components/atoms/charts/ContribRadar/index.jsx +++ b/src/components/atoms/charts/ContribRadar/index.jsx @@ -73,7 +73,7 @@ class ContribRadar extends React.Component { }; componentDidMount = () => { - // First render chart with current year + // Start of by rendering chart with current year this.calculateSources(null); }; @@ -84,6 +84,7 @@ class ContribRadar extends React.Component { fillChart = (results) => { console.log(results); + if (results) { this.setState({ dataRadar: { diff --git a/src/components/atoms/charts/LatestActivity/index.jsx b/src/components/atoms/charts/LatestActivity/index.jsx index d6f5399..a99cb6b 100644 --- a/src/components/atoms/charts/LatestActivity/index.jsx +++ b/src/components/atoms/charts/LatestActivity/index.jsx @@ -41,7 +41,7 @@ class LatestActivity extends React.Component { }; componentDidMount = () => { - // First render chart with current week + // Start of by rendering chart with current week this.calculateSources(undefined, undefined); }; @@ -97,7 +97,6 @@ class LatestActivity extends React.Component { calculateSources = (year, activity) => { const { statistic } = this.props; - let contribData, week, lastWeek, lastWeekValues; if (!year) { From b02a59c7401dab005b237caed63c49e8430bd022 Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 16:43:26 +0200 Subject: [PATCH 032/312] Update src/components/atoms/index.js Now it is a valid heading. Co-authored-by: Pinterics David <55298934+pinterid@users.noreply.github.com> --- src/components/atoms/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/atoms/index.js b/src/components/atoms/index.js index f61c52a..f5f7b77 100644 --- a/src/components/atoms/index.js +++ b/src/components/atoms/index.js @@ -1,7 +1,7 @@ //#region > Imports //> Atoms // Import all components to export them for easy access from parent components -//>> User profile +//> User profile import Calendar2D from "./charts/Calendar2D"; import Calendar3D from "./charts/Calendar3D"; import ContribRadar from "./charts/ContribRadar"; From db80cda202e72d0d6090db8ed4e925531c133c3d Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 16:45:13 +0200 Subject: [PATCH 033/312] Improve code quality The naming of a constant variable has been refined. --- src/components/atoms/charts/Calendar2D/index.jsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index 823f0ea..84731f4 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -16,7 +16,7 @@ import "./calendar2d.scss"; //#endregion //#region > Constant Variables -const months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; +const MONTHS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]; //#endregion //#region > Components @@ -165,9 +165,9 @@ class Calender2D extends React.Component { contributions in the last year
    - {months.map((month, key) => { + {MONTHS.map((month, key) => { return ( - + {this.getEachMonth(key)} ); From b9c939234f707ffa29022b1f12b822a4c31e7585 Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 16:55:07 +0200 Subject: [PATCH 034/312] Apply suggestions from code review Some suggestions have been implemented. Co-authored-by: Pinterics David <55298934+pinterid@users.noreply.github.com> --- src/components/molecules/Footer/index.jsx | 2 +- src/components/molecules/forms/LoginForm/index.jsx | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/molecules/Footer/index.jsx b/src/components/molecules/Footer/index.jsx index edc0509..8e6c33f 100644 --- a/src/components/molecules/Footer/index.jsx +++ b/src/components/molecules/Footer/index.jsx @@ -23,10 +23,10 @@ import "./footer.scss"; import Logo from "../../../assets/navigation/logo.png"; //#endregion +//#region > Constant Variables //> Local data // Slogans /** @todo Change to uppercase */ -//#region > Constant Variables const slogans = [ "Become a snek!", "Connect with your colleges!", diff --git a/src/components/molecules/forms/LoginForm/index.jsx b/src/components/molecules/forms/LoginForm/index.jsx index e60b858..5205638 100644 --- a/src/components/molecules/forms/LoginForm/index.jsx +++ b/src/components/molecules/forms/LoginForm/index.jsx @@ -102,6 +102,7 @@ class LoginForm extends React.Component { weight: 10, }); } + if (this.state.login_password === "") { errors.push({ code: 21, @@ -120,7 +121,9 @@ class LoginForm extends React.Component { this.state.login_username, this.state.login_password ); + console.log(result); + if (result) { this.setState( { From 596d75e36ce152e160294fbefab4a2275bc2da7c Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 16:56:54 +0200 Subject: [PATCH 035/312] Improve code quality The code quality has been improved due to a request by @pinterid. --- src/components/atoms/charts/Calendar2D/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/atoms/charts/Calendar2D/index.jsx b/src/components/atoms/charts/Calendar2D/index.jsx index 84731f4..2e7417d 100644 --- a/src/components/atoms/charts/Calendar2D/index.jsx +++ b/src/components/atoms/charts/Calendar2D/index.jsx @@ -167,7 +167,7 @@ class Calender2D extends React.Component { {MONTHS.map((month, key) => { return ( - + {this.getEachMonth(key)} ); From dde3c5f4c422050fbbe44917fa4666af5eb6846e Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 17:00:39 +0200 Subject: [PATCH 036/312] Improve code quality The code quality has been improved due to a request of @pinterid. --- .../molecules/forms/RegisterForm/index.jsx | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/molecules/forms/RegisterForm/index.jsx b/src/components/molecules/forms/RegisterForm/index.jsx index be69cdf..a78b665 100644 --- a/src/components/molecules/forms/RegisterForm/index.jsx +++ b/src/components/molecules/forms/RegisterForm/index.jsx @@ -192,6 +192,7 @@ class RegisterForm extends React.Component { let usernames = this.state.usernames.filter(function (obj) { return obj.id !== id; }); + this.setState({ sourceList, usernames, @@ -234,6 +235,7 @@ class RegisterForm extends React.Component { } } }); + if (rtn.includes(true)) { return true; } else { @@ -288,6 +290,7 @@ class RegisterForm extends React.Component { // Handle sumbit of register form handleSubmit = async () => { console.log("Handle submit"); + // CHANGE TO CONST let { password1, @@ -312,6 +315,7 @@ class RegisterForm extends React.Component { weight: 10, }); } + if (sourceList.length === 0) { errors.push({ code: 2, @@ -319,6 +323,7 @@ class RegisterForm extends React.Component { weight: 10, }); } + if (firstname === "") { errors.push({ code: 3, @@ -326,6 +331,7 @@ class RegisterForm extends React.Component { weight: 8, }); } + if (lastname === "") { errors.push({ code: 4, @@ -333,6 +339,7 @@ class RegisterForm extends React.Component { weight: 8, }); } + if (email === "") { errors.push({ code: 5, @@ -340,6 +347,7 @@ class RegisterForm extends React.Component { weight: 9, }); } + if (username === "") { errors.push({ code: 6, @@ -347,6 +355,7 @@ class RegisterForm extends React.Component { weight: 10, }); } + if (password1 === "") { errors.push({ code: 7, @@ -354,6 +363,7 @@ class RegisterForm extends React.Component { weight: 10, }); } + if (password2 === "") { errors.push({ code: 8, @@ -361,6 +371,7 @@ class RegisterForm extends React.Component { weight: 10, }); } + if (code === "") { errors.push({ code: 9, @@ -375,9 +386,8 @@ class RegisterForm extends React.Component { loading: true, }, () => { - // Cache data - let cache = {}; console.log("Register", this.state); + let registrationData = { sources: sourceList, username, @@ -387,6 +397,7 @@ class RegisterForm extends React.Component { gift_code: promoCode && code !== "" ? code : null, password: password1, }; + this.props.globalFunctions.registerUser(registrationData); } ); From 13ea5b4161d6eb9bf565f981ae07c8d6aa0e4368 Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 17:08:05 +0200 Subject: [PATCH 037/312] Improve code quality The code quality was improved due to a request by Codacy. --- src/components/molecules/Footer/footer.scss | 16 ++++++++-------- src/components/molecules/Navbar/navbar.scss | 16 ++++++++-------- .../molecules/UserActionCard/useractioncard.scss | 9 +++++---- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/components/molecules/Footer/footer.scss b/src/components/molecules/Footer/footer.scss index 9a0cc45..3cf3e16 100644 --- a/src/components/molecules/Footer/footer.scss +++ b/src/components/molecules/Footer/footer.scss @@ -75,17 +75,17 @@ footer { color: #212121 !important; } - .madeby { - a { - color: #212121; - border-bottom: solid #77bd43 2px; - transition: border-bottom 0.2s ease; + .madeby { + a { + color: #212121; + border-bottom: solid #77bd43 2px; + transition: border-bottom 0.2s ease; - &:hover { - border-bottom: solid #0366d6 2px; + &:hover { + border-bottom: solid #0366d6 2px; + } } } - } ul { i { diff --git a/src/components/molecules/Navbar/navbar.scss b/src/components/molecules/Navbar/navbar.scss index 1a9d545..3192548 100644 --- a/src/components/molecules/Navbar/navbar.scss +++ b/src/components/molecules/Navbar/navbar.scss @@ -53,14 +53,6 @@ } } - // Remove search field delete button - input[type="search"]::-webkit-search-decoration, - input[type="search"]::-webkit-search-cancel-button, - input[type="search"]::-webkit-search-results-button, - input[type="search"]::-webkit-search-results-decoration { - -webkit-appearance: none; - } - input[type="search"] { &:focus { color: #495057; @@ -70,6 +62,14 @@ box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); } } + + // Remove search field delete button + input[type="search"]::-webkit-search-decoration, + input[type="search"]::-webkit-search-cancel-button, + input[type="search"]::-webkit-search-results-button, + input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; + } .spacer { margin-left: 1rem; diff --git a/src/components/molecules/UserActionCard/useractioncard.scss b/src/components/molecules/UserActionCard/useractioncard.scss index 3dd1891..d4941a3 100644 --- a/src/components/molecules/UserActionCard/useractioncard.scss +++ b/src/components/molecules/UserActionCard/useractioncard.scss @@ -65,7 +65,7 @@ i { &.fab { - &:after { + &::after { transition: all 0.1s ease; position: absolute; font-family: "Font Awesome 5 Free", sans-serif; @@ -117,15 +117,16 @@ margin-bottom: 0; } + li { + margin-bottom: 0 !important; + } + li:not(.disabled) { span { color: #495057; } } - li { - margin-bottom: 0 !important; - } } } From 4842f885364a89978abe8a3e494f87b76a4c8176 Mon Sep 17 00:00:00 2001 From: Pinterid Date: Sat, 6 Jun 2020 17:19:30 +0200 Subject: [PATCH 038/312] Improve code quality The code quality was improved due to a request by Codacy. --- src/components/molecules/Navbar/navbar.scss | 16 ++++++++-------- .../molecules/UserActionCard/useractioncard.scss | 3 +-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/components/molecules/Navbar/navbar.scss b/src/components/molecules/Navbar/navbar.scss index 3192548..1a9d545 100644 --- a/src/components/molecules/Navbar/navbar.scss +++ b/src/components/molecules/Navbar/navbar.scss @@ -53,6 +53,14 @@ } } + // Remove search field delete button + input[type="search"]::-webkit-search-decoration, + input[type="search"]::-webkit-search-cancel-button, + input[type="search"]::-webkit-search-results-button, + input[type="search"]::-webkit-search-results-decoration { + -webkit-appearance: none; + } + input[type="search"] { &:focus { color: #495057; @@ -62,14 +70,6 @@ box-shadow: 0 0 0 0.2rem rgba(119, 189, 67, 0.25); } } - - // Remove search field delete button - input[type="search"]::-webkit-search-decoration, - input[type="search"]::-webkit-search-cancel-button, - input[type="search"]::-webkit-search-results-button, - input[type="search"]::-webkit-search-results-decoration { - -webkit-appearance: none; - } .spacer { margin-left: 1rem; diff --git a/src/components/molecules/UserActionCard/useractioncard.scss b/src/components/molecules/UserActionCard/useractioncard.scss index d4941a3..c5c1911 100644 --- a/src/components/molecules/UserActionCard/useractioncard.scss +++ b/src/components/molecules/UserActionCard/useractioncard.scss @@ -89,7 +89,7 @@ &:hover { i { - &:after { + &::after { color: lighten(#77bd43, 15%); transform: scale(1.5); } @@ -126,7 +126,6 @@ color: #495057; } } - } } From da5cc089f5f5cfeb00885b20fe3e389e2acf0c93 Mon Sep 17 00:00:00 2001 From: Schett Nico <52858351+schettn@users.noreply.github.com> Date: Sat, 6 Jun 2020 17:26:34 +0200 Subject: [PATCH 039/312] Apply suggestions from code review Added suggestions Co-authored-by: Florian Kleber --- src/components/atoms/Pinned/index.jsx | 2 +- src/components/atoms/Project/index.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/Pinned/index.jsx b/src/components/atoms/Pinned/index.jsx index e348cf4..70fbd4b 100644 --- a/src/components/atoms/Pinned/index.jsx +++ b/src/components/atoms/Pinned/index.jsx @@ -14,7 +14,7 @@ import "./pinned.scss"; //#region > Components /** - * @class Displays pinned projects + * @class A component which contains pinned projects */ class Pinned extends React.Component { render() { diff --git a/src/components/atoms/Project/index.jsx b/src/components/atoms/Project/index.jsx index a8c0eae..6a4dadc 100644 --- a/src/components/atoms/Project/index.jsx +++ b/src/components/atoms/Project/index.jsx @@ -11,7 +11,7 @@ import { MDBCol, MDBIcon } from "mdbreact"; //#region > Components /** - * @class A project which contains repository data + * @class A component which contains repository data */ class Project extends React.Component { render() { From a1cbeb477da40b9c9974a45067b5530a1ef64ffa Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 17:50:36 +0200 Subject: [PATCH 040/312] Improve code quality The code quality has been improved due to a request of @kleberbaum. --- .../atoms/charts/Calendar3D/index.jsx | 3 +++ .../atoms/charts/ContribRadar/index.jsx | 18 ++++++++++-------- .../atoms/charts/LatestActivity/index.jsx | 3 +++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/components/atoms/charts/Calendar3D/index.jsx b/src/components/atoms/charts/Calendar3D/index.jsx index 6322686..a3434b7 100644 --- a/src/components/atoms/charts/Calendar3D/index.jsx +++ b/src/components/atoms/charts/Calendar3D/index.jsx @@ -178,6 +178,7 @@ class Calendar3D extends React.Component { renderIsometrics = () => { if (this.context) { const obelisk = require("obelisk.js"); + // Create a canvas 2D point for pixel view world let point = new obelisk.Point(70, 70); // Create view instance to nest everything @@ -207,6 +208,7 @@ class Calendar3D extends React.Component { } const maxHight = 100; + let x = 0; let y = 0; let maxCount = 0; // Max number of contributions / day in the last year @@ -325,6 +327,7 @@ class Calendar3D extends React.Component { const data = localStorage.getItem("3dChart"); const dataObject = JSON.parse(data); const context = this.context.getContext("2d"); + let img = new Image(); img.src = dataObject.data; diff --git a/src/components/atoms/charts/ContribRadar/index.jsx b/src/components/atoms/charts/ContribRadar/index.jsx index 85b7762..c99bb96 100644 --- a/src/components/atoms/charts/ContribRadar/index.jsx +++ b/src/components/atoms/charts/ContribRadar/index.jsx @@ -83,8 +83,9 @@ class ContribRadar extends React.Component { } fillChart = (results) => { + //#TSID console.log(results); - + if (results) { this.setState({ dataRadar: { @@ -104,13 +105,14 @@ class ContribRadar extends React.Component { calculateSources = (nextPropsYear) => { const { statistic } = this.props; - let totalReviews = 0, - totalIssues = 0, - totalRequests = 0, - totalCommits = 0, - totalSources = 1, - year, - results = []; + + let totalReviews = 0; + let totalIssues = 0; + let totalRequests = 0; + let totalCommits = 0; + let totalSources = 1; + let year; + let results = []; if (nextPropsYear === null) { year = this.props.year; diff --git a/src/components/atoms/charts/LatestActivity/index.jsx b/src/components/atoms/charts/LatestActivity/index.jsx index a99cb6b..577d372 100644 --- a/src/components/atoms/charts/LatestActivity/index.jsx +++ b/src/components/atoms/charts/LatestActivity/index.jsx @@ -51,7 +51,9 @@ class LatestActivity extends React.Component { } fillChart = (results, lastWeek) => { + //#TSID console.log(results, lastWeek); + if (results) { this.setState({ dataLine: { @@ -97,6 +99,7 @@ class LatestActivity extends React.Component { calculateSources = (year, activity) => { const { statistic } = this.props; + let contribData, week, lastWeek, lastWeekValues; if (!year) { From b835a3dca095998efe4486329ac64c21093c8696 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 18:00:37 +0200 Subject: [PATCH 041/312] Improve code quality The code quality has been improved due to a request of @kleberbaum. --- src/components/molecules/forms/LoginForm/index.jsx | 6 +++--- src/components/molecules/forms/RegisterForm/index.jsx | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/molecules/forms/LoginForm/index.jsx b/src/components/molecules/forms/LoginForm/index.jsx index 5205638..91a8a3f 100644 --- a/src/components/molecules/forms/LoginForm/index.jsx +++ b/src/components/molecules/forms/LoginForm/index.jsx @@ -102,7 +102,7 @@ class LoginForm extends React.Component { weight: 10, }); } - + if (this.state.login_password === "") { errors.push({ code: 21, @@ -122,8 +122,9 @@ class LoginForm extends React.Component { this.state.login_password ); + //#TSID console.log(result); - + if (result) { this.setState( { @@ -133,7 +134,6 @@ class LoginForm extends React.Component { ); } else { // Login fail - //handleLogin(false); this.setState({ loginFail: true, }); diff --git a/src/components/molecules/forms/RegisterForm/index.jsx b/src/components/molecules/forms/RegisterForm/index.jsx index a78b665..9679455 100644 --- a/src/components/molecules/forms/RegisterForm/index.jsx +++ b/src/components/molecules/forms/RegisterForm/index.jsx @@ -88,7 +88,8 @@ class RegisterForm extends React.Component { const username = this.state.gitlab_username; const server = this.state.gitlab_server; - console.log(username, server); + //#TSID + //console.log(username, server); if (username.trim() && server.trim()) { if (server !== "Choose your organisation") { @@ -289,7 +290,8 @@ class RegisterForm extends React.Component { // Handle sumbit of register form handleSubmit = async () => { - console.log("Handle submit"); + //#TSID + //console.log("Handle submit"); // CHANGE TO CONST let { @@ -386,7 +388,8 @@ class RegisterForm extends React.Component { loading: true, }, () => { - console.log("Register", this.state); + //#TSID + //console.log("Register", this.state); let registrationData = { sources: sourceList, From dfd911c0bddac2a2d27089124043a628adc064ac Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 18:04:20 +0200 Subject: [PATCH 042/312] Improve code quality The code quality has been improved. --- src/components/molecules/forms/LoginForm/index.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/molecules/forms/LoginForm/index.jsx b/src/components/molecules/forms/LoginForm/index.jsx index 91a8a3f..e7db7a3 100644 --- a/src/components/molecules/forms/LoginForm/index.jsx +++ b/src/components/molecules/forms/LoginForm/index.jsx @@ -123,7 +123,7 @@ class LoginForm extends React.Component { ); //#TSID - console.log(result); + //console.log(result); if (result) { this.setState( From 0dfc7c3ab941010ba511d1dfe61773b0baba26dd Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 18:05:12 +0200 Subject: [PATCH 043/312] Improve code quality Comment out all console.log --- src/components/atoms/charts/ContribRadar/index.jsx | 2 +- src/components/atoms/charts/LatestActivity/index.jsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/atoms/charts/ContribRadar/index.jsx b/src/components/atoms/charts/ContribRadar/index.jsx index c99bb96..b58b3c8 100644 --- a/src/components/atoms/charts/ContribRadar/index.jsx +++ b/src/components/atoms/charts/ContribRadar/index.jsx @@ -84,7 +84,7 @@ class ContribRadar extends React.Component { fillChart = (results) => { //#TSID - console.log(results); + //console.log(results); if (results) { this.setState({ diff --git a/src/components/atoms/charts/LatestActivity/index.jsx b/src/components/atoms/charts/LatestActivity/index.jsx index 577d372..27cc609 100644 --- a/src/components/atoms/charts/LatestActivity/index.jsx +++ b/src/components/atoms/charts/LatestActivity/index.jsx @@ -52,7 +52,7 @@ class LatestActivity extends React.Component { fillChart = (results, lastWeek) => { //#TSID - console.log(results, lastWeek); + //console.log(results, lastWeek); if (results) { this.setState({ From a02828165540827aa1996d55ed5150eedecc687c Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 18:30:38 +0200 Subject: [PATCH 044/312] Add OverviewTab Component The OverviewTab Component has been added. --- .../organisms/tabs/OverviewTab/index.jsx | 203 ++++++++++++++++++ .../tabs/OverviewTab/overviewtab.scss | 29 +++ 2 files changed, 232 insertions(+) create mode 100644 src/components/organisms/tabs/OverviewTab/index.jsx create mode 100644 src/components/organisms/tabs/OverviewTab/overviewtab.scss diff --git a/src/components/organisms/tabs/OverviewTab/index.jsx b/src/components/organisms/tabs/OverviewTab/index.jsx new file mode 100644 index 0000000..a7cf286 --- /dev/null +++ b/src/components/organisms/tabs/OverviewTab/index.jsx @@ -0,0 +1,203 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// React PropTypes +import PropTypes from "prop-types"; +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { MDBRow, MDBCol, MDBBtn, MDBIcon } from "mdbreact"; + +//> CSS +import "./overviewtab.scss"; +//> Components +import { + Calendar2D, + Calendar3D, + ContribRadar, + Pinned, + LatestActivity, +} from "../../../atoms"; +//#endregion + +//#region > Constants +/** @description Dummy data */ +const pinned = [ + { + category: { + color: "green", + title: "Test", + }, + pinned: { + views: 4, + description: "This is the description", + }, + link: "https://www.google.com", + }, + { + category: { + color: "red", + title: "Test", + }, + pinned: { + views: 11, + description: "This is the description 2", + }, + link: "https://www.google.com", + }, +]; +//#endregion + +//#region > Components +class OverviewTab extends React.Component { + state = { + selectedYear: undefined, + }; + + selectDay = (day, wkey, dkey) => { + this.setState({ + activity: { + day, + wkey, + dkey, + }, + }); + }; + + render() { + const { platformData } = this.props; + + return ( + <> + {platformData && ( + + {platformData.statistic.languages.map((language, i) => { + if (i < 6) { + return ( + + + + {language.name} {language.share}% + + + ); + } + })} + + )} + {true && ( + <> + + +

    Pinned

    +
    + + Customize + +
    + + {pinned.map((item, i) => { + return ; + })} + + + )} + {platformData && + (platformData.user.settings.show3DDiagram || + platformData.user.settings.show2DDiagram) && ( +
    + {platformData.statistic.years.map((year, i) => { + return ( + this.setState({ selectedYear: year.year })} + > + {year.year} + + ); + })} + this.setState({ selectedYear: undefined })} + > + Current + +
    + )} + {platformData && platformData.user.settings.show3DDiagram && ( + + )} + {platformData && platformData.user.settings.show2DDiagram && ( + + )} + + +

    Contribution Types

    + {platformData && !platformData.user.settings.showContribDiagram && ( +
    + +
    + )} +
    + +

    + Activity + +

    +

    Week overview

    + +
    +
    + + ); + } +} +//#endregion + +//#region > PropTypes +OverviewTab.propTypes = { + platformData: PropTypes.object.isRequired, +}; +//#endregion + +//#region > Exports +export default OverviewTab; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/organisms/tabs/OverviewTab/overviewtab.scss b/src/components/organisms/tabs/OverviewTab/overviewtab.scss new file mode 100644 index 0000000..914a243 --- /dev/null +++ b/src/components/organisms/tabs/OverviewTab/overviewtab.scss @@ -0,0 +1,29 @@ +.pinned { + margin-bottom: 2rem; + .card-body { + padding: 0.5rem; + border: 1px lighten(grey, 40%) solid; + .badge { + padding: 0.5rem; + } + } + .col-md-4 { + margin-bottom: 1rem; + } +} +.year-select { + .btn { + padding-left: 0.9rem; + padding-right: 0.9rem; + &.selected { + box-shadow: none; + background-color: #77bd43 !important; + color: white; + } + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ From adb4344cdac7b3003277a29ec65aea8417cf0037 Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 18:30:59 +0200 Subject: [PATCH 045/312] Add ProjectTab Component The ProjectTab Component has been added. --- .../organisms/tabs/ProjectTab/index.jsx | 50 +++++++++++++++++++ .../organisms/tabs/ProjectTab/projecttab.scss | 50 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/components/organisms/tabs/ProjectTab/index.jsx create mode 100644 src/components/organisms/tabs/ProjectTab/projecttab.scss diff --git a/src/components/organisms/tabs/ProjectTab/index.jsx b/src/components/organisms/tabs/ProjectTab/index.jsx new file mode 100644 index 0000000..c0ac8f2 --- /dev/null +++ b/src/components/organisms/tabs/ProjectTab/index.jsx @@ -0,0 +1,50 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +// React PropTypes +import PropTypes from "prop-types"; +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { MDBRow } from "mdbreact"; + +//> CSS +import "./projecttab.scss"; +//> Components +import { Project } from "../../../atoms"; +//#endregion + +//#region > Components +class ProjectTab extends React.Component { + render() { + const { repoList } = this.props; + + return ( + <> +

    Repositories

    + + {repoList && + repoList.map((repo, i) => { + return ; + })} + + + ); + } +} +//#endregion + +//#region > PropTypes +ProjectTab.propTypes = { + repoList: PropTypes.array.isRequired, +}; +//#endregion + +//#region > Exports +export default ProjectTab; +//#endregion + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ diff --git a/src/components/organisms/tabs/ProjectTab/projecttab.scss b/src/components/organisms/tabs/ProjectTab/projecttab.scss new file mode 100644 index 0000000..a7d21f3 --- /dev/null +++ b/src/components/organisms/tabs/ProjectTab/projecttab.scss @@ -0,0 +1,50 @@ +.project-list { + padding: 0; + .col-md-6:nth-child(even) { + padding-left: 0.15rem; + } + .col-md-6:nth-child(odd) { + padding-right: 0.15rem; + } + .lead { + font-weight: 400; + } + img { + height: 24px; + margin-right: 0.5rem; + width: auto; + border-radius: 50%; + background: white; + } + .img-badge { + border-radius: 0; + max-width: 100%; + height: auto; + } + li { + cursor: pointer; + margin-bottom: 0.3rem; + color: #3b3b3b; + list-style: none; + background: rgba(0, 0, 0, 0.05); + transition: all 0.1s ease; + padding: 1rem !important; + align-items: center; + i { + width: 30px; + text-align: center; + padding-right: 0.5rem; + } + &:hover { + background: rgba(0, 0, 0, 0.1); + } + .badge { + box-shadow: none; + } + } +} + +/** + * SPDX-License-Identifier: (EUPL-1.2) + * Copyright © Simon Prast + */ From cfbcbf914c3bd136906333dec5cbbb522b0a656a Mon Sep 17 00:00:00 2001 From: schettn Date: Sat, 6 Jun 2020 18:31:41 +0200 Subject: [PATCH 046/312] Add TalksTab Component The TalksTab Component has been added. --- .../organisms/tabs/TalksTab/index.jsx | 212 ++++++++++++++++++ .../organisms/tabs/TalksTab/talkstab.scss | 75 +++++++ 2 files changed, 287 insertions(+) create mode 100644 src/components/organisms/tabs/TalksTab/index.jsx create mode 100644 src/components/organisms/tabs/TalksTab/talkstab.scss diff --git a/src/components/organisms/tabs/TalksTab/index.jsx b/src/components/organisms/tabs/TalksTab/index.jsx new file mode 100644 index 0000000..83d140b --- /dev/null +++ b/src/components/organisms/tabs/TalksTab/index.jsx @@ -0,0 +1,212 @@ +//#region > Imports +//> React +// Contains all the functionality necessary to define React components +import React from "react"; +//> React Router bindings to DOM +import { withRouter } from "react-router-dom"; +//> MDB +// "Material Design for Bootstrap" is a great UI design framework +import { + MDBRow, + MDBCol, + MDBIcon, + MDBBtn, + MDBCard, + MDBCardHeader, + MDBCardBody, + MDBCardFooter, +} from "mdbreact"; + +//> CSS +import "./talkstab.scss"; +//> Modules +import UploadModal from "../../../molecules/modals/UploadModal"; +//#endregion + +//#region > Components +class Talks extends React.Component { + state = { + showUpload: false, + loading: true, + }; + + handleUploadClose = () => { + if (this.state.showUpload) { + this.setState({ + showUpload: false, + }); + } + }; + + updateIframe = (talk) => { + let iframe; + + if (talk.interval.loaded === false) { + if (document.getElementById(talk.uid)) { + iframe = document.getElementById(talk.uid); + iframe.src = talk.displayUrl; + } + } + }; + + render() { + const { globalState } = this.props; + const talkList = globalState.fetchedUser.platformData.talks; + + if (talkList) { + talkList.map((talk) => { + talk.social = { + likes: 17, + date: new Date().toLocaleDateString("en-US", { + year: "numeric", + month: "numeric", + day: "numeric", + }), + }; + + talk.interval = { + timeoutID: setInterval(() => this.updateIframe(talk), 4000), + loaded: false, + }; + return talk; + }); + } + + return ( + <> + + +

    Talks

    +
    + {globalState.logged && ( + + this.setState({ showUpload: true })} + > + Upload + + + )} +
    + + {talkList && + talkList.map((talk, i) => { + return ( + + + + + + {talk.name.length > 25 + ? talk.name.substring(0, 25) + "..." + : talk.name} + + + {globalState.logged && ( + this.props.deleteTalk(talk)}> + + + )} + + + + + +
    +
    +