Skip to content

Commit

Permalink
Sprint Fig πŸ₯ (#41)
Browse files Browse the repository at this point in the history
* ✨ Begin Sprint Fig (Sat - 4/10/21)

* ✨ Add basic Admin tools

* πŸ—ƒ Add Firestore mock data for 'passages'

* ✨ Add 'Candidates' and 'Voting' buttons

* ✨ Begin implementing 'voting record' functionality

* ✨ Impl: After you vote, disable the voting buttons (show what you voted for)

* ✨ Impl: After you vote, show the results of the voting

* πŸ›  Fix webpack's HMR

* ✨ Add a 'Write' page where users can submit passage candidates (WIP)

* ♻️ Modify 'App.tsx' to bounce all unauthenticated users

* ✨ Add sidebar to 'Write' page (WIP)

* ♻️ Move 'changelog' into its own 'changelog.md' file

* ✨ Add overall collapsible sidebar to all pages (WIP)

* πŸ’„ Beautify the sidebar

* ✨ Impl 'deleteVote' firestore api call (WIP)

* ♻️ Change how votes are saved/read to/from firestore

* ✨ Add 'Results' page (WIP)

* ✨ Change the url in the address bar upon page navigation

* ✨ Sidebar: Highlight the page the user is currently looking at

* ♻️ Move 'page' widgets into their own 'pages' dir

* ✨ Sidebar: Add links to 'Admin Console' & 'Write' pages

* ✨ Sidebar: Add ability to navigate to external links

* ✨ Sidebar: Add external link to 'Changelog'

* ✨ Sidebar: Don't render when user is logged out

* ✨ 'Vote' page: Display a countdown clock until next coronation (Sun - 4/25/21)
  • Loading branch information
r002 authored Apr 26, 2021
1 parent 100de00 commit 4281e26
Show file tree
Hide file tree
Showing 23 changed files with 1,133 additions and 143 deletions.
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,17 @@ $> taskkill /PID <PID> /F
- https://mariusschulz.com/blog/declaring-global-variables-in-typescript
- https://stackoverflow.com/questions/52100103/getting-all-documents-from-one-collection-in-firestore
- https://medium.com/firebase-developers/the-secrets-of-firestore-fieldvalue-servertimestamp-revealed-29dd7a38a82b
- https://gitmoji.dev/
- https://gitmoji.dev/

---

## Project Motivation
Several motivations inspired and drove this project.

First: I've always been a big fan of the "self-quantification movement." I own a Fitbit and enjoy seeing granular metrics on everything I do: Sleep, exercise, etc. But Fitbit alone was insufficient. I wanted to know how much time I spent eating, brushing my teeth, running errands, etc.

Second: I wanted a good project with which to learn React with hooks and what webdev looks like nowadays in 2021. Webpack, ESLint, TypeScript, Firebase preview channels, the whole nine yards. My previous knowledge on the webdev front was horribly outdated. Also: Tests, design patterns, Git. It was high time to get caught up.

Finally, realistically though, what ***really*** drove this project: My wife, honest to God, bugs me probably once a week that "I don't spend enough time with her." And that: "I love my computer and spend more time with it than I love her." Utter baloney. With this app, I now finally have hard, cold data to show The Wife that, "See? We *did* visit the park four times last week!" and "I spent an aggregate total of __ hours __ minutes with you last month watching Netflix, going out for walks, and eating."

Data and technology to the rescue! πŸ˜€
83 changes: 83 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Changelog

## [Sat - 4/10/21 | Sprint Fig πŸ₯](https://github.com/r002/captains-log/pull/41)
- ✨ Begin Sprint Fig
- ✨ Add basic Admin tools
- πŸ—ƒ Add Firestore mock data for 'passages'
- ✨ Add 'Candidates' and 'Voting' buttons
- ✨ Begin implmenting 'voting record' functionality
- ✨ Done: After you vote, disable the voting buttons (show what you voted for)
- πŸ›  Fix webpack's HMR
- ✨ Add a 'Write' page where users can submit passage candidates (WIP)
- ♻️ Modify 'App.tsx' to bounce all unautheticated users
- ✨ Add sidebar to 'Write' page (WIP)
- ♻️ Move 'changelog' into its own 'changelog.md' file
- ✨ Add overall collapsible sidebar to all pages (WIP)
- πŸ’„ Beautify the sidebar
- ✨ Impl 'deleteVote' firestore api call (WIP)
- ♻️ Change how votes are saved/read to/from firestore
- ✨ Add 'Results' page (WIP)
- ✨ Change the url in the address bar upon page navigation
- ✨ In sidebar: Highlight the page the user is currently looking at
- ♻️ Move 'page' widgets into their own 'pages' dir
- ✨ In sidebar: Add links to 'Admin Console' & 'Write' pages
- ✨ Sidebar: Add ability to navigate to external links
- ✨ Sidebar: Add external link to 'Changelog'
- ✨ Sidebar: Don't render when user is logged out
- ✨ 'Vote' page: Display a giant countdown clock until next coronation
- TODO: After deadline passes, show results of the voting
- TODO: Implement Comments

## [Fri - 4/9/21 | Sprint Elderberry πŸ’](https://github.com/r002/captains-log/pull/40)
- ✨ Begin adding Wattpad POC page. Add new 'Wattpad' entrypoint to webpack
- πŸ›‚ Add Clark Kent dummy user, update Firestore rules, handle unauthorized users
- ♻️ Move FlashAlert inside NavBar widget
- ✨ Add StoryBoard widget
- πŸ—ƒ Update Firestore mock data


## [Thu - 4/1/21 | Sprint Durian 🍈](https://github.com/r002/captains-log/pull/33)
- ♻️ Refactor widgets into 'LogTypes' & 'Inputs' for better organization</li>
- πŸ›  Fix package-lock.json</li>
- πŸ—ƒ Update 'data/multi-users' with YoutubeLogs dummy data</li>
- ♻️ #27: Begin refactoring global event handlers for 'log actions' into DataContext</li>
- πŸ”¨ Add npm dev script shortcut to start auth/firestore emulators</li>
- ♻️ #27: Finish refactoring global event handlers for 'log actions' into DataContext</li>
- ✨ #31: Add 'Details Pane'. Shows Youttube videos for YT log entries</li>
- ♻️ Change it so 'Welcome Log' is always shown if no user is logged in</li>
- ✨ #31: Improve the 'Details Pane'-- show different pane for ActivityLogs</li>
- ✨ #38: Add up/down keyboard arrow support to navigate logs</li>
- ✨ Add support for parsing 'https://youtu.be/...' vids</li>

## [Mon - 3/29/21 | Sprint Apple 🍎](https://github.com/r002/captains-log/pull/24)
- 🐞 Fix #23: 'FlashAlert' bug. Reset every time the theme changes</li>
- ♻️ Refactor 'ThemeContext' to expose a 'toggler' hook</li>
- ♻️ Refactor the buttons in Navbar to use types</li>
- ✨ #4: Add 'watch' command to add clickable Youtube links in logs</li>
- ♻️ Refactor public config into its own file</li>
- 🐞 Fix IooB bug when processing ActivityLogs to compute durations</li>
- 🐞 Fix bug: Allow dt of YoutubeLogs to be edited</li>
- ♻️ Refactor the way logs are read from db & updated. Use 'Object.assign(..)'</li>
- β™»οΈπŸ€‘ Refactor code in 'Navbar'. Add 'Export Logs' dummy button</li>
- β™»οΈπŸ€‘ Rename all event handlers in 'Navbar'. Add 'Export Logs' dummy function</li>
- ✨ #29: Impl log exporter - exports the most recent 1000 logs as '.json' file</li>
- ♻️ Refactor the way YoutubeLogs are stored in db. Store 'vid' instead of 'url'</li>

## [Fri - 3/26/21 | PR #18: Add dt/activity edit/delete functionality in ActivityLog](https://github.com/r002/captains-log/pull/18)
- 🧹 Delete '\data\saved_data' from repo</li>
- πŸ™ˆ Update .gitignore to exclude local Firestore data that's saved on exit (`/data/saved_data/`)</li>
- ♻️ Refactor code to generate unique Firestore ids on the clientside before writing to Firestore</li>
- 🀑 Add dummy GUI buttons in ActivityLog widget</li>
- ✨ Impl 'delete button' (❌) in ActivityLog widget</li>
- ♻️ Refactor Firestore api calls into /FirestoreApi.ts</li>
- ♻️ Refactor Ticker into its own widget</li>
- ✨ Impl 'double-click-to-edit/update-activity' for ActivityLog</li>
- ♻️ Combine 'updateLog' into 'writeLog' in /FirestoreApi.ts</li>
- 🩹 Round sleep & activity metalog durations to the nearest minute</li>
- 🩹 Round sleep & activity metalog durations to the nearest minute; try again</li>
- ✨ Impl 'double-click-to-edit/update-datetime' for ActivityLog</li>
- 🐞 Impl 'double-click-to-edit/update-datetime' for ActivityLog; fix bug</li>
- ♻️ Refactor 'DtInput' & 'ActivityInput' into their own widgets</li>
- ✨ Impl 'FlashAlert' modal. Invalid DtInput now flashes alert & fails gracefully</li>
- ♻️ Refactor 'sendLogDelete' into `/services/Internal.ts`</li>
- 🐞 Fix 'FlashAlert' bug. Reset every time user signs in/out</li>
2 changes: 1 addition & 1 deletion data/multi-users/auth_export/accounts.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"kind":"identitytoolkit#DownloadAccountResponse","users":[{"localId":"IrQMtCapW6rkJzs8XqPdrvVkntqr","createdAt":"1618046097922","lastLoginAt":"1618089023105","displayName":"Clark Kent","photoUrl":"https://upload.wikimedia.org/wikipedia/en/thumb/d/d6/Superman_Man_of_Steel.jpg/220px-Superman_Man_of_Steel.jpg","screenName":"Superman","email":"[email protected]","emailVerified":true,"providerUserInfo":[{"providerId":"google.com","rawId":"5579365237773824206342892315665271489352","federatedId":"5579365237773824206342892315665271489352","displayName":"Clark Kent","photoUrl":"https://upload.wikimedia.org/wikipedia/en/thumb/d/d6/Superman_Man_of_Steel.jpg/220px-Superman_Man_of_Steel.jpg","email":"[email protected]","screenName":"Superman"}],"lastRefreshAt":"2021-04-10T21:10:23.105Z"},{"localId":"JOKYpMbqVxruIKO5pj9jvz4pySAr","createdAt":"1616120233889","lastLoginAt":"1618089013948","displayName":"John McClane","photoUrl":"https://pbs.twimg.com/profile_images/2647803927/1f3436521ba2ee011d4e6a9d60596c44.jpeg","providerUserInfo":[{"providerId":"google.com","rawId":"0861056242461056649423093128039461622495","federatedId":"0861056242461056649423093128039461622495","displayName":"John McClane","photoUrl":"https://pbs.twimg.com/profile_images/2647803927/1f3436521ba2ee011d4e6a9d60596c44.jpeg","email":"[email protected]","screenName":"John"}],"validSince":"1618018135","email":"[email protected]","emailVerified":true,"disabled":false,"lastRefreshAt":"2021-04-10T21:10:13.948Z"},{"localId":"OJ5WOiv3hU07LQzNMyGj8jB0Kgxc","createdAt":"1616269116330","lastLoginAt":"1618050839854","displayName":"Diana Prince","photoUrl":"https://news.artnet.com/app/news-upload/2019/12/Movies-Gallery_WW84_05_5deb0dd8d64557.66209613-256x256.jpg","providerUserInfo":[{"providerId":"google.com","rawId":"5241301171256853587898344326373797001945","federatedId":"5241301171256853587898344326373797001945","displayName":"Diana Prince","photoUrl":"https://news.artnet.com/app/news-upload/2019/12/Movies-Gallery_WW84_05_5deb0dd8d64557.66209613-256x256.jpg","email":"[email protected]","screenName":"Wonder Woman"}],"validSince":"1618018135","email":"[email protected]","emailVerified":true,"disabled":false,"lastRefreshAt":"2021-04-10T10:33:59.854Z"}]}
{"kind":"identitytoolkit#DownloadAccountResponse","users":[{"localId":"IrQMtCapW6rkJzs8XqPdrvVkntqr","createdAt":"1618046097922","lastLoginAt":"1618089023105","displayName":"Clark Kent","photoUrl":"https://upload.wikimedia.org/wikipedia/en/thumb/d/d6/Superman_Man_of_Steel.jpg/220px-Superman_Man_of_Steel.jpg","providerUserInfo":[{"providerId":"google.com","rawId":"5579365237773824206342892315665271489352","federatedId":"5579365237773824206342892315665271489352","displayName":"Clark Kent","photoUrl":"https://upload.wikimedia.org/wikipedia/en/thumb/d/d6/Superman_Man_of_Steel.jpg/220px-Superman_Man_of_Steel.jpg","email":"[email protected]","screenName":"Superman"}],"validSince":"1619181861","email":"[email protected]","emailVerified":true,"disabled":false},{"localId":"JOKYpMbqVxruIKO5pj9jvz4pySAr","createdAt":"1616120233889","lastLoginAt":"1619181913054","displayName":"John McClane","photoUrl":"https://pbs.twimg.com/profile_images/2647803927/1f3436521ba2ee011d4e6a9d60596c44.jpeg","providerUserInfo":[{"providerId":"google.com","rawId":"0861056242461056649423093128039461622495","federatedId":"0861056242461056649423093128039461622495","displayName":"John McClane","photoUrl":"https://pbs.twimg.com/profile_images/2647803927/1f3436521ba2ee011d4e6a9d60596c44.jpeg","email":"[email protected]","screenName":"John"}],"validSince":"1619181861","email":"[email protected]","emailVerified":true,"disabled":false,"lastRefreshAt":"2021-04-23T16:34:03.799Z"},{"localId":"OJ5WOiv3hU07LQzNMyGj8jB0Kgxc","createdAt":"1616269116330","lastLoginAt":"1619196331075","displayName":"Diana Prince","photoUrl":"https://news.artnet.com/app/news-upload/2019/12/Movies-Gallery_WW84_05_5deb0dd8d64557.66209613-256x256.jpg","providerUserInfo":[{"providerId":"google.com","rawId":"5241301171256853587898344326373797001945","federatedId":"5241301171256853587898344326373797001945","displayName":"Diana Prince","photoUrl":"https://news.artnet.com/app/news-upload/2019/12/Movies-Gallery_WW84_05_5deb0dd8d64557.66209613-256x256.jpg","email":"[email protected]","screenName":"Wonder Woman"}],"validSince":"1619181861","email":"[email protected]","emailVerified":true,"disabled":false,"lastRefreshAt":"2021-04-23T16:45:31.076Z"}]}
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"start": "webpack serve --config webpack.dev.js",
"format": "prettier --write \"src/**/*.{js,jsx}\"",
"db": "firebase emulators:start --only \"auth,firestore\" --import=data\\multi-users --export-on-exit=data\\saved_data",
"bkupdb": "firebase emulators:export data\\multi-users"
"dbdump": "firebase emulators:export data\\multi-users"
},
"repository": {
"type": "git",
Expand Down
87 changes: 77 additions & 10 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,49 @@
import styled, { css } from 'styled-components'
import firebase from 'firebase/app'
import React, { useState, useEffect } from 'react'
import { Navbar } from './widgets/Navbar'
import { ThemeContext, themes } from './providers/ThemeContext'
import './style.css'
import { UserContext } from './providers/AuthContext'
import styled from 'styled-components'
import { TFlashAlert } from './services/Internal'
import Sidebar from './widgets/Sidebar'
import LogEntry from './pages/LogEntry'
import StoryBoard from './pages/StoryBoard'
import Results from './pages/Results'
import Admin from './pages/Admin'
import Write from './pages/Write'

type TMainLayout = {
readonly collapseSidebar: boolean
readonly userLoggedIn: boolean
}

const MainLayout = styled.div<TMainLayout>`
height: 100vh;
display: grid;
grid-gap: 0;
grid-template-columns: 0 1fr;
grid-template-rows: 52px 1fr;
grid-template-areas:
"sidebar navbar"
"sidebar content";
background-color: transparent;
color: #444;
${props => props.userLoggedIn && css`
grid-template-columns: 250px 1fr;
`}
${props => props.collapseSidebar && css`
grid-template-columns: 50px 1fr;
`}
`

const Body = styled.div`
grid-area: content;
padding: 40px 20px 20px 20px;
width: 100%;
background-color: transparent;
/* background: lightslategray; */
box-sizing: border-box;
/* border: solid darkgray 1px; */
Expand Down Expand Up @@ -81,17 +115,35 @@ const useAuth = (setFlashAlert: React.Dispatch<React.SetStateAction<TFlashAlert
return state
}

const pages = new Map([
['index', <LogEntry />],
['storyboard', <StoryBoard />],
['results', <Results />],
['write', <Write />],
['admin', <Admin />]
])

type TApp = {
bodyContent: React.ReactNode
page: string
}
const App = (props: TApp) => {
const [flashAlert, setFlashAlert] = useState<TFlashAlert | null>(null)
const { initializing, user } = useAuth(setFlashAlert)
const [collapseSidebar, setCollapseSidebar] = useState(false)
const [page, setPage] = useState(props.page)
const [context, setContext] = useState({
theme: themes.light,
toggleTheme: customToggler
})

function navigate (page: string): void {
if (page.includes('https://')) {
window.location.href = page
} else {
setPage(page)
}
}

function customToggler (): void {
setContext((oldContext) => ({
theme: oldContext.theme === themes.light
Expand All @@ -104,9 +156,13 @@ const App = (props: TApp) => {
function listenForFlashAlert (event: Event) {
const fa = (event as CustomEvent).detail as TFlashAlert
setFlashAlert(fa)
console.log('!!!!!!!!!!!!!! FlashAlert received!', fa)
console.log('!!!!!!!!!! FlashAlert received!', fa)
}

useEffect(() => {
history.pushState({ page: page }, page, '/?p=' + page)
}, [page])

useEffect(() => {
document.body.addEventListener('flashAlert', listenForFlashAlert, false)
return () => {
Expand All @@ -119,21 +175,32 @@ const App = (props: TApp) => {
}, [user, context])

let appWrapper = <></>
if (!initializing) {
if (initializing) {
console.log('firebase is initializing!!!!')
} else {
appWrapper =
<>
<ThemeContext.Provider value={context}>
<UserContext.Provider value={{ user }}>
<Navbar flashAlert={flashAlert} />
<Body>
{props.bodyContent}
</Body>
<MainLayout collapseSidebar={collapseSidebar}
userLoggedIn={user !== null}>
{user &&
<Sidebar navigate={navigate}
selectedPage={page}
collapseSidebar={collapseSidebar}
setCollapseSidebar={setCollapseSidebar} />
}
<Navbar flashAlert={flashAlert} />
<Body>
{user === null
? 'πŸ‘‹ Hello! πŸ™‹β€β™‚οΈ Please login to proceed. πŸ™'
: pages.get(page) ?? <>Page not found!</>}
</Body>
</MainLayout>
</UserContext.Provider>
</ThemeContext.Provider>
</>
document.body.style.visibility = 'visible'
} else {
console.log('firebase is initializing!!!!')
}

// console.log('App render fired 😁')
Expand Down
Loading

0 comments on commit 4281e26

Please sign in to comment.