Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

246 auth verfication and dashboard fetch placeholders #259

Open
wants to merge 12 commits into
base: development
Choose a base branch
from
8 changes: 6 additions & 2 deletions app/AuthWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { onAuthStateChanged, signOut } from 'firebase/auth'
import { auth } from '@/app/services/initializeFirebase'
import { getUserProfile } from '@/app/services/userInfo'
import LandingPage from '@/app/components/LandingPage'

import Loading from './components/Loading'
const AuthContext = createContext()

export const AuthProvider = ({ children }) => {
Expand All @@ -37,7 +37,11 @@ export const AuthProvider = ({ children }) => {
const memoizedUserProfile = useMemo(() => userProfile, [userProfile])

if (loading) {
return <div>Loading...</div>
return (
<div>
<Loading prompt={'Logging In...'} />
</div>
)
}

const handleSignOut = () => {
Expand Down
20 changes: 19 additions & 1 deletion app/DataProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
useContext
} from 'react'
import { collection, getDocs, doc, updateDoc, addDoc } from 'firebase/firestore'
import { ref, uploadBytes, getDownloadURL } from 'firebase/storage'

import { db } from '@/app/services/initializeFirebase.js'
import { db, storage } from '@/app/services/initializeFirebase.js'
import { useAuth } from '@/app/AuthWrapper.js'
import getTeams from '@/app/services/getTeams.js'

Expand Down Expand Up @@ -92,6 +93,23 @@

const createMatch = useCallback(async (collectionName, newMatchData) => {
try {
let pdfUrl = null
if (newMatchData.pdfFile) {
const pdfRef = ref(storage, `match-pdfs/${newMatchData.pdfFile.name}`)
const metadata = {
contentType: 'application/pdf'
}

const snapshot = await uploadBytes(
pdfRef,
newMatchData.pdfFile.blob,
metadata
)
pdfUrl = await getDownloadURL(snapshot.ref)
}
console.log(pdfUrl)
newMatchData.pdfFile = pdfUrl

const newMatch = {
id: 'temp-id',
collection: collectionName,
Expand All @@ -107,7 +125,7 @@
setError(err)
console.error('Error creating new match:', err)
}
}, [])

Check warning on line 128 in app/DataProvider.js

View workflow job for this annotation

GitHub Actions / lint

React Hook useCallback has a missing dependency: 'fetchMatches'. Either include it or remove the dependency array

const fetchLogos = useCallback(async () => {
// Cache expiry time, currently 24 hours
Expand Down
113 changes: 71 additions & 42 deletions app/components/Dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import DashTileContainer from '@/app/components/DashTileContainer'
// import getTeams from '@/app/services/getTeams.js'
import RosterList from '@/app/components/RosterList.js'
import Loading from './Loading'

import { searchableProperties } from '@/app/services/searchableProperties.js'
import SearchIcon from '@/public/search'
Expand All @@ -25,18 +26,12 @@
const { matches, logos } = useData()
const [searchTerm, setSearchTerm] = useState('')
const [selectedMatchSets, setSelectedMatchSets] = useState([])
console.log(matches)

console.log('matches', matches)
console.log(matches.length)
const formattedMatches = formatMatches(matches)
console.log(formattedMatches)

// default show latest match: TODO BUG causes infinite re-rendering
// useEffect(() => {
// if (formattedMatches.length > 0) {
// const latestMatchKey = `${formattedMatches[0].matchDate}#${formattedMatches[0].teams.opponentTeam}`
// setSelectedMatchSets([latestMatchKey])
// }
// }, [formattedMatches])

// Fuzzy search
const fuse = useMemo(() => {
if (!formattedMatches.length) return null
Expand Down Expand Up @@ -75,7 +70,24 @@
)
}

const displayMatchSets = searchTerm ? filteredMatchSets : selectedMatchSets
// A: Search Results
// B: Carousel Results
// Default: All
const displayMatchSets = useMemo(() => {
if (searchTerm) return filteredMatchSets
if (selectedMatchSets.length > 0) return selectedMatchSets

// fetch all, arr(set(matches))
return [
...new Set(
formattedMatches.map((match) =>
match.matchDetails.duel
? `${match.matchDate}#${match.teams.opponentTeam}`
: `_#${match.matchDetails.event}`
)
)
]
}, [searchTerm, filteredMatchSets, selectedMatchSets, formattedMatches])

return (
<div className={styles.container}>
Expand Down Expand Up @@ -111,7 +123,11 @@

<div className={styles.carousel}>
{formattedMatches.map((match, index) => {
const matchKey = `${match.matchDate}#${match.teams.opponentTeam}`
let matchKey = `${match.matchDate}#${match.teams.opponentTeam}`
if (!match.matchDetails.duel) {
console.log('EVENT')
matchKey = `_#${match.matchDetails.event}`
}

return (
<div
Expand All @@ -119,7 +135,7 @@
className={`${styles.card} ${selectedMatchSets.includes(matchKey) ? styles.active : ''}`}
onClick={() => handleCarouselClick(matchKey)}
>
<img

Check warning on line 138 in app/components/Dashboard.js

View workflow job for this annotation

GitHub Actions / lint

Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element
src={logos[match.teams.opponentTeam]}
alt="Team Logo"
className={styles.logo}
Expand All @@ -132,39 +148,52 @@

<div className={styles.mainContent}>
<div className={styles.matchesSection}>
{displayMatchSets.map((matchKey, index) => {
const singlesMatches = formattedMatches.filter(
(match) =>
match.singles &&
matchKey === `${match.matchDate}#${match.teams.opponentTeam}`
)
const doublesMatches = formattedMatches.filter(
(match) =>
!match.singles &&
matchKey === `${match.matchDate}#${match.teams.opponentTeam}`
)
const [matchDate, matchName] = matchKey.split('#')
return (
<div key={index} className={styles.matchSection}>
<div className={styles.matchContainer}>
<div className={styles.matchHeader}>
<h3>{`v ${matchName}`}</h3>
<span className={styles.date}>{matchDate}</span>
{matches.length === 0 ? (
<Loading prompt={'Fetching Matches...'} />
) : (
displayMatchSets.map((matchKey, index) => {
const singlesMatches = formattedMatches.filter(
(match) =>
match.singles &&
((match.matchDetails.duel &&
matchKey ===
`${match.matchDate}#${match.teams.opponentTeam}`) ||
(!match.matchDetails.duel &&
matchKey === `_#${match.matchDetails.event}`))
)
const doublesMatches = formattedMatches.filter(
(match) =>
!match.singles &&
((match.matchDetails.duel &&
matchKey ===
`${match.matchDate}#${match.teams.opponentTeam}`) ||
(!match.matchDetails.duel &&
matchKey === `_#${match.matchDetails.event}`))
)
const [matchDate, matchName] = matchKey.split('#')

return (
<div key={index} className={styles.matchSection}>
<div className={styles.matchContainer}>
<div className={styles.matchHeader}>
<h3>{matchName}</h3>
<span className={styles.date}>{matchDate}</span>
</div>
<DashTileContainer
matches={singlesMatches}
matchType="Singles"
onTileClick={handleTileClick}
/>
<DashTileContainer
matches={doublesMatches}
matchType="Doubles"
onTileClick={handleTileClick}
/>
</div>
<DashTileContainer
matches={singlesMatches}
matchType="Singles"
onTileClick={handleTileClick}
/>
<DashTileContainer
matches={doublesMatches}
matchType="Doubles"
onTileClick={handleTileClick}
/>
</div>
</div>
)
})}
)
})
)}
</div>

<div className={styles.rosterContainer}>
Expand Down
30 changes: 30 additions & 0 deletions app/components/Loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import styles from '@/app/styles/Loading.module.css'

export default function Loading({ prompt }) {
return (
<div className={styles.loadingContainer}>
<svg
width="400"
height="400"
viewBox="0 0 400 400"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<circle
cx="200"
cy="200"
r="100"
stroke="#2774ae"
strokeWidth="6"
strokeLinecap="round"
strokeDasharray="628.32" /* Circumference of the circle */
strokeDashoffset="628.32" /* Initially hidden */
className={styles.animatedCircle}
/>
<text x="200" y="350" className={styles.customText}>
{prompt}
</text>
</svg>
</div>
)
}
6 changes: 3 additions & 3 deletions app/matches/[slug]/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ const MatchPage = () => {
player2TieScores={matchData.pointsJson.map(
(point) => point.player2TiebreakScore
)}
isUnfinished={matchData.matchDetails.status === 'unfinished'}
isUnfinished={matchData.matchDetails.unfinished}
displaySections={{ score: true, info: true, matchup: true }}
/>
<div className={styles.headerRow}>
Expand Down Expand Up @@ -399,7 +399,7 @@ const MatchPage = () => {
player2TieScores={matchData.pointsJson.map(
(point) => point.player2TiebreakScore
)}
isUnfinished={matchData.matchDetails.status === 'unfinished'}
isUnfinished={matchData.matchDetails.unfinished}
displaySections={{ score: true, info: true, matchup: true }}
/>
</div>
Expand Down Expand Up @@ -429,7 +429,7 @@ const MatchPage = () => {
{showPDF ? (
<iframe
className={styles.pdfView}
src={matchData.pdfUrl}
src={matchData.pdfFile}
width="90%"
height="1550"
/>
Expand Down
42 changes: 34 additions & 8 deletions app/services/matchSchemas.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ const initialSchema = {
title: 'Date',
format: 'date'
},
unfinished: {
type: 'boolean',
title: 'Unfinished'
},
duel: {
type: 'boolean',
title: 'Duel'
},
matchScore: {
type: 'object',
title: 'Match Score',
Expand Down Expand Up @@ -149,8 +157,8 @@ const initialSchema = {
},
pdfFile: {
type: 'string',
title: 'PDF File',
format: 'data-url'
title: 'PDF File'
// format: 'data-url'
}
},
required: [
Expand All @@ -175,26 +183,44 @@ const uiSchema = {
matchScore: {
set1: {
clientTiebreak: {
'ui:widget': 'updown'
'ui:widget': 'text',
'ui:options': {
inputType: 'number'
}
},
opponentTiebreak: {
'ui:widget': 'updown'
'ui:widget': 'text',
'ui:options': {
inputType: 'number'
}
}
},
set2: {
clientTiebreak: {
'ui:widget': 'updown'
'ui:widget': 'text',
'ui:options': {
inputType: 'number'
}
},
opponentTiebreak: {
'ui:widget': 'updown'
'ui:widget': 'text',
'ui:options': {
inputType: 'number'
}
}
},
set3: {
clientTiebreak: {
'ui:widget': 'updown'
'ui:widget': 'text',
'ui:options': {
inputType: 'number'
}
},
opponentTiebreak: {
'ui:widget': 'updown'
'ui:widget': 'text',
'ui:options': {
inputType: 'number'
}
}
}
}
Expand Down
Loading
Loading