Compare commits
19 Commits
react-app-
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1cccc6a41 | ||
|
|
e158b5ccd6 | ||
|
|
aafba656c8 | ||
|
|
17de3426e2 | ||
|
|
f58d607c5d | ||
|
|
ddaf3df1a3 | ||
|
|
4398ee2d45 | ||
|
|
3b9ee304db | ||
|
|
f5c8edd74c | ||
|
|
de22b649a2 | ||
|
|
7bc236e7e7 | ||
|
|
db72085762 | ||
|
|
406a89db39 | ||
|
|
3f01282bcc | ||
|
|
998cf45a97 | ||
|
|
c474fe3792 | ||
|
|
64a9420b01 | ||
|
|
90d633ed23 | ||
|
|
5d3c81a650 |
14647
package-lock.json
generated
Normal file
14647
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -3,13 +3,17 @@
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@reach/router": "^1.2.1",
|
||||
"firebase": "^7.2.2",
|
||||
"node-sass": "^4.13.0",
|
||||
"react": "^16.11.0",
|
||||
"react-dom": "^16.11.0",
|
||||
"react-firebaseui": "^4.1.0",
|
||||
"react-redux": "^7.1.1",
|
||||
"react-scripts": "3.2.0",
|
||||
"redux": "^4.0.4",
|
||||
"redux-thunk": "^2.3.0"
|
||||
"redux-thunk": "^2.3.0",
|
||||
"uuid": "^3.3.3"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
||||
22
src/App.css
22
src/App.css
@@ -1,22 +0,0 @@
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #09d3ac;
|
||||
}
|
||||
42
src/App.js
42
src/App.js
@@ -1,11 +1,49 @@
|
||||
import React from "react";
|
||||
import React, {useState, useEffect} from "react";
|
||||
import StyledFirebaseAuth from 'react-firebaseui/StyledFirebaseAuth';
|
||||
import firebase from'firebase'
|
||||
import { Provider } from "react-redux";
|
||||
import { Router } from "@reach/router";
|
||||
import Boxes from "./boxes/Boxes";
|
||||
import SignedIn from "./SignedIn/SignedIn.js";
|
||||
import setupStore from "./store/setupStore.js";
|
||||
|
||||
const config = {
|
||||
apiKey: "AIzaSyC5krz4RBiT87RK7cEidh3n-A4H63uGcyM",
|
||||
authDomain: "retrod-7e2cd.firebaseapp.com",
|
||||
};
|
||||
const uiConfig = {
|
||||
signInFlow: 'popup',
|
||||
signInSuccessUrl: '/',
|
||||
signInOptions: [
|
||||
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
|
||||
]
|
||||
};
|
||||
function App() {
|
||||
const [sprint, setSprint] = useState(1);
|
||||
const [isSignedIn, setSignIn] = useState(false)
|
||||
useEffect(() => {
|
||||
firebase.auth().onAuthStateChanged(user => {
|
||||
setSignIn(!!user)
|
||||
})
|
||||
})
|
||||
return (
|
||||
<Provider store={setupStore()}>
|
||||
<div>Yoooooo</div>
|
||||
<Router>
|
||||
<Boxes exact path={`/` + sprint} />
|
||||
</Router>
|
||||
<div>
|
||||
{isSignedIn ? (
|
||||
<>
|
||||
<SignedIn/>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<h1>You're Not Signed In</h1>
|
||||
<StyledFirebaseAuth uiConfig={uiConfig} firebaseAuth={firebase.auth()}/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</Provider>
|
||||
);
|
||||
}
|
||||
|
||||
25
src/Items/Items.js
Normal file
25
src/Items/Items.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
import { databaseRef } from '../store/firebase.js'
|
||||
import styles from "./items.module.css";
|
||||
|
||||
export default function Item({ item, boxId, sprint }) {
|
||||
const handleClick = e => {
|
||||
let url;
|
||||
if(boxId === "1"){
|
||||
url = `retros/` + sprint + `/www/`
|
||||
} else if(boxId === "2"){
|
||||
url = `retros/` + sprint + `/!www/`
|
||||
} else if(boxId === "3"){
|
||||
url = `retros/` + sprint + `/questions/`
|
||||
} else {
|
||||
url = 'retros/1/a/'
|
||||
}
|
||||
databaseRef.ref(url + item.id + `/completed`).set(item.completed === false ? true : false)
|
||||
}
|
||||
return (
|
||||
<div className={styles.flexItem}>
|
||||
<p style={{ textDecoration: item.completed ? "line-through" : "" }}>{item.title}</p>
|
||||
<button onClick={handleClick}>{item.completed === false ? <p className={styles.checkmark}>✓</p> : <p className={styles.redx}>x</p>}</button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
15
src/Items/items.module.css
Normal file
15
src/Items/items.module.css
Normal file
@@ -0,0 +1,15 @@
|
||||
.flexItem{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
button{
|
||||
background: none;
|
||||
border: none;
|
||||
}
|
||||
.checkmark{
|
||||
color: green;
|
||||
cursor: pointer;
|
||||
}
|
||||
.redx{
|
||||
color: red;
|
||||
}
|
||||
45
src/NewItem/NewItem.js
Normal file
45
src/NewItem/NewItem.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import React, {useState} from 'react';
|
||||
import { databaseRef } from '../store/firebase.js'
|
||||
import uuid from "uuid";
|
||||
|
||||
export default function NewItem({ addItem, boxId, sprint }) {
|
||||
const [value, setValue ] = useState("");
|
||||
const handleSubmit = e => {
|
||||
e.preventDefault();
|
||||
let retroRef;
|
||||
let url;
|
||||
if(boxId === "1"){
|
||||
url = `retros/` + sprint + `/www`;
|
||||
retroRef = databaseRef.ref(url);
|
||||
} else if(boxId === "2"){
|
||||
url = `retros/` + sprint + `/!www`;
|
||||
retroRef = databaseRef.ref(url);
|
||||
} else if(boxId === "3"){
|
||||
url = `retros/` + sprint + `/questions`;
|
||||
retroRef = databaseRef.ref(url);
|
||||
} else {
|
||||
url = 'retros/1/a';
|
||||
retroRef = databaseRef.ref(url);
|
||||
}
|
||||
const item = {
|
||||
completed: false,
|
||||
id: uuid.v4(),
|
||||
title: value,
|
||||
}
|
||||
let objectId = retroRef.push(item);
|
||||
databaseRef.ref(url + `/` + objectId.key + `/id`).set(objectId.key)
|
||||
setValue("")
|
||||
}
|
||||
return (
|
||||
<div>
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
value={value}
|
||||
placeholder="stuff"
|
||||
onChange={e => setValue(e.target.value)}
|
||||
/>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
21
src/SignedIn/SignedIn.js
Normal file
21
src/SignedIn/SignedIn.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from "react";
|
||||
import firebase from'firebase';
|
||||
import SprintSelect from "../sprintSelect/SprintSelect"
|
||||
import styles from "./signedIn.module.css";
|
||||
|
||||
export default function SignedIn() {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.alignRight}>
|
||||
<div className={styles.marginRight}>
|
||||
<p>{firebase.auth().currentUser.displayName}</p>
|
||||
<div>
|
||||
<img align="right" className={styles.profilePicture} alt='user profile' src={firebase.auth().currentUser.photoURL} />
|
||||
</div>
|
||||
<button className={styles.signOutButton} onClick={() => firebase.auth().signOut()}>Sign Out</button>
|
||||
</div>
|
||||
</div>
|
||||
<SprintSelect />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
25
src/SignedIn/signedIn.module.css
Normal file
25
src/SignedIn/signedIn.module.css
Normal file
@@ -0,0 +1,25 @@
|
||||
body{
|
||||
background: lightseagreen;
|
||||
}
|
||||
.alignRight{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
.marginRight{
|
||||
margin-right: 1rem;
|
||||
}
|
||||
.signOutButton{
|
||||
background: none;
|
||||
border: none;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
padding: 0;
|
||||
margin-top: 1rem;
|
||||
}
|
||||
.alignRight .profilePicture{
|
||||
max-width: 50px;
|
||||
}
|
||||
13
src/boxes/Boxes.js
Normal file
13
src/boxes/Boxes.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
import styles from './Boxes.module.css'
|
||||
import Cards from '../cards/Cards.js'
|
||||
|
||||
export default function Boxes({ sectionName, boxId, sprint }) {
|
||||
return (
|
||||
<div>
|
||||
<div className={styles.box}>
|
||||
<Cards sectionName={sectionName} boxId={boxId} sprint={sprint} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
4
src/boxes/Boxes.module.css
Normal file
4
src/boxes/Boxes.module.css
Normal file
@@ -0,0 +1,4 @@
|
||||
.box{
|
||||
border: .15rem solid black;
|
||||
background: lightgrey;
|
||||
}
|
||||
55
src/cards/Cards.js
Normal file
55
src/cards/Cards.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import { databaseRef } from '../store/firebase.js'
|
||||
import Item from '../Items/Items.js';
|
||||
import NewItem from '../NewItem/NewItem.js'
|
||||
import DeleteItem from '../deleteItem/DeleteItem.js'
|
||||
import styles from "./cards.module.css";
|
||||
|
||||
export function Cards({item, setItem, boxId, sprint, sectionName, sprint_id}) {
|
||||
return (
|
||||
<>
|
||||
<h3>{sectionName}</h3>
|
||||
{item.map((i, index) => (
|
||||
<div className={i.sprint_id === sprint ? styles.cardBackground : styles.hide} key={i.id}>
|
||||
<Item
|
||||
item={i}
|
||||
index={index}
|
||||
boxId={boxId}
|
||||
sprint={sprint}
|
||||
/>
|
||||
<DeleteItem item={i} boxId={boxId} sprint={sprint}/>
|
||||
</div>
|
||||
))}
|
||||
<NewItem sprint={sprint} boxId={boxId}/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function FirebaseWrapper({sectionName, boxId, sprint}) {
|
||||
const [cards, setCards] = useState(null)
|
||||
let retro;
|
||||
if(boxId === "1"){
|
||||
retro = databaseRef.ref(`retros/` + sprint + `/www`);
|
||||
} else if(boxId === "2"){
|
||||
retro = databaseRef.ref(`retros/` + sprint + `/!www`);
|
||||
} else if(boxId === "3"){
|
||||
retro = databaseRef.ref(`retros/` + sprint + `/questions`);
|
||||
} else {
|
||||
retro = databaseRef.ref('retros/1/a');
|
||||
}
|
||||
const retroRef = useMemo(() => databaseRef.ref(retro), []);
|
||||
useEffect(() => {
|
||||
retroRef.on('value', function(snapshot) {
|
||||
const values = Object.values(snapshot.val())
|
||||
setCards(values)
|
||||
});
|
||||
// this will be called when our component unmounts
|
||||
return () => {
|
||||
retroRef.off();
|
||||
}
|
||||
}, [retroRef]);
|
||||
if(!cards) {
|
||||
return <div>loading...</div>;
|
||||
};
|
||||
return <Cards sectionName={sectionName} item={cards} boxId={boxId} sprint={sprint} setItem={()=> {}}/>
|
||||
}
|
||||
8
src/cards/cards.module.css
Normal file
8
src/cards/cards.module.css
Normal file
@@ -0,0 +1,8 @@
|
||||
.cardBackground{
|
||||
background: white;
|
||||
margin: .5em;
|
||||
padding: 1em;
|
||||
}
|
||||
.hide{
|
||||
display: none;
|
||||
}
|
||||
31
src/deleteItem/DeleteItem.js
Normal file
31
src/deleteItem/DeleteItem.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { databaseRef } from '../store/firebase.js'
|
||||
import styles from "./deleteItem.module.css";
|
||||
|
||||
export default function DeleteItem({ item, boxId, objectId, sprint }) {
|
||||
// const [value, setValue ] = useState("");
|
||||
|
||||
const handleClick = e => {
|
||||
let retroRef;
|
||||
if(boxId === "1"){
|
||||
retroRef = databaseRef.ref(`retros/` + sprint + `/www/` + item.id);
|
||||
} else if(boxId === "2"){
|
||||
retroRef = databaseRef.ref(`retros/` + sprint + `/!www/` + item.id);
|
||||
} else if(boxId === "3"){
|
||||
retroRef = databaseRef.ref(`retros/` + sprint + `/questions/` + item.id);
|
||||
} else {
|
||||
retroRef = databaseRef.ref(`retros/1/a/` + item.id);
|
||||
}
|
||||
// const item = {
|
||||
// completed: false,
|
||||
// id: uuid.v4(),
|
||||
// title: value,
|
||||
// }
|
||||
// databaseRef.ref.remove(retroRef);
|
||||
// setValue("")
|
||||
retroRef.remove()
|
||||
}
|
||||
return (
|
||||
<button className={styles.deleteButton} onClick={handleClick}>DELETE</button>
|
||||
)
|
||||
}
|
||||
10
src/deleteItem/deleteItem.module.css
Normal file
10
src/deleteItem/deleteItem.module.css
Normal file
@@ -0,0 +1,10 @@
|
||||
.deleteButton{
|
||||
color: darkred;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
font-size: .5em;
|
||||
font-weight: bolder;
|
||||
letter-spacing: 1px;
|
||||
cursor: pointer;
|
||||
}
|
||||
54
src/sprintSelect/SprintSelect.js
Normal file
54
src/sprintSelect/SprintSelect.js
Normal file
@@ -0,0 +1,54 @@
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import Boxes from "../boxes/Boxes";
|
||||
import { databaseRef } from '../store/firebase.js'
|
||||
import styles from "../sprintSelect/sprintSelect.module.css";
|
||||
|
||||
export function SprintSelect({item}) {
|
||||
const [sprint, setSprint] = useState(1);
|
||||
let sprintArray = [];
|
||||
let sortedSprint;
|
||||
sortedSprint = item.map((i, index) => (
|
||||
sprintArray.push(i.sprint_id)
|
||||
))
|
||||
.reduce((unique, item) => {
|
||||
return unique.includes(item) ? unique : [...unique, item]
|
||||
}, [])
|
||||
.sort();
|
||||
let dropdownSprint;
|
||||
dropdownSprint = sortedSprint.map((i, index) => (
|
||||
<option onClick={() => setSprint(i)}>{i}</option>
|
||||
));
|
||||
return (
|
||||
<div>
|
||||
<label>Choose Sprint:</label>
|
||||
<select>
|
||||
{dropdownSprint}
|
||||
</select>
|
||||
<h3>Sprint {sprint}</h3>
|
||||
<div className={styles.grid}>
|
||||
<Boxes sectionName={"What Went Well"} sprint={sprint} boxId={'1'} />
|
||||
<Boxes sectionName={"What Could Be Better"} sprint={sprint} boxId={'2'}/>
|
||||
<Boxes sectionName={"Questions"} sprint={sprint} boxId={'3'}/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function FirebaseWrapper() {
|
||||
const [cards, setCards] = useState(null)
|
||||
let retro = databaseRef.ref(`retros/1/www`);
|
||||
const retroRef = useMemo(() => databaseRef.ref(retro), []);
|
||||
useEffect(() => {
|
||||
retroRef.on('value', function(snapshot) {
|
||||
const values = Object.values(snapshot.val())
|
||||
setCards(values)
|
||||
});
|
||||
return () => {
|
||||
retroRef.off();
|
||||
}
|
||||
}, [retroRef]);
|
||||
if(!cards) {
|
||||
return <div>loading...</div>;
|
||||
};
|
||||
return <SprintSelect item={cards} setItem={()=> {}}/>
|
||||
}
|
||||
6
src/sprintSelect/sprintSelect.module.css
Normal file
6
src/sprintSelect/sprintSelect.module.css
Normal file
@@ -0,0 +1,6 @@
|
||||
.grid{
|
||||
display: grid;
|
||||
grid-template-columns: auto auto auto;
|
||||
grid-column-gap: 1em;
|
||||
margin: 1rem;
|
||||
}
|
||||
7
src/store/firebase.js
Normal file
7
src/store/firebase.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import * as firebase from 'firebase';const config = {
|
||||
apiKey: "AIzaSyC5krz4RBiT87RK7cEidh3n-A4H63uGcyM",
|
||||
authDomain: "retrod-7e2cd.firebaseapp.com",
|
||||
databaseURL: "https://retrod-7e2cd.firebaseio.com/",
|
||||
}
|
||||
firebase.initializeApp(config);
|
||||
export const databaseRef = firebase.database();
|
||||
@@ -1,13 +1,14 @@
|
||||
import { createStore, applyMiddleware, compose } from "redux";
|
||||
import thunk from "redux-thunk";
|
||||
import rootReducer from "../reducers/main.js";
|
||||
const devTools = window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__();
|
||||
|
||||
export default function setupStore() {
|
||||
return createStore(
|
||||
rootReducer,
|
||||
compose(
|
||||
applyMiddleware(thunk),
|
||||
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
|
||||
(devTools || function(f) { return f; })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user