From 785aa88227662dd4d079c282acff8f77b103062a Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Sun, 20 Jun 2021 16:17:18 -0400 Subject: [PATCH 01/30] =?UTF-8?q?=F0=9F=94=96=201.8.0:=20=F0=9F=A5=AD=20Be?= =?UTF-8?q?gin=20`sprint-imbe`=20(Sun=20-=206/20/21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 2 +- src/StudyGroup.tsx | 2 +- src/data/changelog.json | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 8185186..d423cfd 100644 --- a/public/index.html +++ b/public/index.html @@ -2,7 +2,7 @@ - Sprint Hala 🍍 (Thu - 6/10/21) + Sprint Imbe 🥭 (Sun - 6/20/21) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 12abf6e..17507b5 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -452,7 +452,7 @@ const StudyGroup: React.FC = (props) => { Repo    Members    History    - Changelog    + Changelog    CodeNewbie
diff --git a/src/data/changelog.json b/src/data/changelog.json index 5de4519..af77811 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.0", + "message": "🥭 Begin `sprint-imbe` (Sun - 6/20/21)", + "built": "Sun, 20 Jun 2021 16:17:17 EDT" + }, { "version": "1.7.4", "message": "📦 Release `sprint-hala` 🍍 ➡ PROD: `v1.7.4-hala`", From e393e4243c06d06b98544df01843c01a042829a6 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 24 Jun 2021 18:05:57 -0400 Subject: [PATCH 02/30] =?UTF-8?q?=F0=9F=94=96=201.8.1:=20=E2=9C=A8=20Add?= =?UTF-8?q?=20`pagination-by-month`=20to=20`dashboard=20GUI`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 242 +++++++++++--------------------------- src/data/changelog.json | 5 + src/lib/util.ts | 56 +++++++++ src/services/GithubApi.ts | 121 +++++++++++++++++++ 4 files changed, 252 insertions(+), 172 deletions(-) create mode 100644 src/services/GithubApi.ts diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 17507b5..98939f5 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -3,63 +3,11 @@ import React, { useState, useEffect } from 'react' import styled, { css } from 'styled-components' import { UserProgressDb, Tag } from './models/UserProgress' import CountdownClock from './widgets/CountdownClock' -import { formatTime } from './lib/util' +import * as util from './lib/util' import changelogUri from './data/changelog.json' import './providers/AuthContext' import firebase from 'firebase/app' - -const uriAllCards = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100' -const uriAllCards0 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=r002' -const uriAllCards1 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=anitabe404' -const uriAllCards2 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=shazahuang' - -type StudyMember = { - userFullname: string - userHandle: string - startDateStr: string - uid: string - repo: string - active: boolean -} - -const studyMembers: StudyMember[] = [ - { - userFullname: 'Robert Lin', - userHandle: 'r002', - startDateStr: '2021-05-03T04:00:00Z', - uid: '45280066', - repo: 'https://github.com/studydash/cards', - active: true - }, - { - userFullname: 'Anita Beauchamp', - userHandle: 'anitabe404', - startDateStr: '2021-05-04T04:00:00Z', - uid: '9167395', - repo: 'https://github.com/studydash/cards', - active: true - }, - { - userFullname: 'Matthew Curcio', - userHandle: 'mccurcio', - startDateStr: '2021-05-10T04:00:00Z', - uid: '1915749', - repo: 'https://github.com/studydash/cards', - active: false - }, - { - userFullname: 'Shaza Huang', - userHandle: 'shazahuang', - startDateStr: '2021-06-18T04:00:00Z', - uid: '85973779', - repo: 'https://github.com/studydash/cards', - active: true - } -] -const upDb = new UserProgressDb() -for (const member of studyMembers) { - upDb.addUser(member) -} +import { getUpDb, tagMap, uriAllCards, studyMembers, StudyMember } from './services/GithubApi' type Commit = { version: string @@ -67,88 +15,21 @@ type Commit = { built: Date } -const tagMap = new Map() -tagMap.set('movie trailer', { - name: 'movie trailer', - icon: '🎬' -}) -tagMap.set('tv show', { - name: 'tv show', - icon: '📺' -}) -tagMap.set('youtube', { - name: 'youtube', - icon: '▶' -}) -tagMap.set('reading', { - name: 'reading', - icon: '📖' -}) -tagMap.set('life', { - name: 'life', - icon: '🌳' -}) -tagMap.set('travel', { - name: 'travel', - icon: '🛸' -}) -tagMap.set('podcast notes', { - name: 'podcast notes', - icon: '🎙' -}) - +const initialDate = new Date() const fetchVersion = fetch(changelogUri) -const fetchAllCards0 = fetch(uriAllCards0) -const fetchAllCards1 = fetch(uriAllCards1) -const fetchAllCards2 = fetch(uriAllCards2) -Promise.all([fetchVersion, fetchAllCards0, fetchAllCards1, fetchAllCards2]).then(responses => { +Promise.all([fetchVersion, getUpDb(initialDate)]).then(responses => { const jsonVersion = responses[0].json() - const jsonAllCards0 = responses[1].json() - const jsonAllCards1 = responses[2].json() - const jsonAllCards2 = responses[3].json() - Promise.all([jsonVersion, jsonAllCards0, jsonAllCards1, jsonAllCards2]).then(jsonPayloads => { + const initialUpDb = responses[1] + Promise.all([jsonVersion]).then(jsonPayloads => { const allCommits = jsonPayloads[0] - const allCards0 = jsonPayloads[1] - const allCards1 = jsonPayloads[2] - const allCards2 = jsonPayloads[3] const latestCommit = { version: allCommits[0].version, message: allCommits[0].message, built: new Date(allCommits[0].built) } - for (const item of allCards0.concat(allCards1).concat(allCards2)) { - // Ad-hoc code to adjust dates of Anita's cards - 5/11/21 - // This is a total hack. Write a proper `updateCard(...)` method later - if (item.number === 16) { - item.created_at = '2021-05-08T04:00:00Z' - } else if (item.number === 19) { - item.created_at = '2021-05-09T04:00:00Z' - } else if (item.number === 22) { - item.created_at = '2021-05-10T04:00:00Z' - } - - const tags = [] as Tag[] - for (const label of item.labels) { - if (tagMap.has(label.name)) { - tags.push(tagMap.get(label.name)!) // Why is assertion required here? 5/20/21 - } - } - - const cardInput = { - title: item.title, - userHandle: item.user.login, - number: item.number, - createdAt: item.created_at, - updatedAt: item.updated_at, - tags: tags, - comments: item.comments - } - upDb.getUser(cardInput.userHandle)!.setCard(cardInput) - } - ReactDOM.render( - , + , document.querySelector('#root') ) }) @@ -213,7 +94,7 @@ const CardComp: React.FC = (props) => { {title}
- {formatTime(props.created)}  + {util.formatTime(props.created)}  (#{props.number}) {props.tags.length > 0 && <> } {props.tags.map((tag: Tag) => {tag.icon})} @@ -286,25 +167,6 @@ const MissedDayCard: React.FC<{dateStr: string}> = (props) => { ) } -const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] -const dateCursor = new Date() // Start on today -const startDate = new Date('2021-05-03T04:00:00Z') // First day of our study group! 🥳 - -// Generate the date range we're interested in -type TDay = { - dayNo: number - dateStr: string -} -const dateRange = [] as TDay[] -while (dateCursor.getTime() >= startDate.getTime()) { - dateRange.push({ - dayNo: dateCursor.getDay(), - dateStr: dateCursor.toLocaleDateString() - }) - dateCursor.setTime(dateCursor.getTime() - 86400 * 1000) // Step one day backwards until we get to the start date -} -// console.log('$$ dateRange:', dateRange) - const FLine = styled.div` width: 100%; border: 0; @@ -369,21 +231,34 @@ const FFooter = styled.div` const FStudyGroup = styled.div` height: 100%; min-height: 100vh; - margin: 0; + margin: 0 0 60px 0; padding: 0; ` +const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + type TStudyGroup = { commit: Commit userProgressDb: UserProgressDb + initialDate: Date } + const StudyGroup: React.FC = (props) => { // console.log('>> render Study Group') - // const [upDb, setUpDb] = useState(props.userProgressDb) + const [upDb, setUpDb] = useState(props.userProgressDb) const [value, setValue] = useState(0) + const [curDate, setCurDate] = useState(props.initialDate) + + // Load cards + useEffect(() => { + if (curDate !== props.initialDate) { + // console.log('>> Fire sinceDate useEffect', curDate) + Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) + } + }, [curDate]) function updateDashboard (payload: any) { - console.log('>> updateDashboard: ' + value) + console.log('>> updateDashboard: ', value, payload.dt.toDate(), payload.issue.number, payload.issue.title, payload.kind) if (payload.kind === 'issue') { runUpdateIssueFlow(payload) } else if (payload.kind === 'issue_comment') { @@ -444,6 +319,17 @@ const StudyGroup: React.FC = (props) => { return () => unsubscribe() }, []) + function navPrevMonth () { + setCurDate(util.getPrevMonth(curDate)) + } + + function navNextMonth () { + setCurDate(util.getNextMonth(curDate)) + } + + const startDate = new Date('2021-05-03T04:00:00Z') + const dateRange = util.getDateRange(curDate) + return ( @@ -453,7 +339,8 @@ const StudyGroup: React.FC = (props) => { Members    History    Changelog    - CodeNewbie + CodeNewbie    + New Card
@@ -462,15 +349,18 @@ const StudyGroup: React.FC = (props) => { { studyMembers.map((member: StudyMember, i: number) => { const handle = member.userHandle - const streak = upDb.getUser(handle)?.CurrentStreak - const missedDays = upDb.getUser(handle)?.MissedDays + // const streak = upDb.getUser(handle)?.CurrentStreak + // const missedDays = upDb.getUser(handle)?.MissedDays const rs = [] const content =
Member #{i}: {handle} | - Streak: {streak} consecutive days | + {/* Streak: {streak} consecutive days | */} +  Streak: NA | Start: {(new Date(member.startDateStr)).toDateString()} | - Missed Days: {missedDays}
+ {/* Missed Days: {missedDays} */} +  Missed Days: NA +
if (member.active) { rs.push(content) @@ -481,7 +371,18 @@ const StudyGroup: React.FC = (props) => { }) }
-

Progress:

+ +
+ +   {util.printMonthYear(curDate)}   + +
+
+ @@ -489,29 +390,26 @@ const StudyGroup: React.FC = (props) => { . { - dateRange.map((day: TDay, i: number) => { - dateCursor.setDate(dateCursor.getDate() - 1) - return ( -
- - {days[day.dayNo]}
- {day.dateStr.replace('/2021', '/21')} -
- {day.dayNo === 0 && - - } -
- ) - }) + dateRange.map((day: util.TDay, i: number) => +
+ + {days[day.dayNo]}
+ {day.dateStr.replace('/2021', '/21')} +
+ {day.dayNo === 0 && + + } +
+ ) }
{ studyMembers.map((m: StudyMember, i: number) => - m.active + m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() ? { - dateRange.map((day: TDay, i: number) => renderCard(upDb, m, day, i)) + dateRange.map((day: util.TDay, i: number) => renderCard(upDb, m, day, i)) } : @@ -526,7 +424,7 @@ const StudyGroup: React.FC = (props) => { ) } -function renderCard (upDb:UserProgressDb, m:StudyMember, day: TDay, i: number) { +function renderCard (upDb:UserProgressDb, m:StudyMember, day: util.TDay, i: number) { const rs = [] const card = upDb.getUser(m.userHandle)!.getCard(day.dateStr) if (card) { diff --git a/src/data/changelog.json b/src/data/changelog.json index af77811..09bac84 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.1", + "message": "✨ Add `pagination-by-month` to `dashboard GUI`", + "built": "Thu, 24 Jun 2021 18:05:57 EDT" + }, { "version": "1.8.0", "message": "🥭 Begin `sprint-imbe` (Sun - 6/20/21)", diff --git a/src/lib/util.ts b/src/lib/util.ts index 66802dc..320affb 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -49,3 +49,59 @@ export class AutoId { return autoId } } + +export function printMonthYear (d: Date): string { + const options = { + year: 'numeric', + month: 'long' + } + return new Intl.DateTimeFormat('en-US', options as any).format(d) +} + +export function getNextMonth (d: Date): Date { + const nd = new Date(d.getFullYear(), d.getMonth() + 1, d.getDate()) // Step forward one month + // console.log('>> getNextMonth:', d.toDateString(), nd.toDateString()) + return nd +} + +export function getPrevMonth (d: Date): Date { + const nd = new Date(d.getFullYear(), d.getMonth() - 1, 1) // Step backward one month; start on first day + // console.log('>> getPrevMonth:', d.toDateString(), nd.toDateString()) + return nd +} + +export function getPeriod (d: Date): string { + return `${d.getFullYear()}-` + `${d.getMonth() + 1}`.padStart(2, '0') +} + +export function getMonthLastDay (d: Date): Date { + const nd = new Date(d.getFullYear(), d.getMonth() + 1, 0) + return nd +} + +export type TDay = { + dayNo: number + dateStr: string +} + +export function getDateRange (endDate: Date): TDay[] { + const today = new Date() + let dateCursor: Date + if (today.getMonth() === endDate.getMonth()) { + dateCursor = new Date(endDate.getFullYear(), endDate.getMonth(), today.getDate()) // Start on today + } else { + dateCursor = new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0) // Start on the last day of the month + } + + const dateRange = [] as TDay[] + const startDate = new Date(endDate.getFullYear(), endDate.getMonth(), 1) // Stop on the first day of the month at midnight ET + // Eg. Tue Jun 01 2021 00:00:00 GMT-0400 (Eastern Daylight Time) + while (dateCursor.getTime() >= startDate.getTime()) { + dateRange.push({ + dayNo: dateCursor.getDay(), + dateStr: dateCursor.toLocaleDateString() + }) + dateCursor.setTime(dateCursor.getTime() - 86400 * 1000) // Step one day backwards until we get to the start date + } + return dateRange +} diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts new file mode 100644 index 0000000..9584cc5 --- /dev/null +++ b/src/services/GithubApi.ts @@ -0,0 +1,121 @@ +import { UserProgressDb, Tag } from '../models/UserProgress' +import * as util from '../lib/util' + +export const uriAllCards = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100' +// const uriAllCards0 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=r002' +// const uriAllCards1 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=anitabe404' +// const uriAllCards2 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=shazahuang' + +export type StudyMember = { + userFullname: string + userHandle: string + startDateStr: string + uid: string + repo: string + active: boolean +} + +export const studyMembers: StudyMember[] = [ + { + userFullname: 'Robert Lin', + userHandle: 'r002', + startDateStr: '2021-05-03T04:00:00Z', + uid: '45280066', + repo: 'https://github.com/studydash/cards', + active: true + }, + { + userFullname: 'Anita Beauchamp', + userHandle: 'anitabe404', + startDateStr: '2021-05-04T04:00:00Z', + uid: '9167395', + repo: 'https://github.com/studydash/cards', + active: true + }, + { + userFullname: 'Matthew Curcio', + userHandle: 'mccurcio', + startDateStr: '2021-05-10T04:00:00Z', + uid: '1915749', + repo: 'https://github.com/studydash/cards', + active: false + }, + { + userFullname: 'Shaza Huang', + userHandle: 'shazahuang', + startDateStr: '2021-06-18T04:00:00Z', + uid: '85973779', + repo: 'https://github.com/studydash/cards', + active: true + } +] + +export const tagMap = new Map() +tagMap.set('movie trailer', { + name: 'movie trailer', + icon: '🎬' +}) +tagMap.set('tv show', { + name: 'tv show', + icon: '📺' +}) +tagMap.set('youtube', { + name: 'youtube', + icon: '▶' +}) +tagMap.set('reading', { + name: 'reading', + icon: '📖' +}) +tagMap.set('life', { + name: 'life', + icon: '🌳' +}) +tagMap.set('travel', { + name: 'travel', + icon: '🛸' +}) +tagMap.set('podcast notes', { + name: 'podcast notes', + icon: '🎙' +}) + +export async function getUpDb (d: Date): Promise { + const upDb = new UserProgressDb() + for (const member of studyMembers) { + upDb.addUser(member) + } + + const fetchCards = await fetch(uriAllCards + '&labels=' + util.getPeriod(d)) + const allCards = await fetchCards.json() + for (const item of allCards) { + // Ad-hoc code to adjust dates of Anita's cards - 5/11/21 + // This is a total hack. Write a proper `updateCard(...)` method later + if (item.number === 16) { + item.created_at = '2021-05-08T04:00:00Z' + } else if (item.number === 19) { + item.created_at = '2021-05-09T04:00:00Z' + } else if (item.number === 22) { + item.created_at = '2021-05-10T04:00:00Z' + } + + const tags = [] as Tag[] + for (const label of item.labels) { + if (tagMap.has(label.name)) { + tags.push(tagMap.get(label.name)!) // Why is assertion required here? 5/20/21 + } + } + + const cardInput = { + title: item.title, + userHandle: item.user.login, + number: item.number, + createdAt: item.created_at, + updatedAt: item.updated_at, + tags: tags, + comments: item.comments + } + upDb.getUser(cardInput.userHandle)!.setCard(cardInput) + } + return upDb +} From 7aad1c527f992b46258280ffd4ee4e995d58a8cb Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 24 Jun 2021 21:41:25 -0400 Subject: [PATCH 03/30] =?UTF-8?q?=F0=9F=94=96=201.8.2:=20=F0=9F=92=84=20Be?= =?UTF-8?q?autify=20`pagination=20controls`=20on=20`dashboard=20GUI`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 14 ++++++++++++-- src/data/changelog.json | 5 +++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 98939f5..04648f3 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -235,6 +235,15 @@ const FStudyGroup = styled.div` padding: 0; ` +const FMonthTitle = styled.span` + font-size: 18px; + color: black; + background: yellow; + border: 1px yellow solid; + padding: 3px 3px 5px 3px; + margin: 10px; +` + const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] type TStudyGroup = { @@ -337,9 +346,10 @@ const StudyGroup: React.FC = (props) => { Raw Data    Repo    Members    - History    + Screenshots    Changelog    CodeNewbie    + Tasks    New Card
@@ -376,7 +386,7 @@ const StudyGroup: React.FC = (props) => { -   {util.printMonthYear(curDate)}   +   {util.printMonthYear(curDate)}   diff --git a/src/data/changelog.json b/src/data/changelog.json index 09bac84..c31e706 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.2", + "message": "💄 Beautify `pagination controls` on `dashboard GUI`", + "built": "Thu, 24 Jun 2021 21:41:24 EDT" + }, { "version": "1.8.1", "message": "✨ Add `pagination-by-month` to `dashboard GUI`", From 7f69062323945000e580440f5fc31667186a535f Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 1 Jul 2021 16:07:18 -0400 Subject: [PATCH 04/30] =?UTF-8?q?=F0=9F=94=96=201.8.3:=20=E2=9C=A8=20Impl?= =?UTF-8?q?=20live=20`Current/Max=20Streak`=20on=20`dashboard=20GUI`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 58 ++++++++++++++++++++----------------- src/data/changelog.json | 5 ++++ src/models/UserProgress.ts | 35 ---------------------- src/services/GithubApi.ts | 9 ++++-- src/widgets/MembersPane.tsx | 36 +++++++++++++++++++++++ 5 files changed, 78 insertions(+), 65 deletions(-) create mode 100644 src/widgets/MembersPane.tsx diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 04648f3..2aa4f64 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -3,11 +3,12 @@ import React, { useState, useEffect } from 'react' import styled, { css } from 'styled-components' import { UserProgressDb, Tag } from './models/UserProgress' import CountdownClock from './widgets/CountdownClock' +import MembersPane from './widgets/MembersPane' import * as util from './lib/util' import changelogUri from './data/changelog.json' import './providers/AuthContext' import firebase from 'firebase/app' -import { getUpDb, tagMap, uriAllCards, studyMembers, StudyMember } from './services/GithubApi' +import { getUpDb, tagMap, uriAllCards, StudyMember } from './services/GithubApi' type Commit = { version: string @@ -257,6 +258,7 @@ const StudyGroup: React.FC = (props) => { const [upDb, setUpDb] = useState(props.userProgressDb) const [value, setValue] = useState(0) const [curDate, setCurDate] = useState(props.initialDate) + const [members, setMembers] = useState>([]) // Load cards useEffect(() => { @@ -318,7 +320,32 @@ const StudyGroup: React.FC = (props) => { upDb.getUser(cardInput.userHandle)!.setCard(cardInput) } - // Listen for latest updates from Firestore + // Listen for latest member stats updates from Firestore + useEffect(() => { + const unsubscribe = firebase.firestore().collection('members') + .onSnapshot((querySnapshot) => { + const members = [] as Array + querySnapshot.forEach((doc) => { + const member = doc.data() + members.push({ + userFullname: member.Fullname, + userHandle: member.Handle, + startDateStr: member.StartDate, + uid: member.Uid, + repo: member.Repo, + active: member.Active, + streakCurrent: member.StreakCurrent, + streakMax: member.StreakMax, + recordCount: member.RecordCount + }) + }) + setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) + console.log('>> member stats update received: ', new Date()) + }) + return () => unsubscribe() + }, []) + + // Listen for latest card updates from Firestore useEffect(() => { const unsubscribe = firebase.firestore().collection('ghUpdates').doc('latestUpdate') .onSnapshot((doc) => { @@ -356,30 +383,7 @@ const StudyGroup: React.FC = (props) => {

Study Group 00:

- { - studyMembers.map((member: StudyMember, i: number) => { - const handle = member.userHandle - // const streak = upDb.getUser(handle)?.CurrentStreak - // const missedDays = upDb.getUser(handle)?.MissedDays - const rs = [] - const content = -
- Member #{i}: {handle} | - {/* Streak: {streak} consecutive days | */} -  Streak: NA | - Start: {(new Date(member.startDateStr)).toDateString()} | - {/* Missed Days: {missedDays} */} -  Missed Days: NA -
-
- if (member.active) { - rs.push(content) - } else { - rs.push({content}) - } - return (rs) - }) - } +
@@ -414,7 +418,7 @@ const StudyGroup: React.FC = (props) => { } { - studyMembers.map((m: StudyMember, i: number) => + members.map((m: StudyMember, i: number) => m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() ? diff --git a/src/data/changelog.json b/src/data/changelog.json index c31e706..b4c48db 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.3", + "message": "✨ Impl live `Current/Max Streak` on `dashboard GUI`", + "built": "Thu, 01 Jul 2021 16:07:17 EDT" + }, { "version": "1.8.2", "message": "💄 Beautify `pagination controls` on `dashboard GUI`", diff --git a/src/models/UserProgress.ts b/src/models/UserProgress.ts index 9c9f0e4..8330625 100644 --- a/src/models/UserProgress.ts +++ b/src/models/UserProgress.ts @@ -68,41 +68,6 @@ class UserProgress { getCard (dateStr: string) { return this._cards.get(dateStr) } - - calculateStreak () { - // console.log('>> Calculate streak for:', this.userHandle) - const dateCursor = new Date() // Start on today - // Generate the date range we're interested in - const dateRange = [] as string[] - while (dateCursor.getTime() >= this.startDate.getTime()) { - dateRange.push(dateCursor.toLocaleDateString()) - dateCursor.setTime(dateCursor.getTime() - 86400 * 1000) // Step one day backwards until we get to the start date - } - // console.log('>> dateRange:', this.startDate.getDate(), dateRange) - for (const dateStr of dateRange) { - // console.log('>> dateStr:', dateStr) - if (this._cards.has(dateStr)) { - this._streakCurrent++ - } else { - const today = new Date() - if (today.toLocaleDateString() !== dateStr) { // Don't do anything if user hasn't yet contributed today - // console.log('>> Resetting streak!') - this._streakCurrent = 0 // Reset the streak - this._missedDays++ - } - } - } - } - - get CurrentStreak () { - this._streakCurrent = this._missedDays = 0 - this.calculateStreak() - return this._streakCurrent - } - - get MissedDays () { - return this._missedDays - } } export class UserProgressDb { diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index 9584cc5..1c22eb0 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -12,10 +12,13 @@ export type StudyMember = { startDateStr: string uid: string repo: string - active: boolean + active: boolean, + streakCurrent: number, + streakMax: number, + recordCount: number } -export const studyMembers: StudyMember[] = [ +const members = [ { userFullname: 'Robert Lin', userHandle: 'r002', @@ -82,7 +85,7 @@ tagMap.set('podcast notes', { export async function getUpDb (d: Date): Promise { const upDb = new UserProgressDb() - for (const member of studyMembers) { + for (const member of members) { upDb.addUser(member) } diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx new file mode 100644 index 0000000..979d3cd --- /dev/null +++ b/src/widgets/MembersPane.tsx @@ -0,0 +1,36 @@ +import React from 'react' +import { StudyMember } from '../services/GithubApi' + +type TMembersPane = { + members: Array +} + +const MembersPane: React.FC = (props) => { + return ( + <> + { + props.members.map((member: StudyMember, i: number) => { + const handle = member.userHandle + const rs = [] + const content = +
+ Member #{i}: {handle} | + Start: {(new Date(member.startDateStr)).toDateString()} | + Max Streak: {member.streakMax} | + Current Streak: {member.streakCurrent} | + Total Days: {member.recordCount} +
+
+ if (member.active) { + rs.push(content) + } else { + rs.push({content}) + } + return (rs) + }) + } + + ) +} + +export default MembersPane From a8c9527c266762341022e8c90b53b189641d5fc3 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 1 Jul 2021 20:41:52 -0400 Subject: [PATCH 05/30] =?UTF-8?q?=F0=9F=94=96=201.8.4:=20=E2=9C=A8=20Add?= =?UTF-8?q?=20`{StartDate}=20to=20{EndDate}`=20title=20when=20hovering=20o?= =?UTF-8?q?ver=20`Streak=20Numbers`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 31 ++++++++++++++++++++----------- src/data/changelog.json | 5 +++++ src/services/GithubApi.ts | 23 ++++++++++------------- src/widgets/MembersPane.tsx | 19 ++++++++++++++----- 4 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 2aa4f64..7e22fca 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -322,21 +322,30 @@ const StudyGroup: React.FC = (props) => { // Listen for latest member stats updates from Firestore useEffect(() => { - const unsubscribe = firebase.firestore().collection('members') + const unsubscribe = firebase.firestore().collection('studyMembers') .onSnapshot((querySnapshot) => { const members = [] as Array querySnapshot.forEach((doc) => { - const member = doc.data() + const m = doc.data() members.push({ - userFullname: member.Fullname, - userHandle: member.Handle, - startDateStr: member.StartDate, - uid: member.Uid, - repo: member.Repo, - active: member.Active, - streakCurrent: member.StreakCurrent, - streakMax: member.StreakMax, - recordCount: member.RecordCount + userFullname: m.Fullname, + userHandle: m.Handle, + startDateStr: m.StartDate, + uid: m.Uid, + repo: m.Repo, + active: m.Active, + streakCurrent: { + days: m.StreakCurrent.Days, + startDate: m.StreakCurrent.StartDate, + endDate: m.StreakCurrent.EndDate + }, + streakMax: { + days: m.StreakMax.Days, + startDate: m.StreakMax.StartDate, + endDate: m.StreakMax.EndDate + }, + recordCount: m.RecordCount, + daysJoined: m.DaysJoined }) }) setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) diff --git a/src/data/changelog.json b/src/data/changelog.json index b4c48db..61e2838 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.4", + "message": "✨ Add `{StartDate} to {EndDate}` title when hovering over `Streak Numbers`", + "built": "Thu, 01 Jul 2021 20:41:52 EDT" + }, { "version": "1.8.3", "message": "✨ Impl live `Current/Max Streak` on `dashboard GUI`", diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index 1c22eb0..710d38e 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -6,6 +6,12 @@ export const uriAllCards = 'https://api.github.com/repos/studydash/cards/issues? // const uriAllCards1 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=anitabe404' // const uriAllCards2 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=shazahuang' +export type Streak = { + days: number, + startDate: string, + endDate: string +} + export type StudyMember = { userFullname: string userHandle: string @@ -13,9 +19,10 @@ export type StudyMember = { uid: string repo: string active: boolean, - streakCurrent: number, - streakMax: number, - recordCount: number + streakCurrent: Streak, + streakMax: Streak, + recordCount: number, + daysJoined: number } const members = [ @@ -92,16 +99,6 @@ export async function getUpDb (d: Date): Promise { const fetchCards = await fetch(uriAllCards + '&labels=' + util.getPeriod(d)) const allCards = await fetchCards.json() for (const item of allCards) { - // Ad-hoc code to adjust dates of Anita's cards - 5/11/21 - // This is a total hack. Write a proper `updateCard(...)` method later - if (item.number === 16) { - item.created_at = '2021-05-08T04:00:00Z' - } else if (item.number === 19) { - item.created_at = '2021-05-09T04:00:00Z' - } else if (item.number === 22) { - item.created_at = '2021-05-10T04:00:00Z' - } - const tags = [] as Tag[] for (const label of item.labels) { if (tagMap.has(label.name)) { diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx index 979d3cd..9e2664d 100644 --- a/src/widgets/MembersPane.tsx +++ b/src/widgets/MembersPane.tsx @@ -1,10 +1,20 @@ import React from 'react' -import { StudyMember } from '../services/GithubApi' +import { StudyMember, Streak } from '../services/GithubApi' + +const FStreak: React.FC = (streak) => { + return ( + streak.days !== 0 + ? + {streak.days} + + : {streak.days} + ) +} type TMembersPane = { members: Array } - const MembersPane: React.FC = (props) => { return ( <> @@ -16,9 +26,8 @@ const MembersPane: React.FC = (props) => {
Member #{i}: {handle} | Start: {(new Date(member.startDateStr)).toDateString()} | - Max Streak: {member.streakMax} | - Current Streak: {member.streakCurrent} | - Total Days: {member.recordCount} + Streaks (Max/Current): / | + Total Days: {member.recordCount}/{member.daysJoined}
if (member.active) { From 4cb7e890eac7a2b45cded9eafb8e041bcf102d1f Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Sat, 3 Jul 2021 22:54:33 -0400 Subject: [PATCH 06/30] =?UTF-8?q?=F0=9F=94=96=201.8.5:=20=F0=9F=92=84=20Be?= =?UTF-8?q?autify=20`MembersPane`=20to=20display=20`Current=20Streak`=20de?= =?UTF-8?q?tails=20on=20newline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/changelog.json | 5 +++++ src/widgets/MembersPane.tsx | 22 ++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/data/changelog.json b/src/data/changelog.json index 61e2838..bec0297 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.5", + "message": "💄 Beautify `MembersPane` to display `Current Streak` details on newline", + "built": "Sat, 03 Jul 2021 22:54:32 EDT" + }, { "version": "1.8.4", "message": "✨ Add `{StartDate} to {EndDate}` title when hovering over `Streak Numbers`", diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx index 9e2664d..2742fc8 100644 --- a/src/widgets/MembersPane.tsx +++ b/src/widgets/MembersPane.tsx @@ -17,18 +17,24 @@ type TMembersPane = { } const MembersPane: React.FC = (props) => { return ( - <> +
{ props.members.map((member: StudyMember, i: number) => { const handle = member.userHandle const rs = [] const content = -
- Member #{i}: {handle} | - Start: {(new Date(member.startDateStr)).toDateString()} | - Streaks (Max/Current): / | - Total Days: {member.recordCount}/{member.daysJoined} -
+
+
+ 🧙‍♂️ + Member #{i}: {handle} | + Start: {(new Date(member.startDateStr)).toDateString()} | + Streak Max: | + Total Days: {member.recordCount}/{member.daysJoined} +
+
+ Streak Current: days | + Lastest Submission: { member.streakCurrent.endDate !== '' ? member.streakCurrent.endDate : 'N/A'} +
if (member.active) { rs.push(content) @@ -38,7 +44,7 @@ const MembersPane: React.FC = (props) => { return (rs) }) } - +
) } From d68bf9b9d88b1e0dbc29ffd9a4137e03a98b785e Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Mon, 5 Jul 2021 21:52:55 -0400 Subject: [PATCH 07/30] =?UTF-8?q?=F0=9F=94=96=201.8.6:=20=E2=9C=A8=20Updat?= =?UTF-8?q?e=20`MembersPane`=20to=20show=20latest=20submitted=20card=20num?= =?UTF-8?q?ber?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 3 ++- src/data/changelog.json | 5 +++++ src/services/GithubApi.ts | 3 ++- src/widgets/MembersPane.tsx | 4 +++- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 7e22fca..cc83ce8 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -345,7 +345,8 @@ const StudyGroup: React.FC = (props) => { endDate: m.StreakMax.EndDate }, recordCount: m.RecordCount, - daysJoined: m.DaysJoined + daysJoined: m.DaysJoined, + latestCardNo: m.Record[m.StreakCurrent.EndDate] }) }) setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) diff --git a/src/data/changelog.json b/src/data/changelog.json index bec0297..3d52d50 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.6", + "message": "✨ Update `MembersPane` to show latest submitted card number", + "built": "Mon, 05 Jul 2021 21:52:54 EDT" + }, { "version": "1.8.5", "message": "💄 Beautify `MembersPane` to display `Current Streak` details on newline", diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index 710d38e..6fc09ea 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -22,7 +22,8 @@ export type StudyMember = { streakCurrent: Streak, streakMax: Streak, recordCount: number, - daysJoined: number + daysJoined: number, + latestCardNo: number } const members = [ diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx index 2742fc8..7f5296e 100644 --- a/src/widgets/MembersPane.tsx +++ b/src/widgets/MembersPane.tsx @@ -33,7 +33,9 @@ const MembersPane: React.FC = (props) => {
Streak Current: days | - Lastest Submission: { member.streakCurrent.endDate !== '' ? member.streakCurrent.endDate : 'N/A'} + Latest Submission: { member.streakCurrent.endDate !== '' + ? `#${member.latestCardNo} (${member.streakCurrent.endDate})` + : 'N/A'}
if (member.active) { From ed519b19ae32a0acb334e2df07323fba3780ee62 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 6 Jul 2021 17:05:55 -0400 Subject: [PATCH 08/30] =?UTF-8?q?=F0=9F=94=96=201.8.7:=20=E2=9C=A8=20Suppo?= =?UTF-8?q?rt=20`=3Fd=3DYYYY-MM`=20GET=20{param}=20in=20url?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 10 +++++++--- src/data/changelog.json | 5 +++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index cc83ce8..3cd10ab 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -10,13 +10,16 @@ import './providers/AuthContext' import firebase from 'firebase/app' import { getUpDb, tagMap, uriAllCards, StudyMember } from './services/GithubApi' +// Display cards for a specific date if passed in; else, display the current month's cards +const m = window.location.href.match(/^.*d=(\d{4}-\d{2})$/) // d is expected to be YYYY-MM; eg. "2021-06" +const initialDate = m?.[1] ? new Date(Date.parse(m?.[1] + '-01T04:00:00Z')) : new Date() // Currently assume ET - 7/6/21 + type Commit = { version: string message: string built: Date } -const initialDate = new Date() const fetchVersion = fetch(changelogUri) Promise.all([fetchVersion, getUpDb(initialDate)]).then(responses => { const jsonVersion = responses[0].json() @@ -254,11 +257,11 @@ type TStudyGroup = { } const StudyGroup: React.FC = (props) => { - // console.log('>> render Study Group') const [upDb, setUpDb] = useState(props.userProgressDb) const [value, setValue] = useState(0) const [curDate, setCurDate] = useState(props.initialDate) const [members, setMembers] = useState>([]) + // console.log('>> curDate - initial load:', curDate) // Load cards useEffect(() => { @@ -266,6 +269,7 @@ const StudyGroup: React.FC = (props) => { // console.log('>> Fire sinceDate useEffect', curDate) Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) } + history.pushState({}, '', 'study-group.html?d=' + curDate.toISOString().slice(0, 7)) }, [curDate]) function updateDashboard (payload: any) { @@ -386,7 +390,7 @@ const StudyGroup: React.FC = (props) => { Screenshots    Changelog    CodeNewbie    - Tasks    + Tasks    New Card
diff --git a/src/data/changelog.json b/src/data/changelog.json index 3d52d50..7bb332f 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.7", + "message": "✨ Support `?d=YYYY-MM` GET {param} in url", + "built": "Tue, 06 Jul 2021 17:05:54 EDT" + }, { "version": "1.8.6", "message": "✨ Update `MembersPane` to show latest submitted card number", From b9eb33051c40eb51e933af387eb4d2aba7acc502 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 6 Jul 2021 22:37:58 -0400 Subject: [PATCH 09/30] =?UTF-8?q?=F0=9F=94=96=201.8.8:=20=E2=9C=A8=20Chang?= =?UTF-8?q?e=20url=20to=20`/studydash`=20&=20add=20support=20for=20`Previe?= =?UTF-8?q?wer=20Frame`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/preview/index.html | 47 +++++++++++++++++++++++++++++++++++++++ src/StudyGroup.tsx | 4 ++-- src/data/changelog.json | 5 +++++ webpack.common.js | 11 +++++++-- 4 files changed, 63 insertions(+), 4 deletions(-) create mode 100644 public/preview/index.html diff --git a/public/preview/index.html b/public/preview/index.html new file mode 100644 index 0000000..659c343 --- /dev/null +++ b/public/preview/index.html @@ -0,0 +1,47 @@ + + + + + Studydash - Preview QA + + + + + +
+
+ URL: N/A +
+ +
+ + \ No newline at end of file diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 3cd10ab..82920a6 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -234,7 +234,6 @@ const FFooter = styled.div` const FStudyGroup = styled.div` height: 100%; - min-height: 100vh; margin: 0 0 60px 0; padding: 0; ` @@ -269,7 +268,8 @@ const StudyGroup: React.FC = (props) => { // console.log('>> Fire sinceDate useEffect', curDate) Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) } - history.pushState({}, '', 'study-group.html?d=' + curDate.toISOString().slice(0, 7)) + history.pushState({}, '', '/studydash/?d=' + curDate.toISOString().slice(0, 7)) + window.parent.postMessage(window.location.href, '*') }, [curDate]) function updateDashboard (payload: any) { diff --git a/src/data/changelog.json b/src/data/changelog.json index 7bb332f..005bf91 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.8", + "message": "✨ Change url to `/studydash` \u0026 add support for `Previewer Frame`", + "built": "Tue, 06 Jul 2021 22:37:58 EDT" + }, { "version": "1.8.7", "message": "✨ Support `?d=YYYY-MM` GET {param} in url", diff --git a/webpack.common.js b/webpack.common.js index 3b7d812..03e7738 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -17,17 +17,24 @@ module.exports = { }), new HtmlWebpackPlugin({ title: 'Wattpad POC', - filename: 'wattpad.html', + filename: './wattpad/index.html', template: './public/wattpad.html', favicon: './public/favicon.ico', chunks: ['wattpad'] }), new HtmlWebpackPlugin({ title: 'Study Group 00', - filename: 'study-group.html', + filename: './studydash/index.html', template: './public/study-group.html', favicon: './public/favicon.ico', chunks: ['StudyGroup'] + }), + new HtmlWebpackPlugin({ + title: 'Preview', + filename: './preview/index.html', + template: './public/preview/index.html', + favicon: './public/favicon.ico', + chunks: [] }) ], module: { From 7c2acada8f5169fd3a587d617f40b310caf2e349 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Wed, 7 Jul 2021 02:26:35 -0400 Subject: [PATCH 10/30] =?UTF-8?q?=F0=9F=94=96=201.8.9:=20=F0=9F=90=9E=20Fi?= =?UTF-8?q?x=20bug:=20Clicking=20on=20cards=20now=20opens=20them=20in=20`t?= =?UTF-8?q?arget=3D'=5Ftop'`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/preview/index.html | 7 ++++--- src/StudyGroup.tsx | 2 +- src/data/changelog.json | 5 +++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/public/preview/index.html b/public/preview/index.html index 659c343..d39e695 100644 --- a/public/preview/index.html +++ b/public/preview/index.html @@ -2,7 +2,7 @@ - Studydash - Preview QA + StudyDash - Preview QA
- Latest QA Build: N/A +
Latest QA Build:
- +
\ No newline at end of file diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 943bcfd..1357c17 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -240,9 +240,9 @@ const FStudyGroup = styled.div` const FMonthTitle = styled.span` font-size: 18px; - color: black; - background: yellow; - border: 1px yellow solid; + color: white; + background: #161b22; + border: 1px #30363d solid; padding: 3px 3px 5px 3px; margin: 10px; ` diff --git a/src/data/changelog.json b/src/data/changelog.json index 0e3acd9..d3456fe 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.11", + "message": "✨ Support `pass-thru` `GET {params}` in `Previewer` top-level url", + "built": "Wed, 07 Jul 2021 17:24:35 EDT" + }, { "version": "1.8.10", "message": "🐞 Fix bug: Clicking on top navbar links now opens them in `target='_top'`", From e11961be65141673a40feede67d8fbee41aa5419 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 8 Jul 2021 16:50:49 -0400 Subject: [PATCH 13/30] =?UTF-8?q?=F0=9F=94=96=201.8.12:=20=E2=9C=A8=20Add?= =?UTF-8?q?=20`octicon=20comments`=20icon=20&=20update=20the=20GUI=20in=20?= =?UTF-8?q?real-time=20on=20every=20new=20comment=20+/-?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/study-group.html | 11 +++++++ src/StudyGroup.tsx | 65 ++++++++++++++++++++++++-------------- src/data/changelog.json | 5 +++ src/models/UserProgress.ts | 16 ++++++++-- src/services/GithubApi.ts | 12 +++++++ 5 files changed, 82 insertions(+), 27 deletions(-) diff --git a/public/study-group.html b/public/study-group.html index a9462cb..7e7eb8b 100644 --- a/public/study-group.html +++ b/public/study-group.html @@ -42,6 +42,17 @@ .octicon { fill: #a5b5bb; + margin-top: 2px; + margin-bottom: -3px; + padding-right: 6px; + /* background: pink; */ + } + + .commentNo { + font-weight: 600; + font-size: 13px; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; + color: #a5b5bb; } diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 1357c17..6f8c056 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -107,15 +107,15 @@ const CardComp: React.FC = (props) => { | 🍿 }
-
+
{props.comments !== 0 && - - {props.comments} + + + {props.comments} } - {/* | {props.comments} */}
@@ -255,9 +255,11 @@ type TStudyGroup = { initialDate: Date } +let globalInitialLoad = true // Hack. 7/8/21 + const StudyGroup: React.FC = (props) => { const [upDb, setUpDb] = useState(props.userProgressDb) - const [value, setValue] = useState(0) + const [value, setValue] = useState(new Date()) const [curDate, setCurDate] = useState(props.initialDate) const [members, setMembers] = useState>([]) // console.log('>> curDate - initial load:', curDate) @@ -272,26 +274,41 @@ const StudyGroup: React.FC = (props) => { window.parent.postMessage(window.location.href, '*') }, [curDate]) + // This should NOT run on initial load. 7/8/21 function updateDashboard (payload: any) { - console.log('>> updateDashboard: ', value, payload.dt.toDate(), payload.issue.number, payload.issue.title, payload.kind) - if (payload.kind === 'issue') { - runUpdateIssueFlow(payload) - } else if (payload.kind === 'issue_comment') { - runUpdateIssueCommentFlow(payload) + if (globalInitialLoad) { + console.log('>> Initial load detected. Skipping dashboard refresh') + globalInitialLoad = false // Flip the one-time flag. Hack. 7/8/21 + } else { + console.log('>> updateDashboard:', payload.dt.toDate().toISOString(), payload.issue.number, payload.issue.title, payload.kind) + if (payload.kind === 'issue') { + runUpdateIssueFlow(payload) + } else if (payload.kind === 'issue_comment') { + runUpdateIssueCommentFlow(payload) + } + setValue(new Date()) // Force update hack to repaint React GUI. 5/31/21 } - setValue(oldVal => oldVal + 1) // Force update hack to repaint React GUI. 5/31/21 } - // Bug with GitHub? Comment count seems buggy. 6/1/21 function runUpdateIssueCommentFlow (payload:any) { - console.log('>> TODO: runUpdateIssueCommentFlow:', payload.action, payload.kind) - // Currently broken - need to reach out to GitHub for guidance. 6/2/21 - // const dateStr = (new Date(payload.issue.created_at)).toLocaleDateString() - // if (payload.action === 'created') { - // upDb.getUser(payload.issue.user.login)!.getCard(dateStr)!.comments++ - // } else if (payload.action === 'deleted') { - // upDb.getUser(payload.issue.user.login)!.getCard(dateStr)!.comments-- - // } + // For now, until GitHub fixes the `comments number payload` bug, just + // query the GitHub REST API to refresh the entire GUI to get all up-to-date comment counts. 7/8/21 + console.log('>> Run: UpdateIssueCommentFlow:', payload.action, payload.kind, payload.issue.number, payload.issue.user.login) + if (payload.action === 'created') { + upDb.getUser(payload.issue.user.login)?.incrementComments(payload.issue.number) + } else if (payload.action === 'deleted') { + upDb.getUser(payload.issue.user.login)?.decrementComments(payload.issue.number) + } + + // Experimental; remove this later. Keeping here for future reference. 7/8/21 + // // getNumberOfCommentsPerCard(payload.issue.number) + // // This is a total hack; we wait 61 seconds for the GitHub-side to propogate the change before fetching from them again. 7/8/21 + // const d = new Date() + // console.log('>>>>>> Begin timer to query GitHub:', d) + // setTimeout(() => { + // console.log('>>>>>> Now querying GitHub - 61 secs later...', d) + // Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) + // }, 61000) } function runUpdateIssueFlow (payload:any) { @@ -363,7 +380,7 @@ const StudyGroup: React.FC = (props) => { useEffect(() => { const unsubscribe = firebase.firestore().collection('ghUpdates').doc('latestUpdate') .onSnapshot((doc) => { - // console.log('Data update received: ', doc.data()) + // console.log('>> doc.data():', doc.data()) updateDashboard(doc.data()) }) return () => unsubscribe() @@ -396,7 +413,7 @@ const StudyGroup: React.FC = (props) => {
-

Study Group 00:

+

{value.toISOString()} | Study Group 00:


diff --git a/src/data/changelog.json b/src/data/changelog.json index d3456fe..9108482 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.12", + "message": "✨ Add `octicon comments` icon \u0026 update the GUI in real-time on every new comment +/-", + "built": "Thu, 08 Jul 2021 16:50:49 EDT" + }, { "version": "1.8.11", "message": "✨ Support `pass-thru` `GET {params}` in `Previewer` top-level url", diff --git a/src/models/UserProgress.ts b/src/models/UserProgress.ts index 8330625..5139654 100644 --- a/src/models/UserProgress.ts +++ b/src/models/UserProgress.ts @@ -50,7 +50,8 @@ class UserProgress { userFullname: string userHandle: string startDate: Date - _cards = new Map() + _cardsByDate = new Map() // Index key: Eg. '7/8/2021' + _cardsByNo = new Map() // Index key: Eg. 185 _streakCurrent = 0 _missedDays = 0 @@ -62,11 +63,20 @@ class UserProgress { setCard (cardInput: TCardInput) { const card = new Card(cardInput) - this._cards.set(card.createdStr, card) + this._cardsByDate.set(card.createdStr, card) + this._cardsByNo.set(card.number, card) } getCard (dateStr: string) { - return this._cards.get(dateStr) + return this._cardsByDate.get(dateStr) + } + + incrementComments (cardNo: number) { + this._cardsByNo.get(cardNo)!.comments++ + } + + decrementComments (cardNo: number) { + this._cardsByNo.get(cardNo)!.comments-- } } diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index 6fc09ea..d3dd2e8 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -91,6 +91,18 @@ tagMap.set('podcast notes', { icon: '🎙' }) +// Experimental; remove this later. Keeping here for future reference. 7/8/21 +// export async function getNumberOfCommentsPerCard (cardNo: number) { +// const url = `https://api.github.com/repos/studydash/cards/issues/${cardNo}/comments` +// const fetchTimeline = await fetch(url, { +// // headers: { +// // Accept: 'application/vnd.github.mockingbird-preview+json' +// // } +// }) +// const rs = await fetchTimeline.json() +// console.log('>>rs', rs) +// } + export async function getUpDb (d: Date): Promise { const upDb = new UserProgressDb() for (const member of members) { From 41e15092dda60c7c0642b0fa8cbfa58a7385dfa1 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 8 Jul 2021 21:23:27 -0400 Subject: [PATCH 14/30] =?UTF-8?q?=F0=9F=94=96=201.8.13:=20=F0=9F=94=8A=20A?= =?UTF-8?q?dd=20more=20debug=20logging=20to=20the=20`+/-=20comment=20count?= =?UTF-8?q?`=20logic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/preview/index.html | 4 +++- src/StudyGroup.tsx | 10 ++++++---- src/data/changelog.json | 5 +++++ src/models/UserProgress.ts | 6 +++++- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/public/preview/index.html b/public/preview/index.html index 52e8609..ce4caee 100644 --- a/public/preview/index.html +++ b/public/preview/index.html @@ -28,8 +28,10 @@ #urlLabel { font-weight: bold; - width: 135px; + /* width: 135px; */ padding-top: 5px; + padding-right: 10px; + white-space: nowrap; } #urlBox { diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 6f8c056..f4c3d36 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -293,11 +293,13 @@ const StudyGroup: React.FC = (props) => { function runUpdateIssueCommentFlow (payload:any) { // For now, until GitHub fixes the `comments number payload` bug, just // query the GitHub REST API to refresh the entire GUI to get all up-to-date comment counts. 7/8/21 - console.log('>> Run: UpdateIssueCommentFlow:', payload.action, payload.kind, payload.issue.number, payload.issue.user.login) + console.log('\t>> Run: UpdateIssueCommentFlow:', payload.action, payload.kind, payload.issue.number, payload.issue.user.login) if (payload.action === 'created') { upDb.getUser(payload.issue.user.login)?.incrementComments(payload.issue.number) + console.log('\t\t>> Comments count++:', upDb.getUser(payload.issue.user.login)?.getCardByNo(payload.issue.number)?.comments) } else if (payload.action === 'deleted') { upDb.getUser(payload.issue.user.login)?.decrementComments(payload.issue.number) + console.log('\t\t>> Comments count--:', upDb.getUser(payload.issue.user.login)?.getCardByNo(payload.issue.number)?.comments) } // Experimental; remove this later. Keeping here for future reference. 7/8/21 @@ -371,7 +373,7 @@ const StudyGroup: React.FC = (props) => { }) }) setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) - console.log('>> member stats update received: ', new Date()) + console.log('>> member stats update received:', (new Date()).toISOString()) }) return () => unsubscribe() }, []) @@ -413,7 +415,7 @@ const StudyGroup: React.FC = (props) => {
-

{value.toISOString()} | Study Group 00:

+

Study Group 00 | {value.toISOString()}


@@ -471,7 +473,7 @@ const StudyGroup: React.FC = (props) => { function renderCard (upDb:UserProgressDb, m:StudyMember, day: util.TDay, i: number) { const rs = [] - const card = upDb.getUser(m.userHandle)!.getCard(day.dateStr) + const card = upDb.getUser(m.userHandle)!.getCardByDate(day.dateStr) if (card) { rs.push() diff --git a/src/data/changelog.json b/src/data/changelog.json index 9108482..1eb5061 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.13", + "message": "🔊 Add more debug logging to the `+/- comment count` logic", + "built": "Thu, 08 Jul 2021 21:23:26 EDT" + }, { "version": "1.8.12", "message": "✨ Add `octicon comments` icon \u0026 update the GUI in real-time on every new comment +/-", diff --git a/src/models/UserProgress.ts b/src/models/UserProgress.ts index 5139654..cde86f4 100644 --- a/src/models/UserProgress.ts +++ b/src/models/UserProgress.ts @@ -67,10 +67,14 @@ class UserProgress { this._cardsByNo.set(card.number, card) } - getCard (dateStr: string) { + getCardByDate (dateStr: string) { return this._cardsByDate.get(dateStr) } + getCardByNo (cardNo: number) { + return this._cardsByNo.get(cardNo) + } + incrementComments (cardNo: number) { this._cardsByNo.get(cardNo)!.comments++ } From db2d8abf7fafda86728c924d92b7066d5843019c Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 8 Jul 2021 22:27:09 -0400 Subject: [PATCH 15/30] =?UTF-8?q?=F0=9F=94=96=201.8.14:=20=F0=9F=90=9E=20F?= =?UTF-8?q?ix=20error=20that=20was=20being=20thrown=20if=20comment=20was?= =?UTF-8?q?=20+/-=20to=20a=20card=20not=20currently=20in-view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 12 +++++++----- src/data/changelog.json | 5 +++++ src/models/UserProgress.ts | 10 ++++++++-- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index f4c3d36..d5d4f26 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -256,6 +256,7 @@ type TStudyGroup = { } let globalInitialLoad = true // Hack. 7/8/21 +let globalUpDb: UserProgressDb const StudyGroup: React.FC = (props) => { const [upDb, setUpDb] = useState(props.userProgressDb) @@ -264,10 +265,13 @@ const StudyGroup: React.FC = (props) => { const [members, setMembers] = useState>([]) // console.log('>> curDate - initial load:', curDate) + // Set local instance to global instance + globalUpDb = upDb + // Load cards useEffect(() => { if (curDate !== props.initialDate) { - // console.log('>> Fire sinceDate useEffect', curDate) + console.log('>> Changing date periods', curDate) Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) } history.pushState({}, '', '/studydash/?d=' + curDate.toISOString().slice(0, 7)) @@ -295,11 +299,9 @@ const StudyGroup: React.FC = (props) => { // query the GitHub REST API to refresh the entire GUI to get all up-to-date comment counts. 7/8/21 console.log('\t>> Run: UpdateIssueCommentFlow:', payload.action, payload.kind, payload.issue.number, payload.issue.user.login) if (payload.action === 'created') { - upDb.getUser(payload.issue.user.login)?.incrementComments(payload.issue.number) - console.log('\t\t>> Comments count++:', upDb.getUser(payload.issue.user.login)?.getCardByNo(payload.issue.number)?.comments) + globalUpDb.getUser(payload.issue.user.login)?.incrementComments(payload.issue.number) } else if (payload.action === 'deleted') { - upDb.getUser(payload.issue.user.login)?.decrementComments(payload.issue.number) - console.log('\t\t>> Comments count--:', upDb.getUser(payload.issue.user.login)?.getCardByNo(payload.issue.number)?.comments) + globalUpDb.getUser(payload.issue.user.login)?.decrementComments(payload.issue.number) } // Experimental; remove this later. Keeping here for future reference. 7/8/21 diff --git a/src/data/changelog.json b/src/data/changelog.json index 1eb5061..91200d2 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.14", + "message": "🐞 Fix error that was being thrown if comment was +/- to a card not currently in-view", + "built": "Thu, 08 Jul 2021 22:27:09 EDT" + }, { "version": "1.8.13", "message": "🔊 Add more debug logging to the `+/- comment count` logic", diff --git a/src/models/UserProgress.ts b/src/models/UserProgress.ts index cde86f4..d32b55b 100644 --- a/src/models/UserProgress.ts +++ b/src/models/UserProgress.ts @@ -76,11 +76,17 @@ class UserProgress { } incrementComments (cardNo: number) { - this._cardsByNo.get(cardNo)!.comments++ + if (this._cardsByNo.has(cardNo)) { + this._cardsByNo.get(cardNo)!.comments++ + // console.log('\t\t>> Comments count++:', this._cardsByNo.get(cardNo)!.comments) + } } decrementComments (cardNo: number) { - this._cardsByNo.get(cardNo)!.comments-- + if (this._cardsByNo.has(cardNo)) { + this._cardsByNo.get(cardNo)!.comments-- + // console.log('\t\t>> Comments count--:', this._cardsByNo.get(cardNo)!.comments) + } } } From 38b0752436af8aa6f43485f6dc1c1d90a9e6052b Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 15 Jul 2021 22:15:45 -0400 Subject: [PATCH 16/30] =?UTF-8?q?=F0=9F=94=96=201.8.15:=20=E2=9C=A8=20Reva?= =?UTF-8?q?mp=20`MembersPane`=20to=20better=20visually=20show=20`Missed=20?= =?UTF-8?q?Days`=20and=20`streaks`=20metrics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 4 +++- src/data/changelog.json | 5 +++++ src/lib/util.ts | 5 +++++ src/services/GithubApi.ts | 33 ++++++++++++++++++++++++++++++++- src/widgets/MembersPane.tsx | 33 +++++++++++++++++++++++---------- 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index d5d4f26..4cdd93a 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -371,9 +371,11 @@ const StudyGroup: React.FC = (props) => { }, recordCount: m.RecordCount, daysJoined: m.DaysJoined, - latestCardNo: m.Record[m.StreakCurrent.EndDate] + latestCardNo: m.Record[m.StreakCurrent.EndDate], + record: new Map(Object.entries(m.Record)) }) }) + // console.log('\t>> member[0].record', members[0].record) setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) console.log('>> member stats update received:', (new Date()).toISOString()) }) diff --git a/src/data/changelog.json b/src/data/changelog.json index 91200d2..b6ee121 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.15", + "message": "✨ Revamp `MembersPane` to better visually show `Missed Days` and `streaks` metrics", + "built": "Thu, 15 Jul 2021 22:15:45 EDT" + }, { "version": "1.8.14", "message": "🐞 Fix error that was being thrown if comment was +/- to a card not currently in-view", diff --git a/src/lib/util.ts b/src/lib/util.ts index 320affb..c963177 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -105,3 +105,8 @@ export function getDateRange (endDate: Date): TDay[] { } return dateRange } + +// Returns "YYYY-MM-DD" => Eg. "2021-07-15" +export function getYearMonthDay (d: Date): string { + return `${d.getFullYear()}-` + `${d.getMonth() + 1}`.padStart(2, '0') + '-' + `${d.getDate()}`.padStart(2, '0') +} diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index d3dd2e8..e5758c0 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -23,7 +23,38 @@ export type StudyMember = { streakMax: Streak, recordCount: number, daysJoined: number, - latestCardNo: number + latestCardNo: number, + record: Map +} + +// const dayCodes = ['U', 'M', 'T', 'W', 'H', 'F', 'S'] + +// Render a member's record for the past 12 weeks * 7 days = 84 times +export function RenderRecord (record: Map, startDate: string): string { + const dateCursor = new Date() + let s = '' + for (let i = 0; i < 7 * 12; i++) { + // console.log('\t>> check key:', util.getYearMonthDay(dateCursor)) + if (dateCursor.getDay() === 6) { + s = '|' + s + } + if (record.has(util.getYearMonthDay(dateCursor))) { + s = '*' + s + // s = dayCodes[dateCursor.getDay()] + s + } else { + if (i === 0) { // It is today + s = '_' + s + } else { + s = '❌' + s // a 'missed' day + } + } + dateCursor.setTime(dateCursor.getTime() - 86400 * 1000) // 86400 seconds in 24 hours + + if (dateCursor.getTime() < Date.parse(startDate)) { + break + } + } + return s } const members = [ diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx index 7f5296e..ce2936c 100644 --- a/src/widgets/MembersPane.tsx +++ b/src/widgets/MembersPane.tsx @@ -1,5 +1,18 @@ import React from 'react' -import { StudyMember, Streak } from '../services/GithubApi' +import { StudyMember, Streak, RenderRecord } from '../services/GithubApi' +import styled from 'styled-components' + +const FColor = styled.span` + color: orange; +` + +const FGreen = styled.span` + color: #5ff708; +` + +const FOrange = styled.span` + color: #ec7240; +` const FStreak: React.FC = (streak) => { return ( @@ -27,22 +40,22 @@ const MembersPane: React.FC = (props) => {
🧙‍♂️ Member #{i}: {handle} | - Start: {(new Date(member.startDateStr)).toDateString()} | - Streak Max: | - Total Days: {member.recordCount}/{member.daysJoined} + Start: {(new Date(member.startDateStr)).toDateString()} | + Max Streak: | + Record: {member.recordCount}/{member.daysJoined} | + Current Streak: days | + Latest Card: #{member.latestCardNo} ({member.streakCurrent.endDate})
- Streak Current: days | - Latest Submission: { member.streakCurrent.endDate !== '' - ? `#${member.latestCardNo} (${member.streakCurrent.endDate})` - : 'N/A'} + {RenderRecord(member.record, member.startDateStr)}
if (member.active) { rs.push(content) - } else { - rs.push({content}) } + // else { + // rs.push({content}) + // } return (rs) }) } From 4233441a99ec7a473cf8db930fcdfed6e395c9aa Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Sun, 18 Jul 2021 14:39:16 -0400 Subject: [PATCH 17/30] =?UTF-8?q?=F0=9F=94=96=201.8.16:=20=F0=9F=92=84?= =?UTF-8?q?=F0=9F=90=9E=20Tweak=20`week=20demarcation`=20logic=20in=20`Mem?= =?UTF-8?q?bersPane`=20&=20fix=20`target=3D'=5Ftop'`=20bug=20in=20links?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 2 +- src/data/changelog.json | 5 +++++ src/services/GithubApi.ts | 12 +++++------- src/widgets/MembersPane.tsx | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 4cdd93a..26474b7 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -138,7 +138,7 @@ const MemberCard: React.FC = (props) => { }} /> ) diff --git a/src/data/changelog.json b/src/data/changelog.json index b6ee121..823487a 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.16", + "message": "💄🐞 Tweak `week demarcation` logic in `MembersPane` \u0026 fix `target='_top'` bug in links", + "built": "Sun, 18 Jul 2021 14:39:16 EDT" + }, { "version": "1.8.15", "message": "✨ Revamp `MembersPane` to better visually show `Missed Days` and `streaks` metrics", diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index e5758c0..d439f1b 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -34,18 +34,16 @@ export function RenderRecord (record: Map, startDate: string): s const dateCursor = new Date() let s = '' for (let i = 0; i < 7 * 12; i++) { - // console.log('\t>> check key:', util.getYearMonthDay(dateCursor)) - if (dateCursor.getDay() === 6) { - s = '|' + s - } + // Demarcate weeks on "Saturday | Sunday" + const weekBar = dateCursor.getDay() === 0 ? '|' : '' // Is it Sunday? If so, prefix with '|' to start a new week if (record.has(util.getYearMonthDay(dateCursor))) { - s = '*' + s + s = weekBar + '*' + s // s = dayCodes[dateCursor.getDay()] + s } else { if (i === 0) { // It is today - s = '_' + s + s = weekBar + '_' + s } else { - s = '❌' + s // a 'missed' day + s = weekBar + '❌' + s // a 'missed' day } } dateCursor.setTime(dateCursor.getTime() - 86400 * 1000) // 86400 seconds in 24 hours diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx index ce2936c..8fb9d24 100644 --- a/src/widgets/MembersPane.tsx +++ b/src/widgets/MembersPane.tsx @@ -39,7 +39,7 @@ const MembersPane: React.FC = (props) => {
🧙‍♂️ - Member #{i}: {handle} | + Member #{i}: {handle} | Start: {(new Date(member.startDateStr)).toDateString()} | Max Streak: | Record: {member.recordCount}/{member.daysJoined} | From 7a42d953715513170000e91726dacb6e14204750 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Sun, 18 Jul 2021 18:03:54 -0400 Subject: [PATCH 18/30] =?UTF-8?q?=F0=9F=94=96=201.8.17:=20=F0=9F=A7=99?= =?UTF-8?q?=E2=80=8D=E2=99=82=EF=B8=8F=20Add=20Jassa=20to=20the=20study=20?= =?UTF-8?q?group!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 4 ++-- src/data/changelog.json | 5 +++++ src/services/GithubApi.ts | 10 +++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 26474b7..a8da553 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -129,7 +129,7 @@ type TMemberCard = { } const MemberCard: React.FC = (props) => { return ( - +
) } - if (day.dayNo === 0 && Date.parse(day.dateStr) > Date.parse(m.startDateStr)) { + if (day.dayNo === 0 && Date.parse(day.dateStr) >= Date.parse(m.startDateStr)) { rs.push( ) diff --git a/src/data/changelog.json b/src/data/changelog.json index 823487a..c6b60e9 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.17", + "message": "🧙‍♂️ Add Jassa to the study group!", + "built": "Sun, 18 Jul 2021 18:03:54 EDT" + }, { "version": "1.8.16", "message": "💄🐞 Tweak `week demarcation` logic in `MembersPane` \u0026 fix `target='_top'` bug in links", diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index d439f1b..aeccb16 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -35,7 +35,7 @@ export function RenderRecord (record: Map, startDate: string): s let s = '' for (let i = 0; i < 7 * 12; i++) { // Demarcate weeks on "Saturday | Sunday" - const weekBar = dateCursor.getDay() === 0 ? '|' : '' // Is it Sunday? If so, prefix with '|' to start a new week + const weekBar = i !== 0 && dateCursor.getDay() === 0 ? '|' : '' // Is it Sunday? If so, prefix with '|' to start a new week if (record.has(util.getYearMonthDay(dateCursor))) { s = weekBar + '*' + s // s = dayCodes[dateCursor.getDay()] + s @@ -87,6 +87,14 @@ const members = [ uid: '85973779', repo: 'https://github.com/studydash/cards', active: true + }, + { + userFullname: 'Jassa Deen', + userHandle: 'JazDee', + startDateStr: '2021-07-18T04:00:00Z', + uid: '87615293', + repo: 'https://github.com/studydash/cards', + active: true } ] From 25400a65fdbd5346d422bdef08632f130c514e74 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 20 Jul 2021 01:16:00 -0400 Subject: [PATCH 19/30] =?UTF-8?q?=F0=9F=94=96=201.8.18:=20=E2=99=BB=20Refa?= =?UTF-8?q?ctor=20`dashboard`=20to=20fetch=20`studyMembers`=20from=20Fires?= =?UTF-8?q?tore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/changelog.json | 5 ++++ src/models/MStudyMember.ts | 14 ++++++++++ src/services/FirestoreApi.ts | 21 +++++++++++++++ src/services/GithubApi.ts | 50 ++++-------------------------------- 4 files changed, 45 insertions(+), 45 deletions(-) create mode 100644 src/models/MStudyMember.ts diff --git a/src/data/changelog.json b/src/data/changelog.json index c6b60e9..02b2969 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.18", + "message": "♻ Refactor `dashboard` to fetch `studyMembers` from Firestore", + "built": "Tue, 20 Jul 2021 01:16:00 EDT" + }, { "version": "1.8.17", "message": "🧙‍♂️ Add Jassa to the study group!", diff --git a/src/models/MStudyMember.ts b/src/models/MStudyMember.ts new file mode 100644 index 0000000..8063433 --- /dev/null +++ b/src/models/MStudyMember.ts @@ -0,0 +1,14 @@ +/** + * An abbreviated model of StudyMember. + * Only contains the core fields. + */ +type MStudyMember = { + userFullname: string + userHandle: string + startDateStr: string + uid: string + repo: string + active: boolean +} + +export default MStudyMember diff --git a/src/services/FirestoreApi.ts b/src/services/FirestoreApi.ts index 224524a..4a9af5d 100644 --- a/src/services/FirestoreApi.ts +++ b/src/services/FirestoreApi.ts @@ -2,6 +2,27 @@ import firebase from 'firebase/app' import { ILog, TPassage, TVote } from '../widgets/Shared' import { AutoId } from '../lib/util' import MMenuItem from '../models/MMenuItem' +import MStudyMember from '../models/MStudyMember' + +/** + * @param void + * @returns a promise of studyMembers[] + */ +export async function getStudyMembers (): Promise> { + const qs = await firebase.firestore().collection('studyMembers').get() + const studyMembers = qs.docs.map((doc: any) => { + const o = doc.data() + return { + userFullname: o.Fullname, + userHandle: o.Handle, + startDateStr: o.StartDate, + uid: o.Uid, + repo: o.Repo, + active: o.Active + } + }) + return studyMembers +} /** * Queries firestore to get menu items. diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index aeccb16..4b617a3 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -1,5 +1,6 @@ import { UserProgressDb, Tag } from '../models/UserProgress' import * as util from '../lib/util' +import { getStudyMembers } from './FirestoreApi' export const uriAllCards = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100' // const uriAllCards0 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=r002' @@ -35,7 +36,7 @@ export function RenderRecord (record: Map, startDate: string): s let s = '' for (let i = 0; i < 7 * 12; i++) { // Demarcate weeks on "Saturday | Sunday" - const weekBar = i !== 0 && dateCursor.getDay() === 0 ? '|' : '' // Is it Sunday? If so, prefix with '|' to start a new week + const weekBar = dateCursor.getDay() === 0 ? '|' : '' // Is it Sunday? If so, prefix with '|' to start a new week if (record.has(util.getYearMonthDay(dateCursor))) { s = weekBar + '*' + s // s = dayCodes[dateCursor.getDay()] + s @@ -52,52 +53,9 @@ export function RenderRecord (record: Map, startDate: string): s break } } - return s + return s.replace(/^\|/g, '') // Trim any leading '|' from final output } -const members = [ - { - userFullname: 'Robert Lin', - userHandle: 'r002', - startDateStr: '2021-05-03T04:00:00Z', - uid: '45280066', - repo: 'https://github.com/studydash/cards', - active: true - }, - { - userFullname: 'Anita Beauchamp', - userHandle: 'anitabe404', - startDateStr: '2021-05-04T04:00:00Z', - uid: '9167395', - repo: 'https://github.com/studydash/cards', - active: true - }, - { - userFullname: 'Matthew Curcio', - userHandle: 'mccurcio', - startDateStr: '2021-05-10T04:00:00Z', - uid: '1915749', - repo: 'https://github.com/studydash/cards', - active: false - }, - { - userFullname: 'Shaza Huang', - userHandle: 'shazahuang', - startDateStr: '2021-06-18T04:00:00Z', - uid: '85973779', - repo: 'https://github.com/studydash/cards', - active: true - }, - { - userFullname: 'Jassa Deen', - userHandle: 'JazDee', - startDateStr: '2021-07-18T04:00:00Z', - uid: '87615293', - repo: 'https://github.com/studydash/cards', - active: true - } -] - export const tagMap = new Map() tagMap.set('movie trailer', { name: 'movie trailer', @@ -142,6 +100,8 @@ tagMap.set('podcast notes', { export async function getUpDb (d: Date): Promise { const upDb = new UserProgressDb() + const members = await getStudyMembers() + for (const member of members) { upDb.addUser(member) } From 9d7e64e3c0851df9599f110ae1643b928af74a5d Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 20 Jul 2021 22:44:32 -0400 Subject: [PATCH 20/30] =?UTF-8?q?=F0=9F=94=96=201.8.19:=20=E2=99=BB=20Refa?= =?UTF-8?q?ctor=20models=20+=20`LastCard`=20fields=20in=20`StudyMember`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyGroup.tsx | 8 ++++++-- src/data/changelog.json | 5 +++++ src/models/StudyMember.ts | 25 +++++++++++++++++++++++++ src/services/GithubApi.ts | 21 --------------------- src/widgets/MembersPane.tsx | 5 +++-- 5 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 src/models/StudyMember.ts diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index a8da553..2fb7c97 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -2,13 +2,14 @@ import ReactDOM from 'react-dom' import React, { useState, useEffect } from 'react' import styled, { css } from 'styled-components' import { UserProgressDb, Tag } from './models/UserProgress' +import { StudyMember } from './models/StudyMember' import CountdownClock from './widgets/CountdownClock' import MembersPane from './widgets/MembersPane' import * as util from './lib/util' import changelogUri from './data/changelog.json' import './providers/AuthContext' import firebase from 'firebase/app' -import { getUpDb, tagMap, uriAllCards, StudyMember } from './services/GithubApi' +import { getUpDb, tagMap, uriAllCards } from './services/GithubApi' // Display cards for a specific date if passed in; else, display the current month's cards const m = window.location.href.match(/^.*d=(\d{4}-\d{2})$/) // d is expected to be YYYY-MM; eg. "2021-06" @@ -371,7 +372,10 @@ const StudyGroup: React.FC = (props) => { }, recordCount: m.RecordCount, daysJoined: m.DaysJoined, - latestCardNo: m.Record[m.StreakCurrent.EndDate], + lastCard: { + date: m.LastCard.Date, + number: m.LastCard.Number + }, record: new Map(Object.entries(m.Record)) }) }) diff --git a/src/data/changelog.json b/src/data/changelog.json index 02b2969..9f30e04 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.8.19", + "message": "♻ Refactor models + `LastCard` fields in `StudyMember`", + "built": "Tue, 20 Jul 2021 22:44:32 EDT" + }, { "version": "1.8.18", "message": "♻ Refactor `dashboard` to fetch `studyMembers` from Firestore", diff --git a/src/models/StudyMember.ts b/src/models/StudyMember.ts new file mode 100644 index 0000000..2252b27 --- /dev/null +++ b/src/models/StudyMember.ts @@ -0,0 +1,25 @@ +export type Streak = { + days: number, + startDate: string, + endDate: string +} + +export type Card = { + date: string, + number: number +} + +export type StudyMember = { + userFullname: string + userHandle: string + startDateStr: string + uid: string + repo: string + active: boolean, + streakCurrent: Streak, + streakMax: Streak, + recordCount: number, + daysJoined: number, + lastCard: Card, + record: Map +} diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index 4b617a3..6e74586 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -7,27 +7,6 @@ export const uriAllCards = 'https://api.github.com/repos/studydash/cards/issues? // const uriAllCards1 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=anitabe404' // const uriAllCards2 = 'https://api.github.com/repos/studydash/cards/issues?milestone=1&sort=created&direction=desc&per_page=100&creator=shazahuang' -export type Streak = { - days: number, - startDate: string, - endDate: string -} - -export type StudyMember = { - userFullname: string - userHandle: string - startDateStr: string - uid: string - repo: string - active: boolean, - streakCurrent: Streak, - streakMax: Streak, - recordCount: number, - daysJoined: number, - latestCardNo: number, - record: Map -} - // const dayCodes = ['U', 'M', 'T', 'W', 'H', 'F', 'S'] // Render a member's record for the past 12 weeks * 7 days = 84 times diff --git a/src/widgets/MembersPane.tsx b/src/widgets/MembersPane.tsx index 8fb9d24..a0c7233 100644 --- a/src/widgets/MembersPane.tsx +++ b/src/widgets/MembersPane.tsx @@ -1,5 +1,6 @@ import React from 'react' -import { StudyMember, Streak, RenderRecord } from '../services/GithubApi' +import { StudyMember, Streak } from '../models/StudyMember' +import { RenderRecord } from '../services/GithubApi' import styled from 'styled-components' const FColor = styled.span` @@ -44,7 +45,7 @@ const MembersPane: React.FC = (props) => { Max Streak: | Record: {member.recordCount}/{member.daysJoined} | Current Streak: days | - Latest Card: #{member.latestCardNo} ({member.streakCurrent.endDate}) + Latest Card: #{member.lastCard.number} ({member.lastCard.date})
{RenderRecord(member.record, member.startDateStr)} From 055d48d6a2b992fd3493648f260c294dac0a3fec Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 29 Jul 2021 20:46:42 -0400 Subject: [PATCH 21/30] =?UTF-8?q?=F0=9F=94=96=201.9.0:=20=F0=9F=8D=91=20Be?= =?UTF-8?q?gin=20`sprint-jambul`=20(Thu=20-=207/29/21)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 2 +- src/data/changelog.json | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index d423cfd..5277481 100644 --- a/public/index.html +++ b/public/index.html @@ -2,7 +2,7 @@ - Sprint Imbe 🥭 (Sun - 6/20/21) + Sprint Jambul 🍑 (Thursday - 7/29/21) diff --git a/src/data/changelog.json b/src/data/changelog.json index 9f30e04..8760225 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.0", + "message": "🍑 Begin `sprint-jambul` (Thu - 7/29/21)", + "built": "Thu, 29 Jul 2021 20:46:42 EDT" + }, { "version": "1.8.19", "message": "♻ Refactor models + `LastCard` fields in `StudyMember`", From af34a289c9ce486a0790a8852b519cd94f5eaa79 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Fri, 30 Jul 2021 02:12:08 -0400 Subject: [PATCH 22/30] =?UTF-8?q?=F0=9F=94=96=201.9.1:=20=E2=9C=A8=20Start?= =?UTF-8?q?=20`dashboard`=20GUI=20redesign=20that=20is=20beautified=20with?= =?UTF-8?q?=20CSS=20art?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/study-group.html | 56 +----------- public/studydash.html | 156 ++++++++++++++++++++++++++++++++ src/StudyDash.tsx | 138 ++++++++++++++++++++++++++++ src/StudyGroup.tsx | 25 ++--- src/assets/css/board.css | 27 ++++++ src/assets/css/design01.css | 15 +++ src/assets/css/landscape.css | 106 ++++++++++++++++++++++ src/assets/css/links+glyphs.css | 33 +++++++ src/data/changelog.json | 5 + src/widgets/Layout.tsx | 11 +++ webpack.common.js | 8 +- 11 files changed, 507 insertions(+), 73 deletions(-) create mode 100644 public/studydash.html create mode 100644 src/StudyDash.tsx create mode 100644 src/assets/css/board.css create mode 100644 src/assets/css/design01.css create mode 100644 src/assets/css/landscape.css create mode 100644 src/assets/css/links+glyphs.css create mode 100644 src/widgets/Layout.tsx diff --git a/public/study-group.html b/public/study-group.html index 7e7eb8b..63c0b4b 100644 --- a/public/study-group.html +++ b/public/study-group.html @@ -1,60 +1,10 @@ - - + + + Study Group 00 -
diff --git a/public/studydash.html b/public/studydash.html new file mode 100644 index 0000000..721f436 --- /dev/null +++ b/public/studydash.html @@ -0,0 +1,156 @@ + + + + + + StudyDash - Jambul + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/src/StudyDash.tsx b/src/StudyDash.tsx new file mode 100644 index 0000000..775241a --- /dev/null +++ b/src/StudyDash.tsx @@ -0,0 +1,138 @@ +import './assets/css/landscape.css' +import './assets/css/board.css' +import './assets/css/links+glyphs.css' + +import ReactDOM from 'react-dom' +import React, { useState, useEffect } from 'react' +import styled from 'styled-components' +import './providers/AuthContext' +import firebase from 'firebase/app' +import { StudyMember } from './models/StudyMember' +import * as util from './lib/util' +import * as l from './widgets/Layout' + +const Board = styled.div` + position: absolute; + display: flex; + left: 43px; + top: 29px; +` + +// const Card = styled.div` +// width: 205px; +// height: 28px; +// ` + +const FMemberCard = styled.div` + width: 205px; + height: 28px; + background: #632242; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + + font-family: 'Chakra Petch', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 14px; + line-height: 29px; + color: #FFFFFF; + + margin-right: 11px; + padding: 1px; + padding-left: 7px; + box-sizing: border-box; +` + +type TMemberCard = { + name: string + userHandle: string + uid: string +} +const MemberCard: React.FC = (props) => { + return ( + + {props.userHandle} + + ) +} + +const MemberBoard: React.VFC = () => { + const [members, setMembers] = useState>([]) + const [curDate] = useState(new Date()) + + // Listen for latest member stats updates from Firestore + useEffect(() => { + const unsubscribe = firebase.firestore().collection('studyMembers') + .onSnapshot((querySnapshot) => { + const members = [] as Array + querySnapshot.forEach((doc) => { + const m = doc.data() + members.push({ + userFullname: m.Fullname, + userHandle: m.Handle, + startDateStr: m.StartDate, + uid: m.Uid, + repo: m.Repo, + active: m.Active, + streakCurrent: { + days: m.StreakCurrent.Days, + startDate: m.StreakCurrent.StartDate, + endDate: m.StreakCurrent.EndDate + }, + streakMax: { + days: m.StreakMax.Days, + startDate: m.StreakMax.StartDate, + endDate: m.StreakMax.EndDate + }, + recordCount: m.RecordCount, + daysJoined: m.DaysJoined, + lastCard: { + date: m.LastCard.Date, + number: m.LastCard.Number + }, + record: new Map(Object.entries(m.Record)) + }) + }) + // console.log('\t>> member[0].record', members[0].record) + setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) + console.log('>> member stats update received:', (new Date()).toISOString()) + }) + return () => unsubscribe() + }, []) + + // const dateRange = util.getDateRange(curDate) + return ( + + { + members.map((m: StudyMember, i: number) => + m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() + ? + + { + // dateRange.map((day: util.TDay, i: number) => <>{day} | {i}) + } + + : + ) + } + + ) +} + +ReactDOM.render( + + + , + document.querySelector('#root') +) + +// https://webpack.js.org/api/hot-module-replacement/ +if (module.hot) { + module.hot.accept( + // errorHandler // Function to handle errors when evaluating the new version + ) + + module.hot.dispose(() => { + console.clear() // Clear the console on every hot reload + // Clean up and pass data to the updated module... + }) +} diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 2fb7c97..c603460 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -1,3 +1,5 @@ +import './assets/css/design01.css' +import './assets/css/links+glyphs.css' import ReactDOM from 'react-dom' import React, { useState, useEffect } from 'react' import styled, { css } from 'styled-components' @@ -10,6 +12,7 @@ import changelogUri from './data/changelog.json' import './providers/AuthContext' import firebase from 'firebase/app' import { getUpDb, tagMap, uriAllCards } from './services/GithubApi' +import * as l from './widgets/Layout' // Display cards for a specific date if passed in; else, display the current month's cards const m = window.location.href.match(/^.*d=(\d{4}-\d{2})$/) // d is expected to be YYYY-MM; eg. "2021-06" @@ -40,16 +43,6 @@ Promise.all([fetchVersion, getUpDb(initialDate)]).then(responses => { }) }) -const FHorizontal = styled.div` - display: flex; - flex-direction: row; -` - -const FVertical = styled.div` - display: flex; - flex-direction: column; -` - type TFCard = { readonly empty? : boolean readonly missedDay? : boolean @@ -438,8 +431,8 @@ const StudyGroup: React.FC = (props) => {

- - + + .
. @@ -457,20 +450,20 @@ const StudyGroup: React.FC = (props) => {
) } - + { members.map((m: StudyMember, i: number) => m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() - ? + ? { dateRange.map((day: util.TDay, i: number) => renderCard(upDb, m, day, i)) } - + : ) } - + 🔖 {props.commit.version} | {props.commit.message}
👷‍♂️ {props.commit.built.toString()} diff --git a/src/assets/css/board.css b/src/assets/css/board.css new file mode 100644 index 0000000..1a43407 --- /dev/null +++ b/src/assets/css/board.css @@ -0,0 +1,27 @@ +.board { + position: absolute; + display: flex; + left: 43px; + top: 29px; +} + +.personBox { + width: 205px; + height: 28px; +} + +.personTitle { + background: #632242; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + + font-family: 'Chakra Petch', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 16px; + line-height: 29px; + color: #FFFFFF; + + padding: 2px; + padding-left: 7px; + box-sizing: border-box; +} \ No newline at end of file diff --git a/src/assets/css/design01.css b/src/assets/css/design01.css new file mode 100644 index 0000000..378a57d --- /dev/null +++ b/src/assets/css/design01.css @@ -0,0 +1,15 @@ +@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@500&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap'); + +* { + font-family: 'IBM Plex Mono', monospace; + font-size: 14px; + line-height: 21px; +} + +body { + background-color: #0d1117; + color: white; + margin: 0; + padding: 0; +} \ No newline at end of file diff --git a/src/assets/css/landscape.css b/src/assets/css/landscape.css new file mode 100644 index 0000000..2a5106f --- /dev/null +++ b/src/assets/css/landscape.css @@ -0,0 +1,106 @@ +@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch&display=swap'); + +:root { + --darkblue: #152c3e; + --lightblue: #37618a; + --greenprimary: #879759; + --greenshadow: #648459; +} + +* { + margin: 0; + padding: 0; + font-family: 'Chakra Petch', sans-serif; + font-style: normal; + font-weight: 400; + font-size: 16px; + line-height: 29px; + color: #FFFFFF; +} + +@media (max-width: 960px) { + body { zoom: 0.7; } +} + +html, body { height: 100%; } + +@keyframes bounce { + from { + transform: translateY(0px); + } to { + transform: translateY(-4px); + } +} + +@keyframes sway { + from { + transform: translateX(0px); + } to { + transform: translateX(-12px); + } +} + +body { + min-height: 100%; + background: -webkit-linear-gradient(top, var(--darkblue), var(--lightblue)); + position: relative; + overflow-x: hidden; + overflow-y: hidden; +} + +#mountains { + z-index: 2; + position: absolute; + bottom: 20%; + margin-bottom: -16px; + left: 10%; +} + +#cloud1 { + z-index: 2; + position: absolute; + top: 20%; + right: 4%; + animation: bounce 2s ease-in-out 0s infinite alternate; +} + +#cloud2 { + z-index: 1; + position: absolute; + top: 22%; + right: 16%; + animation: bounce 3.5s ease-in-out 2s infinite alternate; +} + +.trees { + width: 100%; + height: 130px; + z-index: 4; + position: absolute; + bottom: 20%; + margin-bottom: -100px; +} + +#ground { + z-index: 1; + width: 100%; + height: 20%; + position: absolute; + bottom: 0; + background: var(--greenprimary); +} + +#hills { + /* background: rgba(255,0,0,0.3); */ + position: absolute; + left: 10%; + margin-left: -120px; + margin-bottom: -86px; + bottom: 20%; + z-index: 3; +} + +#stars { + width: 100%; + height: 100%; +} \ No newline at end of file diff --git a/src/assets/css/links+glyphs.css b/src/assets/css/links+glyphs.css new file mode 100644 index 0000000..6922714 --- /dev/null +++ b/src/assets/css/links+glyphs.css @@ -0,0 +1,33 @@ +a:link { + color: #2f87f8; + text-decoration: none; +} + +a:visited { + color: #2f87f8; + text-decoration: none; +} + +a:hover { + color: #2f87f8; + text-decoration: underline; +} + +a:active { + color: red; +} + +.octicon { + fill: #a5b5bb; + margin-top: 2px; + margin-bottom: -3px; + padding-right: 6px; + /* background: pink; */ +} + +.commentNo { + font-weight: 600; + font-size: 13px; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; + color: #a5b5bb; +} \ No newline at end of file diff --git a/src/data/changelog.json b/src/data/changelog.json index 8760225..95174e2 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.1", + "message": "✨ Start `dashboard` GUI redesign that is beautified with CSS art", + "built": "Fri, 30 Jul 2021 02:12:08 EDT" + }, { "version": "1.9.0", "message": "🍑 Begin `sprint-jambul` (Thu - 7/29/21)", diff --git a/src/widgets/Layout.tsx b/src/widgets/Layout.tsx new file mode 100644 index 0000000..69a5ae2 --- /dev/null +++ b/src/widgets/Layout.tsx @@ -0,0 +1,11 @@ +import styled from 'styled-components' + +export const FHorizontal = styled.div` + display: flex; + flex-direction: row; +` + +export const FVertical = styled.div` + display: flex; + flex-direction: column; +` diff --git a/webpack.common.js b/webpack.common.js index 03e7738..3e17102 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -5,7 +5,7 @@ module.exports = { entry: { app: './src/index.tsx', wattpad: './src/wattpad.tsx', - StudyGroup: './src/StudyGroup.tsx' + StudyDash: './src/StudyDash.tsx' }, plugins: [ new HtmlWebpackPlugin({ @@ -23,11 +23,11 @@ module.exports = { chunks: ['wattpad'] }), new HtmlWebpackPlugin({ - title: 'Study Group 00', + title: 'StudyDash', filename: './studydash/index.html', - template: './public/study-group.html', + template: './public/studydash.html', favicon: './public/favicon.ico', - chunks: ['StudyGroup'] + chunks: ['StudyDash'] }), new HtmlWebpackPlugin({ title: 'Preview', From ccb0d0f71965476a85fd3af43df335ace798c5bc Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Sat, 31 Jul 2021 22:56:13 -0400 Subject: [PATCH 23/30] =?UTF-8?q?=F0=9F=94=96=201.9.2:=20=E2=9C=A8=20Displ?= =?UTF-8?q?ay=20past=20seven=20days=20worth=20of=20cards=20in=20GUI=20v2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyDash.tsx | 144 +++++++++++++++++++++++++++++++++++----- src/StudyGroup.tsx | 4 +- src/data/changelog.json | 5 ++ src/lib/util.ts | 32 ++++++++- webpack.common.js | 8 +++ 5 files changed, 174 insertions(+), 19 deletions(-) diff --git a/src/StudyDash.tsx b/src/StudyDash.tsx index 775241a..d81e670 100644 --- a/src/StudyDash.tsx +++ b/src/StudyDash.tsx @@ -8,6 +8,8 @@ import styled from 'styled-components' import './providers/AuthContext' import firebase from 'firebase/app' import { StudyMember } from './models/StudyMember' +import { UserProgressDb, Tag } from './models/UserProgress' +import { getUpDb } from './services/GithubApi' import * as util from './lib/util' import * as l from './widgets/Layout' @@ -18,30 +20,72 @@ const Board = styled.div` top: 29px; ` -// const Card = styled.div` -// width: 205px; -// height: 28px; -// ` - -const FMemberCard = styled.div` +const FCard = styled.div` width: 205px; height: 28px; - background: #632242; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); font-family: 'Chakra Petch', sans-serif; font-style: normal; font-weight: 400; - font-size: 14px; line-height: 29px; color: #FFFFFF; - margin-right: 11px; + margin-bottom: 11px; + box-sizing: border-box; +` + +const FMemberCard = styled.div` + background: #632242; + font-size: 15px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + padding-top: 2px; + padding-left: 7px; +` + +const FEntryCard = styled.div` + background: #274867; + font-size: 12px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + padding: 1px; + padding-left: 7px; +` + +const FMissedCard = styled.div` + background: #632242; + font-size: 12px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); padding: 1px; padding-left: 7px; - box-sizing: border-box; ` +const FPendingCard = styled.div` + background: #597252; + font-size: 12px; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + padding: 1px; + padding-left: 7px; +` + +const MissedCard: React.VFC = () => { + return ( + + + No card today! 😢😦🙁 + + + ) +} + +const PendingCard: React.VFC = () => { + return ( + + + Today's card pending! 😀😁😄 + + + ) +} + type TMemberCard = { name: string userHandle: string @@ -49,15 +93,48 @@ type TMemberCard = { } const MemberCard: React.FC = (props) => { return ( - - {props.userHandle} - + + + {props.userHandle} + + + ) +} + +type TEntryCard = { + title: string + userHandle: string + number: number + created: Date + updated: Date + tags: Tag[] + comments: number + repo: string +} + +const EntryCard: React.FC = (props) => { + const title = props.title.length > 33 ? props.title.substr(0, 30) + '...' : props.title + return ( + + + {title} + + ) } const MemberBoard: React.VFC = () => { const [members, setMembers] = useState>([]) const [curDate] = useState(new Date()) + const [upDb, setUpDb] = useState(new UserProgressDb()) + + // Load cards + useEffect(() => { + console.log('>> Changing date periods', curDate) + Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) + history.pushState({}, '', '/studydash/?d=' + util.getYearMonth(curDate)) + window.parent.postMessage(window.location.href, '*') + }, [curDate]) // Listen for latest member stats updates from Firestore useEffect(() => { @@ -99,7 +176,8 @@ const MemberBoard: React.VFC = () => { return () => unsubscribe() }, []) - // const dateRange = util.getDateRange(curDate) + const dateRange = util.getDateRangeOneWeek(curDate) + // console.log('>> dateRange', dateRange) return ( { @@ -108,7 +186,7 @@ const MemberBoard: React.VFC = () => { ? { - // dateRange.map((day: util.TDay, i: number) => <>{day} | {i}) + dateRange.map((day: util.TDay, i: number) => renderCard(upDb, m, day, i)) } : @@ -118,6 +196,40 @@ const MemberBoard: React.VFC = () => { ) } +function renderCard (upDb:UserProgressDb, m:StudyMember, day: util.TDay, i: number) { + // TODO: Move this mock data into a unit test + // const card = { + // title: 'test card', + // userHandle: 'r002', + // number: 123, + // created: new Date(), + // updated: new Date(), + // comments: 0, + // repo: 'https://github.com' + // } as TEntryCard + const today = new Date() + const rs = [] + const card = upDb.getUser(m.userHandle)?.getCardByDate(day.dateStr) ?? null + if (card) { + rs.push() + } else if (today.toLocaleDateString() === day.dateStr) { + rs.push() + } else if (Date.parse(day.dateStr) >= Date.parse(m.startDateStr)) { + rs.push() + } else { + console.log('>> render empty card!') + // rs.push() // No longer needed? 7/31/21 + } + + return ( +
+ {rs} +
+ ) +} + +/// ////////////////////////////////////////////////////////////////////////////////////// ReactDOM.render( diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index c603460..73306c7 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -268,7 +268,7 @@ const StudyGroup: React.FC = (props) => { console.log('>> Changing date periods', curDate) Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) } - history.pushState({}, '', '/studydash/?d=' + curDate.toISOString().slice(0, 7)) + history.pushState({}, '', '/studygroup/?d=' + util.getYearMonth(curDate)) window.parent.postMessage(window.location.href, '*') }, [curDate]) @@ -398,7 +398,7 @@ const StudyGroup: React.FC = (props) => { } const startDate = new Date('2021-05-03T04:00:00Z') - const dateRange = util.getDateRange(curDate) + const dateRange = util.getDateRangeOneMonth(curDate) return ( diff --git a/src/data/changelog.json b/src/data/changelog.json index 95174e2..8db2f8c 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.2", + "message": "✨ Display past seven days worth of cards in GUI v2", + "built": "Sat, 31 Jul 2021 22:56:13 EDT" + }, { "version": "1.9.1", "message": "✨ Start `dashboard` GUI redesign that is beautified with CSS art", diff --git a/src/lib/util.ts b/src/lib/util.ts index c963177..67bfb2b 100644 --- a/src/lib/util.ts +++ b/src/lib/util.ts @@ -50,6 +50,7 @@ export class AutoId { } } +// Eg. "August 2021" export function printMonthYear (d: Date): string { const options = { year: 'numeric', @@ -84,7 +85,31 @@ export type TDay = { dateStr: string } -export function getDateRange (endDate: Date): TDay[] { +// Return past seven days, ending on endDate +export function getDateRangeOneWeek (endDate: Date): TDay[] { + const dateRange = [] as TDay[] + const startDate = new Date() + startDate.setTime(endDate.getTime() - 86400 * 1000 * 7) // Seven days + + const today = new Date() + let dateCursor: Date + if (today.getMonth() === endDate.getMonth()) { + dateCursor = new Date(endDate.getFullYear(), endDate.getMonth(), today.getDate()) // Start on today + } else { + dateCursor = new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0) // Start on the last day of the month + } + + while (dateCursor.getTime() >= startDate.getTime()) { + dateRange.push({ + dayNo: dateCursor.getDay(), + dateStr: dateCursor.toLocaleDateString() + }) + dateCursor.setTime(dateCursor.getTime() - 86400 * 1000) // Step one day backwards until we get to the start date + } + return dateRange +} + +export function getDateRangeOneMonth (endDate: Date): TDay[] { const today = new Date() let dateCursor: Date if (today.getMonth() === endDate.getMonth()) { @@ -110,3 +135,8 @@ export function getDateRange (endDate: Date): TDay[] { export function getYearMonthDay (d: Date): string { return `${d.getFullYear()}-` + `${d.getMonth() + 1}`.padStart(2, '0') + '-' + `${d.getDate()}`.padStart(2, '0') } + +// Returns "YYYY-MM" => Eg. "2021-07" +export function getYearMonth (d: Date): string { + return `${d.getFullYear()}-` + `${d.getMonth() + 1}`.padStart(2, '0') +} diff --git a/webpack.common.js b/webpack.common.js index 3e17102..479e22c 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -5,6 +5,7 @@ module.exports = { entry: { app: './src/index.tsx', wattpad: './src/wattpad.tsx', + StudyGroup: './src/StudyGroup.tsx', StudyDash: './src/StudyDash.tsx' }, plugins: [ @@ -22,6 +23,13 @@ module.exports = { favicon: './public/favicon.ico', chunks: ['wattpad'] }), + new HtmlWebpackPlugin({ + title: 'StudyGroup', + filename: './studygroup/index.html', + template: './public/study-group.html', + favicon: './public/favicon.ico', + chunks: ['StudyGroup'] + }), new HtmlWebpackPlugin({ title: 'StudyDash', filename: './studydash/index.html', From 05f91db62f52e6830eff84703f6401c14b82731c Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 3 Aug 2021 23:26:39 -0400 Subject: [PATCH 24/30] =?UTF-8?q?=F0=9F=94=96=201.9.3:=20=E2=99=BB=20Refac?= =?UTF-8?q?tor=20`card`=20styled=20components=20to=20inherit=20from=20base?= =?UTF-8?q?=20class?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyDash.tsx | 111 +++++++++++++++++++++-------------- src/assets/css/landscape.css | 2 +- src/data/changelog.json | 5 ++ src/services/GithubApi.ts | 10 +++- 4 files changed, 83 insertions(+), 45 deletions(-) diff --git a/src/StudyDash.tsx b/src/StudyDash.tsx index d81e670..8073d80 100644 --- a/src/StudyDash.tsx +++ b/src/StudyDash.tsx @@ -20,69 +20,92 @@ const Board = styled.div` top: 29px; ` +// const FLine = styled.div` +// width: 100%; +// border: 0; +// background-color: #30363d; +// height: 3px; +// margin-top: 8px; +// margin-bottom: 4px; +// ` + const FCard = styled.div` width: 205px; height: 28px; + display: flex; + align-items: center; + font-family: 'Chakra Petch', sans-serif; font-style: normal; font-weight: 400; - line-height: 29px; + /* line-height: 29px; */ color: #FFFFFF; margin-right: 11px; margin-bottom: 11px; box-sizing: border-box; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); ` -const FMemberCard = styled.div` +const FEmpty = styled(FCard)` + width: 34px; + height: 28px; + background: none; + box-shadow: none; +` + +const FDay = styled(FCard)` + width: 34px; + height: 28px; + justify-content: center; + + font-family: 'Chakra Petch', sans-serif; + font-style: normal; + font-weight: 300; + line-height: 11.7px; + color: #FFFFFF; + + font-size: 9px; + background: #632242; +` + +const FMemberCard = styled(FCard)` background: #632242; font-size: 15px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); - padding-top: 2px; padding-left: 7px; ` -const FEntryCard = styled.div` +const FEntryCard = styled(FCard)` background: #274867; font-size: 12px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); - padding: 1px; padding-left: 7px; ` -const FMissedCard = styled.div` +const FMissedCard = styled(FCard)` background: #632242; font-size: 12px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); - padding: 1px; padding-left: 7px; ` -const FPendingCard = styled.div` +const FPendingCard = styled(FCard)` background: #597252; font-size: 12px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); - padding: 1px; padding-left: 7px; ` const MissedCard: React.VFC = () => { return ( - - - No card today! 😢😦🙁 - - + + No card today! 😢😦🙁 + ) } const PendingCard: React.VFC = () => { return ( - - - Today's card pending! 😀😁😄 - - + + Today's card pending! 😀😁😄 + ) } @@ -93,11 +116,9 @@ type TMemberCard = { } const MemberCard: React.FC = (props) => { return ( - - - {props.userHandle} - - + + {props.userHandle} + ) } @@ -115,14 +136,14 @@ type TEntryCard = { const EntryCard: React.FC = (props) => { const title = props.title.length > 33 ? props.title.substr(0, 30) + '...' : props.title return ( - - - {title} - - + + {title} + ) } +const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + const MemberBoard: React.VFC = () => { const [members, setMembers] = useState>([]) const [curDate] = useState(new Date()) @@ -180,6 +201,20 @@ const MemberBoard: React.VFC = () => { // console.log('>> dateRange', dateRange) return ( + + +
+
+ { + dateRange.map((day: util.TDay, i: number) => + + {days[day.dayNo].substring(0, 3)}
+ {day.dateStr.replace('/2021', '')} +
+ ) + } +
+ { members.map((m: StudyMember, i: number) => m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() @@ -197,16 +232,6 @@ const MemberBoard: React.VFC = () => { } function renderCard (upDb:UserProgressDb, m:StudyMember, day: util.TDay, i: number) { - // TODO: Move this mock data into a unit test - // const card = { - // title: 'test card', - // userHandle: 'r002', - // number: 123, - // created: new Date(), - // updated: new Date(), - // comments: 0, - // repo: 'https://github.com' - // } as TEntryCard const today = new Date() const rs = [] const card = upDb.getUser(m.userHandle)?.getCardByDate(day.dateStr) ?? null diff --git a/src/assets/css/landscape.css b/src/assets/css/landscape.css index 2a5106f..e4ec8ab 100644 --- a/src/assets/css/landscape.css +++ b/src/assets/css/landscape.css @@ -1,4 +1,4 @@ -@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch&display=swap'); +@import url('https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@300;400&display=swap'); :root { --darkblue: #152c3e; diff --git a/src/data/changelog.json b/src/data/changelog.json index 8db2f8c..47101f3 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.3", + "message": "♻ Refactor `card` styled components to inherit from base class", + "built": "Tue, 03 Aug 2021 23:26:39 EDT" + }, { "version": "1.9.2", "message": "✨ Display past seven days worth of cards in GUI v2", diff --git a/src/services/GithubApi.ts b/src/services/GithubApi.ts index 6e74586..2e8a4df 100644 --- a/src/services/GithubApi.ts +++ b/src/services/GithubApi.ts @@ -77,6 +77,7 @@ tagMap.set('podcast notes', { // console.log('>>rs', rs) // } +// eslint-disable-next-line export async function getUpDb (d: Date): Promise { const upDb = new UserProgressDb() const members = await getStudyMembers() @@ -85,8 +86,15 @@ export async function getUpDb (d: Date): Promise { upDb.addUser(member) } - const fetchCards = await fetch(uriAllCards + '&labels=' + util.getPeriod(d)) + // // If we are within the first week of a new month, also fetch cards from last month as well. + // const fetchCards0 = await fetch(uriAllCards + '&labels=' + util.getPeriod(util.getPrevMonth(d))) + // const fetchCards = await fetch(uriAllCards + '&labels=' + util.getPeriod(d)) + // const allCards0 = await fetchCards0.json() + // const allCards = await fetchCards.json() + + const fetchCards = await fetch(uriAllCards) const allCards = await fetchCards.json() + for (const item of allCards) { const tags = [] as Tag[] for (const label of item.labels) { From 6a3c8eaf9754e138e07f54576d8e209d50e93a1d Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Tue, 3 Aug 2021 23:42:12 -0400 Subject: [PATCH 25/30] =?UTF-8?q?=F0=9F=94=96=201.9.4:=20=E2=99=BB=20Refac?= =?UTF-8?q?tor=20`MemberBoard`=20into=20separate=20component?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/StudyDash.tsx | 257 +----------------------------------- src/data/changelog.json | 5 + src/widgets/Layout.tsx | 7 + src/widgets/MemberBoard.tsx | 234 ++++++++++++++++++++++++++++++++ 4 files changed, 250 insertions(+), 253 deletions(-) create mode 100644 src/widgets/MemberBoard.tsx diff --git a/src/StudyDash.tsx b/src/StudyDash.tsx index 8073d80..261d2f2 100644 --- a/src/StudyDash.tsx +++ b/src/StudyDash.tsx @@ -1,264 +1,15 @@ import './assets/css/landscape.css' import './assets/css/board.css' import './assets/css/links+glyphs.css' - -import ReactDOM from 'react-dom' -import React, { useState, useEffect } from 'react' -import styled from 'styled-components' -import './providers/AuthContext' -import firebase from 'firebase/app' -import { StudyMember } from './models/StudyMember' -import { UserProgressDb, Tag } from './models/UserProgress' -import { getUpDb } from './services/GithubApi' -import * as util from './lib/util' import * as l from './widgets/Layout' +import { MemberBoard } from './widgets/MemberBoard' -const Board = styled.div` - position: absolute; - display: flex; - left: 43px; - top: 29px; -` - -// const FLine = styled.div` -// width: 100%; -// border: 0; -// background-color: #30363d; -// height: 3px; -// margin-top: 8px; -// margin-bottom: 4px; -// ` - -const FCard = styled.div` - width: 205px; - height: 28px; - - display: flex; - align-items: center; - - font-family: 'Chakra Petch', sans-serif; - font-style: normal; - font-weight: 400; - /* line-height: 29px; */ - color: #FFFFFF; - margin-right: 11px; - margin-bottom: 11px; - box-sizing: border-box; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); -` - -const FEmpty = styled(FCard)` - width: 34px; - height: 28px; - background: none; - box-shadow: none; -` - -const FDay = styled(FCard)` - width: 34px; - height: 28px; - justify-content: center; - - font-family: 'Chakra Petch', sans-serif; - font-style: normal; - font-weight: 300; - line-height: 11.7px; - color: #FFFFFF; - - font-size: 9px; - background: #632242; -` - -const FMemberCard = styled(FCard)` - background: #632242; - font-size: 15px; - padding-left: 7px; -` - -const FEntryCard = styled(FCard)` - background: #274867; - font-size: 12px; - padding-left: 7px; -` - -const FMissedCard = styled(FCard)` - background: #632242; - font-size: 12px; - padding-left: 7px; -` - -const FPendingCard = styled(FCard)` - background: #597252; - font-size: 12px; - padding-left: 7px; -` - -const MissedCard: React.VFC = () => { - return ( - - No card today! 😢😦🙁 - - ) -} - -const PendingCard: React.VFC = () => { - return ( - - Today's card pending! 😀😁😄 - - ) -} - -type TMemberCard = { - name: string - userHandle: string - uid: string -} -const MemberCard: React.FC = (props) => { - return ( - - {props.userHandle} - - ) -} - -type TEntryCard = { - title: string - userHandle: string - number: number - created: Date - updated: Date - tags: Tag[] - comments: number - repo: string -} - -const EntryCard: React.FC = (props) => { - const title = props.title.length > 33 ? props.title.substr(0, 30) + '...' : props.title - return ( - - {title} - - ) -} - -const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] - -const MemberBoard: React.VFC = () => { - const [members, setMembers] = useState>([]) - const [curDate] = useState(new Date()) - const [upDb, setUpDb] = useState(new UserProgressDb()) - - // Load cards - useEffect(() => { - console.log('>> Changing date periods', curDate) - Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) - history.pushState({}, '', '/studydash/?d=' + util.getYearMonth(curDate)) - window.parent.postMessage(window.location.href, '*') - }, [curDate]) - - // Listen for latest member stats updates from Firestore - useEffect(() => { - const unsubscribe = firebase.firestore().collection('studyMembers') - .onSnapshot((querySnapshot) => { - const members = [] as Array - querySnapshot.forEach((doc) => { - const m = doc.data() - members.push({ - userFullname: m.Fullname, - userHandle: m.Handle, - startDateStr: m.StartDate, - uid: m.Uid, - repo: m.Repo, - active: m.Active, - streakCurrent: { - days: m.StreakCurrent.Days, - startDate: m.StreakCurrent.StartDate, - endDate: m.StreakCurrent.EndDate - }, - streakMax: { - days: m.StreakMax.Days, - startDate: m.StreakMax.StartDate, - endDate: m.StreakMax.EndDate - }, - recordCount: m.RecordCount, - daysJoined: m.DaysJoined, - lastCard: { - date: m.LastCard.Date, - number: m.LastCard.Number - }, - record: new Map(Object.entries(m.Record)) - }) - }) - // console.log('\t>> member[0].record', members[0].record) - setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) - console.log('>> member stats update received:', (new Date()).toISOString()) - }) - return () => unsubscribe() - }, []) - - const dateRange = util.getDateRangeOneWeek(curDate) - // console.log('>> dateRange', dateRange) - return ( - - - -
-
- { - dateRange.map((day: util.TDay, i: number) => - - {days[day.dayNo].substring(0, 3)}
- {day.dateStr.replace('/2021', '')} -
- ) - } -
- - { - members.map((m: StudyMember, i: number) => - m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() - ? - - { - dateRange.map((day: util.TDay, i: number) => renderCard(upDb, m, day, i)) - } - - : - ) - } -
- ) -} - -function renderCard (upDb:UserProgressDb, m:StudyMember, day: util.TDay, i: number) { - const today = new Date() - const rs = [] - const card = upDb.getUser(m.userHandle)?.getCardByDate(day.dateStr) ?? null - if (card) { - rs.push() - } else if (today.toLocaleDateString() === day.dateStr) { - rs.push() - } else if (Date.parse(day.dateStr) >= Date.parse(m.startDateStr)) { - rs.push() - } else { - console.log('>> render empty card!') - // rs.push() // No longer needed? 7/31/21 - } - - return ( -
- {rs} -
- ) -} +import ReactDOM from 'react-dom' -/// ////////////////////////////////////////////////////////////////////////////////////// ReactDOM.render( - + - , + , document.querySelector('#root') ) diff --git a/src/data/changelog.json b/src/data/changelog.json index 47101f3..b4bd744 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.4", + "message": "♻ Refactor `MemberBoard` into separate component", + "built": "Tue, 03 Aug 2021 23:42:11 EDT" + }, { "version": "1.9.3", "message": "♻ Refactor `card` styled components to inherit from base class", diff --git a/src/widgets/Layout.tsx b/src/widgets/Layout.tsx index 69a5ae2..be4c992 100644 --- a/src/widgets/Layout.tsx +++ b/src/widgets/Layout.tsx @@ -9,3 +9,10 @@ export const FVertical = styled.div` display: flex; flex-direction: column; ` + +export const Board = styled.div` + position: absolute; + display: flex; + left: 43px; + top: 29px; +` diff --git a/src/widgets/MemberBoard.tsx b/src/widgets/MemberBoard.tsx new file mode 100644 index 0000000..a486b8e --- /dev/null +++ b/src/widgets/MemberBoard.tsx @@ -0,0 +1,234 @@ +import React, { useState, useEffect } from 'react' +import styled from 'styled-components' +import '../providers/AuthContext' +import firebase from 'firebase/app' +import { StudyMember } from '../models/StudyMember' +import { UserProgressDb, Tag } from '../models/UserProgress' +import { getUpDb } from '../services/GithubApi' +import * as util from '../lib/util' +import * as l from '../widgets/Layout' + +const FCard = styled.div` + width: 205px; + height: 28px; + + display: flex; + align-items: center; + + font-family: 'Chakra Petch', sans-serif; + font-style: normal; + font-weight: 400; + /* line-height: 29px; */ + color: #FFFFFF; + margin-right: 11px; + margin-bottom: 11px; + box-sizing: border-box; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); +` + +const FEmpty = styled(FCard)` + width: 34px; + height: 28px; + background: none; + box-shadow: none; +` + +const FDay = styled(FCard)` + width: 34px; + height: 28px; + justify-content: center; + + font-family: 'Chakra Petch', sans-serif; + font-style: normal; + font-weight: 300; + line-height: 11.7px; + color: #FFFFFF; + + font-size: 9px; + background: #632242; +` + +const FMemberCard = styled(FCard)` + background: #632242; + font-size: 15px; + padding-left: 7px; +` + +const FEntryCard = styled(FCard)` + background: #274867; + font-size: 12px; + padding-left: 7px; +` + +const FMissedCard = styled(FCard)` + background: #632242; + font-size: 12px; + padding-left: 7px; +` + +const FPendingCard = styled(FCard)` + background: #597252; + font-size: 12px; + padding-left: 7px; +` + +const MissedCard: React.VFC = () => { + return ( + + No card today! 😢😦🙁 + + ) +} + +const PendingCard: React.VFC = () => { + return ( + + Today's card pending! 😀😁😄 + + ) +} + +type TMemberCard = { + name: string + userHandle: string + uid: string +} +const MemberCard: React.FC = (props) => { + return ( + + {props.userHandle} + + ) +} + +type TEntryCard = { + title: string + userHandle: string + number: number + created: Date + updated: Date + tags: Tag[] + comments: number + repo: string +} + +const EntryCard: React.FC = (props) => { + const title = props.title.length > 33 ? props.title.substr(0, 30) + '...' : props.title + return ( + + {title} + + ) +} + +const days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + +export const MemberBoard: React.VFC = () => { + const [members, setMembers] = useState>([]) + const [curDate] = useState(new Date()) + const [upDb, setUpDb] = useState(new UserProgressDb()) + + // Load cards + useEffect(() => { + console.log('>> Changing date periods', curDate) + Promise.resolve(getUpDb(curDate)).then(rs => setUpDb(rs)) + history.pushState({}, '', '/studydash/?d=' + util.getYearMonth(curDate)) + window.parent.postMessage(window.location.href, '*') + }, [curDate]) + + // Listen for latest member stats updates from Firestore + useEffect(() => { + const unsubscribe = firebase.firestore().collection('studyMembers') + .onSnapshot((querySnapshot) => { + const members = [] as Array + querySnapshot.forEach((doc) => { + const m = doc.data() + members.push({ + userFullname: m.Fullname, + userHandle: m.Handle, + startDateStr: m.StartDate, + uid: m.Uid, + repo: m.Repo, + active: m.Active, + streakCurrent: { + days: m.StreakCurrent.Days, + startDate: m.StreakCurrent.StartDate, + endDate: m.StreakCurrent.EndDate + }, + streakMax: { + days: m.StreakMax.Days, + startDate: m.StreakMax.StartDate, + endDate: m.StreakMax.EndDate + }, + recordCount: m.RecordCount, + daysJoined: m.DaysJoined, + lastCard: { + date: m.LastCard.Date, + number: m.LastCard.Number + }, + record: new Map(Object.entries(m.Record)) + }) + }) + // console.log('\t>> member[0].record', members[0].record) + setMembers(members.sort((a, b) => Date.parse(a.startDateStr) - Date.parse(b.startDateStr))) + console.log('>> member stats update received:', (new Date()).toISOString()) + }) + return () => unsubscribe() + }, []) + + const dateRange = util.getDateRangeOneWeek(curDate) + // console.log('>> dateRange', dateRange) + return ( + + + +
+
+ { + dateRange.map((day: util.TDay, i: number) => + + {days[day.dayNo].substring(0, 3)}
+ {day.dateStr.replace('/2021', '')} +
+ ) + } +
+ + { + members.map((m: StudyMember, i: number) => + m.active && Date.parse(m.startDateStr) <= util.getMonthLastDay(curDate).getTime() + ? + + { + dateRange.map((day: util.TDay, i: number) => renderCard(upDb, m, day, i)) + } + + : + ) + } +
+ ) +} + +function renderCard (upDb:UserProgressDb, m:StudyMember, day: util.TDay, i: number) { + const today = new Date() + const rs = [] + const card = upDb.getUser(m.userHandle)?.getCardByDate(day.dateStr) ?? null + if (card) { + rs.push() + } else if (today.toLocaleDateString() === day.dateStr) { + rs.push() + } else if (Date.parse(day.dateStr) >= Date.parse(m.startDateStr)) { + rs.push() + } else { + console.log('>> render empty card!') + // rs.push() // No longer needed? 7/31/21 + } + + return ( +
+ {rs} +
+ ) +} From 4dbcb56376e57adb28a701af5529384eb535515b Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 5 Aug 2021 14:03:05 -0400 Subject: [PATCH 26/30] =?UTF-8?q?=F0=9F=94=96=201.9.5:=20=E2=9C=A8=20Add?= =?UTF-8?q?=20footer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/studydash.html | 2 ++ src/StudyDash.tsx | 8 +++++++- src/data/changelog.json | 5 +++++ src/widgets/Footer.tsx | 43 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/widgets/Footer.tsx diff --git a/public/studydash.html b/public/studydash.html index 721f436..d5c61cb 100644 --- a/public/studydash.html +++ b/public/studydash.html @@ -8,6 +8,8 @@
+ +
diff --git a/src/StudyDash.tsx b/src/StudyDash.tsx index 261d2f2..32f7f28 100644 --- a/src/StudyDash.tsx +++ b/src/StudyDash.tsx @@ -3,6 +3,7 @@ import './assets/css/board.css' import './assets/css/links+glyphs.css' import * as l from './widgets/Layout' import { MemberBoard } from './widgets/MemberBoard' +import { Footer } from './widgets/Footer' import ReactDOM from 'react-dom' @@ -10,7 +11,12 @@ ReactDOM.render( , - document.querySelector('#root') + document.getElementById('root') +) + +ReactDOM.render( +
, + document.getElementById('footer') ) // https://webpack.js.org/api/hot-module-replacement/ diff --git a/src/data/changelog.json b/src/data/changelog.json index b4bd744..70fe321 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.5", + "message": "✨ Add footer", + "built": "Thu, 05 Aug 2021 14:03:05 EDT" + }, { "version": "1.9.4", "message": "♻ Refactor `MemberBoard` into separate component", diff --git a/src/widgets/Footer.tsx b/src/widgets/Footer.tsx new file mode 100644 index 0000000..b8c1d5e --- /dev/null +++ b/src/widgets/Footer.tsx @@ -0,0 +1,43 @@ +import changelogUri from '../data/changelog.json' +import React, { useEffect, useState } from 'react' +import styled from 'styled-components' + +const FFooter = styled.div` + text-align: right; + position: absolute; + color: black; + bottom: 0; + right: 0; + margin-bottom: 10px; + margin-right: 15px; + z-index: 99; + font-size: 14px; + line-height: 150%; +` + +type Commit = { + version: string + message: string + built: Date +} + +export const Footer: React.VFC = () => { + const [commit, setCommit] = useState() + + useEffect(() => { + fetch(changelogUri).then(rs => rs.json().then(payload => { + setCommit({ + version: payload[0].version, + message: payload[0].message, + built: payload[0].built + }) + })) + }, []) + + return ( + + 🔖 {commit?.version} | {commit?.message}

+ 👷‍♂️ {commit?.built ? commit.built.toString() : 'NA'} + + ) +} From e7284d2d531241d8fed05556cf46e921e6cbf17e Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 5 Aug 2021 15:58:05 -0400 Subject: [PATCH 27/30] =?UTF-8?q?=F0=9F=94=96=201.9.6:=20=E2=9C=A8=20Add?= =?UTF-8?q?=20attribution=20for=20CSS=20background=20art?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/studydash.html | 2 +- src/StudyDash.tsx | 9 +++-- src/StudyGroup.tsx | 1 - src/assets/css/board.css | 27 --------------- src/assets/css/design01.css | 34 +++++++++++++++++++ .../css/{links+glyphs.css => design02.css} | 18 +++++++--- src/assets/css/landscape.css | 4 +-- src/data/changelog.json | 5 +++ src/widgets/Attribution.tsx | 34 +++++++++++++++++++ src/widgets/Footer.tsx | 4 +-- src/widgets/MemberBoard.tsx | 9 +++-- 11 files changed, 106 insertions(+), 41 deletions(-) delete mode 100644 src/assets/css/board.css rename src/assets/css/{links+glyphs.css => design02.css} (64%) create mode 100644 src/widgets/Attribution.tsx diff --git a/public/studydash.html b/public/studydash.html index d5c61cb..8b76817 100644 --- a/public/studydash.html +++ b/public/studydash.html @@ -8,7 +8,7 @@
- +
diff --git a/src/StudyDash.tsx b/src/StudyDash.tsx index 32f7f28..6668446 100644 --- a/src/StudyDash.tsx +++ b/src/StudyDash.tsx @@ -1,9 +1,9 @@ import './assets/css/landscape.css' -import './assets/css/board.css' -import './assets/css/links+glyphs.css' +import './assets/css/design02.css' import * as l from './widgets/Layout' import { MemberBoard } from './widgets/MemberBoard' import { Footer } from './widgets/Footer' +import { Attribution } from './widgets/Attribution' import ReactDOM from 'react-dom' @@ -14,6 +14,11 @@ ReactDOM.render( document.getElementById('root') ) +ReactDOM.render( + , + document.getElementById('attribution') +) + ReactDOM.render(
, document.getElementById('footer') diff --git a/src/StudyGroup.tsx b/src/StudyGroup.tsx index 73306c7..1ee8d52 100644 --- a/src/StudyGroup.tsx +++ b/src/StudyGroup.tsx @@ -1,5 +1,4 @@ import './assets/css/design01.css' -import './assets/css/links+glyphs.css' import ReactDOM from 'react-dom' import React, { useState, useEffect } from 'react' import styled, { css } from 'styled-components' diff --git a/src/assets/css/board.css b/src/assets/css/board.css deleted file mode 100644 index 1a43407..0000000 --- a/src/assets/css/board.css +++ /dev/null @@ -1,27 +0,0 @@ -.board { - position: absolute; - display: flex; - left: 43px; - top: 29px; -} - -.personBox { - width: 205px; - height: 28px; -} - -.personTitle { - background: #632242; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); - - font-family: 'Chakra Petch', sans-serif; - font-style: normal; - font-weight: 400; - font-size: 16px; - line-height: 29px; - color: #FFFFFF; - - padding: 2px; - padding-left: 7px; - box-sizing: border-box; -} \ No newline at end of file diff --git a/src/assets/css/design01.css b/src/assets/css/design01.css index 378a57d..f9b9231 100644 --- a/src/assets/css/design01.css +++ b/src/assets/css/design01.css @@ -12,4 +12,38 @@ body { color: white; margin: 0; padding: 0; +} + +a:link { + color: #2f87f8; + text-decoration: none; +} + +a:visited { + color: #2f87f8; + text-decoration: none; +} + +a:hover { + color: #2f87f8; + text-decoration: underline; +} + +a:active { + color: red; +} + +.octicon { + fill: #a5b5bb; + margin-top: 2px; + margin-bottom: -3px; + padding-right: 6px; + /* background: pink; */ +} + +.commentNo { + font-weight: 600; + font-size: 13px; + font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; + color: #a5b5bb; } \ No newline at end of file diff --git a/src/assets/css/links+glyphs.css b/src/assets/css/design02.css similarity index 64% rename from src/assets/css/links+glyphs.css rename to src/assets/css/design02.css index 6922714..5802c72 100644 --- a/src/assets/css/links+glyphs.css +++ b/src/assets/css/design02.css @@ -1,16 +1,26 @@ +.board { + position: absolute; + display: flex; + left: 43px; + top: 29px; +} + a:link { - color: #2f87f8; + color: white; + font-weight: 300; text-decoration: none; } a:visited { - color: #2f87f8; + color: white; text-decoration: none; } a:hover { - color: #2f87f8; - text-decoration: underline; + color: yellow; + font-weight: 400; + /* text-decoration: underline; */ + /* background-color: yellow; */ } a:active { diff --git a/src/assets/css/landscape.css b/src/assets/css/landscape.css index e4ec8ab..de2be41 100644 --- a/src/assets/css/landscape.css +++ b/src/assets/css/landscape.css @@ -13,9 +13,9 @@ font-family: 'Chakra Petch', sans-serif; font-style: normal; font-weight: 400; - font-size: 16px; + font-size: 12px; line-height: 29px; - color: #FFFFFF; + /* color: blue; */ } @media (max-width: 960px) { diff --git a/src/data/changelog.json b/src/data/changelog.json index 70fe321..8f152d6 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.6", + "message": "✨ Add attribution for CSS background art", + "built": "Thu, 05 Aug 2021 15:58:05 EDT" + }, { "version": "1.9.5", "message": "✨ Add footer", diff --git a/src/widgets/Attribution.tsx b/src/widgets/Attribution.tsx new file mode 100644 index 0000000..e3c1adb --- /dev/null +++ b/src/widgets/Attribution.tsx @@ -0,0 +1,34 @@ +import React from 'react' +import styled from 'styled-components' + +const FAttribution = styled.div` + position: absolute; + color: black; + background-color: #a2a1b1; + top: 0; + right: 0; + margin-top: 29px; + margin-right: 43px; + z-index: 99; + font-size: 14px; + line-height: 150%; + width: fit-content; + height: 28px; + padding-left: 10px; + padding-right: 10px; + box-sizing: border-box; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25); + white-space: nowrap; +` + +const F14Link = styled.span` + font-size: 14px; +` + +export const Attribution: React.VFC = () => { + return ( + + CSS Background Art Credit: Luke Reid + + ) +} diff --git a/src/widgets/Footer.tsx b/src/widgets/Footer.tsx index b8c1d5e..6d237cc 100644 --- a/src/widgets/Footer.tsx +++ b/src/widgets/Footer.tsx @@ -8,8 +8,8 @@ const FFooter = styled.div` color: black; bottom: 0; right: 0; - margin-bottom: 10px; - margin-right: 15px; + margin-bottom: 12px; + margin-right: 20px; z-index: 99; font-size: 14px; line-height: 150%; diff --git a/src/widgets/MemberBoard.tsx b/src/widgets/MemberBoard.tsx index a486b8e..37ebc8f 100644 --- a/src/widgets/MemberBoard.tsx +++ b/src/widgets/MemberBoard.tsx @@ -52,6 +52,7 @@ const FMemberCard = styled(FCard)` background: #632242; font-size: 15px; padding-left: 7px; + padding-top: 3px; ` const FEntryCard = styled(FCard)` @@ -88,6 +89,10 @@ const PendingCard: React.VFC = () => { ) } +const F15Link = styled.span` + font-size: 15px; +` + type TMemberCard = { name: string userHandle: string @@ -96,7 +101,7 @@ type TMemberCard = { const MemberCard: React.FC = (props) => { return ( - {props.userHandle} + {props.userHandle} ) } @@ -116,7 +121,7 @@ const EntryCard: React.FC = (props) => { const title = props.title.length > 33 ? props.title.substr(0, 30) + '...' : props.title return ( - {title} + {title} ) } From 5dc7e820298b89b57661d8c6d9a169699bb7c655 Mon Sep 17 00:00:00 2001 From: Robert Lin Date: Thu, 5 Aug 2021 20:33:04 -0400 Subject: [PATCH 28/30] =?UTF-8?q?=F0=9F=94=96=201.9.7:=20=E2=9C=A8=20Begin?= =?UTF-8?q?=20integration=20of=20CSS=20trees=20to=20be=20dynamic?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/studydash.html | 10 +++++-- src/StudyDash.tsx | 6 ++++ src/data/changelog.json | 5 ++++ src/widgets/MemberBoard.tsx | 2 ++ src/widgets/SceneViz.tsx | 58 +++++++++++++++++++++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/widgets/SceneViz.tsx diff --git a/public/studydash.html b/public/studydash.html index 8b76817..ae7f570 100644 --- a/public/studydash.html +++ b/public/studydash.html @@ -8,6 +8,7 @@
+
@@ -93,7 +94,7 @@ - + @@ -129,8 +130,13 @@
-
Latest QA Build:
+
+ +
diff --git a/public/v2/index.html b/public/v2/index.html new file mode 100644 index 0000000..e19c2a0 --- /dev/null +++ b/public/v2/index.html @@ -0,0 +1,97 @@ + + + + + StudyDash QA | v2 "Jambul" + + + + + +
+
+
+ +
+
+ +
+ + \ No newline at end of file diff --git a/src/data/changelog.json b/src/data/changelog.json index e60614e..38d3dca 100644 --- a/src/data/changelog.json +++ b/src/data/changelog.json @@ -1,4 +1,9 @@ [ + { + "version": "1.9.9", + "message": "♻ Update `Previewer` to `v1`/`v2` \u0026 disable console logging", + "built": "Fri, 06 Aug 2021 05:08:54 EDT" + }, { "version": "1.9.8", "message": "✨ Finish integration of dynamic `CSS tree art` generation", diff --git a/src/widgets/SceneViz.tsx b/src/widgets/SceneViz.tsx index da7dd95..95805db 100644 --- a/src/widgets/SceneViz.tsx +++ b/src/widgets/SceneViz.tsx @@ -11,7 +11,7 @@ export const SceneViz: React.FC = (props) => { if (props.densityIndices.length > 0) { setIndex(oldIndex => { const newIndex = (oldIndex + 1) % props.densityIndices.length - console.log('\t>> densities/newIndex set:', props.densityIndices, newIndex) + // console.log('\t>> densities/newIndex set:', props.densityIndices, newIndex) return newIndex }) } diff --git a/webpack.common.js b/webpack.common.js index 479e22c..9c38726 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -38,9 +38,16 @@ module.exports = { chunks: ['StudyDash'] }), new HtmlWebpackPlugin({ - title: 'Preview', - filename: './preview/index.html', - template: './public/preview/index.html', + title: 'Preview v1', + filename: './v1/index.html', + template: './public/v1/index.html', + favicon: './public/favicon.ico', + chunks: [] + }), + new HtmlWebpackPlugin({ + title: 'Preview v2', + filename: './v2/index.html', + template: './public/v2/index.html', favicon: './public/favicon.ico', chunks: [] })