-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Admin login, games page, etc; custom pocketbase-react
- Loading branch information
Showing
17 changed files
with
3,502 additions
and
17,583 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,50 @@ | ||
import { useState } from 'react'; | ||
|
||
import { Pocketbase as PocketbaseProvider } from 'pocketbase-react'; | ||
import React from 'react'; | ||
import { Pocketbase as PocketbaseProvider } from 'pocketbase-react/src'; | ||
import { Router } from './pages/_router'; | ||
import { AppHeader } from './components/app-header'; | ||
import './style.css'; | ||
|
||
import { useAppContent } from 'pocketbase-react/src'; | ||
import { Game, GameState, Goal, Player, Team } from './types'; | ||
|
||
const serverURL = "http://127.0.0.1:8090"; | ||
// const collections = ['games', 'goals', 'players', 'teams', 'misc']; | ||
const collections: string[] = []; | ||
// these get automatically prefetched & subscribed to updates | ||
const collections = ['games', 'goals', 'players', 'teams', 'misc']; | ||
const webRedirectURL = "mariansam.eu/webred"; | ||
const mobileRedirectURL = "mariansam.eu/mobred" // for example | ||
|
||
const App: React.FC = () => { | ||
export const App: React.FC = () => { | ||
return ( | ||
<PocketbaseProvider | ||
serverURL={serverURL} | ||
webRedirectUrl={webRedirectURL} | ||
mobileRedirectUrl={mobileRedirectURL} | ||
initialCollections={collections} | ||
openURL={async (url) => { | ||
// for example expo WebBrowser | ||
}} | ||
> | ||
<div className="d-flex flex-column align-items-center justify-content-start"> | ||
<AppHeader /> | ||
<div style={{maxWidth: 600, width: '100%'}}> | ||
<Router /> | ||
</div> | ||
<PocketbaseDataLoader> | ||
<div style={{maxWidth: 600, width: '100%'}}> | ||
<Router /> | ||
</div> | ||
</PocketbaseDataLoader> | ||
</div> | ||
</PocketbaseProvider> | ||
); | ||
}; | ||
|
||
export default App; | ||
const PocketbaseDataLoader: React.FC<React.PropsWithChildren> = ({ children }) => { | ||
const gameMisc = useAppContent<GameState>('misc', true); | ||
const players = useAppContent<Player>('players', true); | ||
const games = useAppContent<Game>('games', true); | ||
const teams = useAppContent<Team>('teams', true); | ||
const goals = useAppContent<Goal>('goals', true); | ||
|
||
if (!gameMisc.records || !players.records || !games.records || !teams.records || !goals.records) | ||
return null; | ||
|
||
return children; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import React, { useMemo } from 'react'; | ||
import Card from 'react-bootstrap/Card'; | ||
import Table from 'react-bootstrap/Table'; | ||
import { useGameLogic } from '../logic'; | ||
import { Game } from '../types'; | ||
import { GoalRow } from './goal-row'; | ||
|
||
export const FinishedMatches: React.FC = () => { | ||
const { | ||
games, | ||
gameState, | ||
} = useGameLogic(); | ||
|
||
const finishedGames = useMemo(() => { | ||
const filtered = games.filter(g => g.no < gameState.currentGameNo) | ||
return filtered; | ||
}, [games, gameState]); | ||
|
||
return ( | ||
<div> | ||
<h3 className="text-center mb-3">Dohrané zápasy</h3> | ||
{finishedGames.map(game => ( | ||
<GameView game={game} key={game.id} /> | ||
))} | ||
</div> | ||
); | ||
}; | ||
|
||
type MatchProps = { | ||
game: Game, | ||
}; | ||
|
||
const vsInlineStyle: React.CSSProperties = { | ||
marginTop: 'auto', | ||
marginBottom: 'auto', | ||
fontSize: 20, | ||
}; | ||
|
||
|
||
const GameView: React.FC<MatchProps> = props => { | ||
const { | ||
game, | ||
} = props; | ||
|
||
const { teams } = useGameLogic(); | ||
|
||
const team1 = useMemo(() => { | ||
return teams.find(t => t.id === game.team1); | ||
}, [teams, game]); | ||
|
||
const team2 = useMemo(() => { | ||
return teams.find(t => t.id === game.team2); | ||
}, [teams, game]); | ||
|
||
if (!team1 || !team2) | ||
return null; | ||
|
||
return ( | ||
<Card className='text-center' style={{marginBottom: 32}}> | ||
<Card.Body className='d-flex flex-row justify-content-around' style={{marginBottom: -10}}> | ||
<div className='d-flex flex-column flex-grow-1'> | ||
<Card.Text style={{fontSize: 25}}>{team1.name}</Card.Text> | ||
<Card.Text style={{fontSize: 50, fontWeight: 600, marginTop: -25}} >{game.goals1}</Card.Text> | ||
</div> | ||
|
||
<Card.Text style={vsInlineStyle}>vs</Card.Text> | ||
|
||
<div className='d-flex flex-column flex-grow-1'> | ||
<Card.Text style={{fontSize: 25}}>{team2.name}</Card.Text> | ||
<Card.Text style={{fontSize: 50, fontWeight: 600, marginTop: -25}} >{game.goals2}</Card.Text> | ||
</div> | ||
</Card.Body> | ||
{!!game.goals.length && ( | ||
<Table bordered style={{tableLayout: 'fixed', marginBottom: 0, marginRight: 0}}> | ||
<tbody> | ||
{game.goals.map(goalId => ( | ||
<GoalRow goalId={goalId} small={true} key={goalId} /> | ||
))} | ||
</tbody> | ||
</Table> | ||
)} | ||
</Card> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import React, { useMemo } from 'react'; | ||
import { Goal, ReferenceTo } from '../types'; | ||
import { useGameLogic } from '../logic'; | ||
|
||
type GoalRowProps = { | ||
goalId: ReferenceTo<Goal>, | ||
small?: true, | ||
}; | ||
|
||
export const GoalRow: React.FC<GoalRowProps> = props => { | ||
const { | ||
goalId, | ||
small, | ||
} = props; | ||
|
||
const { goals, players } = useGameLogic(); | ||
|
||
const goal = useMemo(() => { | ||
return goals.find(g => g.id === goalId); | ||
}, [goals, goalId]) | ||
|
||
const player = useMemo(() => { | ||
if (!goal) | ||
return; | ||
return players.find(p => p.id === goal.player); | ||
}, [players, goal]); | ||
|
||
if (!goal || !player) | ||
return null; | ||
|
||
if (goal.side === 1) { | ||
return ( | ||
<tr> | ||
<td className="table-active" style={small && {fontSize: 13, padding: 4}}> | ||
<strong>{player.name}</strong> | ||
<br /> | ||
{goal.minute}. minuta | ||
</td> | ||
<td className="table-light"> | ||
</td> | ||
</tr> | ||
); | ||
} else if (goal.side === 2) { | ||
return ( | ||
<tr className="goal-row"> | ||
<td className="table-light"> | ||
</td> | ||
<td className="table-active" style={small && {fontSize: 13, padding: 4, paddingRight: -1}}> | ||
<strong>{player.name}</strong> | ||
<br /> | ||
{goal.minute}. minuta | ||
</td> | ||
</tr> | ||
); | ||
} | ||
|
||
return null; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,8 @@ | ||
import React from 'react' | ||
import ReactDOM from 'react-dom/client' | ||
import App from './App.tsx' | ||
import { App } from './App.tsx' | ||
import 'bootstrap/dist/css/bootstrap.min.css'; | ||
|
||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( | ||
<React.StrictMode> | ||
<App /> | ||
</React.StrictMode>, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React, { useState } from 'react'; | ||
import { useAuth } from 'pocketbase-react/src'; | ||
|
||
import FormControl from 'react-bootstrap/FormControl'; | ||
import Button from 'react-bootstrap/Button'; | ||
|
||
const ADMIN_EMAIL = '[email protected]'; | ||
|
||
export const AdminLoginPage: React.FC = () => { | ||
const { user, isSignedIn, actions: { signInWithEmailAdmin } } = useAuth(); | ||
|
||
const [password, setPassword] = useState(""); | ||
|
||
const login = () => { | ||
signInWithEmailAdmin(ADMIN_EMAIL, password); | ||
}; | ||
|
||
return ( | ||
<div className='p-4 mx-auto'> | ||
<h3>Admin panel</h3> | ||
<img src='https://kagi.com/proxy/dancing-hotdog.gif?c=LwXhtTInURWSS6isT8YHWKe8FwnGJQHVUI8ripCyb5_bo5Nz6m4FFRepUDLKKGEiwUgilfKdVgJGOj_FkTWB3oVDNKsQqxkcy779n6bix2g%3D' className='mw-100'></img> | ||
<FormControl type="password" className='my-2 py-2' placeholder='heslo zmrde' onChange={(e) => setPassword(e.target.value)} /> | ||
<Button className='mx-auto' onClick={() => login()} style={{display: "block"}}>Login</Button> | ||
</div> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React from 'react'; | ||
import { Route, Switch, Redirect } from "wouter"; | ||
import { useAuth } from 'pocketbase-react/src'; | ||
import { AdminHomePage } from './home'; | ||
import { AdminLoginPage } from './_login'; | ||
|
||
export const AdminRouter: React.FC = () => { | ||
const { user, isSignedIn, actions } = useAuth(); | ||
console.log({user, isSignedIn, actions}); | ||
|
||
if (!isSignedIn) { | ||
return ( | ||
<Switch> | ||
<Route path="/admin/login" component={AdminLoginPage} /> | ||
<Route><Redirect href="/" /></Route> | ||
</Switch> | ||
); | ||
} | ||
|
||
return ( | ||
<Switch> | ||
<Route path="/admin/login"><Redirect href="/admin" /></Route> | ||
<Route path="/admin" component={AdminHomePage} /> | ||
</Switch> | ||
); | ||
}; |
Empty file.
Oops, something went wrong.