32 Commits

Author SHA1 Message Date
1e62ba70d1 Changed to showing visible participate button. 2022-03-07 20:51:25 -06:00
fba8212aeb Fixed access to dashboard page. 2022-03-07 20:49:43 -06:00
5c7e26a1a9 Added package-lock.json to .gitignore. 2022-03-07 20:37:10 -06:00
Arjun Sahni
e773477fb0 Merge pull request #5 from csc309-winter-2022/develop
Develop
2022-03-06 21:51:05 -05:00
Arjun Sahni
196c36444d Update README.md 2022-03-06 21:50:24 -05:00
6a9e677043 Created user dashboard. 2022-03-06 20:49:13 -06:00
Hansi Xu
329cc7c74f Merge branch 'main' of https://github.com/csc309-winter-2022/team58 2022-03-06 21:37:58 -05:00
Hansi Xu
30c407563d Fixed chat 2022-03-06 21:37:30 -05:00
Piyush Sharma
4f338a2005 Merge branch 'main' of https://github.com/csc309-winter-2022/team58 2022-03-06 21:35:14 -05:00
Piyush Sharma
b717c94e4e Added comment 2022-03-06 21:35:10 -05:00
caed17bc8e Added user dashboard. 2022-03-06 20:31:17 -06:00
Piyush Sharma
c7cd9481f3 Update README.md 2022-03-06 21:25:18 -05:00
d402a67266 Merged with latest dev branch. 2022-03-06 20:25:07 -06:00
Piyush Sharma
340acfa2ed Updated Readme 2022-03-06 21:22:50 -05:00
c1fe10ddc8 Removed package-lock.json. 2022-03-06 20:14:50 -06:00
Sahni-Arjun
532b5d3876 minor changes 2022-03-06 21:13:11 -05:00
38d9267bff Initial commit of static interfaces. 2022-03-06 20:12:31 -06:00
Sahni-Arjun
528cb80c1f minor changes, added navbar to admin 2022-03-06 21:01:56 -05:00
Arjun Sahni
a1ed8d14fa Merge pull request #4 from csc309-winter-2022/develop
Develop
2022-03-06 20:52:17 -05:00
Arjun Sahni
641eca074f Merge pull request #3 from csc309-winter-2022/admin
admin functionality
2022-03-06 20:51:53 -05:00
Hansi Xu
7ea36e01e5 Merge branch 'develop' 2022-03-06 20:32:40 -05:00
Hansi Xu
9c583ce5e0 Merge branch 'chat' into develop 2022-03-06 20:31:41 -05:00
Piyush Sharma
61c138f5c3 Merge pull request #2 from csc309-winter-2022/develop
Merging authentication and homepage into main branch
2022-03-06 20:27:55 -05:00
Piyush Sharma
d9b0c827c8 Merge pull request #1 from csc309-winter-2022/authentication
Added Sign in/up, Home, and Navbar
2022-03-06 20:24:01 -05:00
Piyush Sharma
e1befed115 Added Homepage and Navbar 2022-03-06 20:22:23 -05:00
Hansi Xu
0a1323da8a Finally fixed input 2022-03-06 18:15:21 -05:00
Hansi Xu
7e17e1c9e9 Adding profile pics for phase1 (hard coded contacts) 2022-03-06 16:22:26 -05:00
Hansi Xu
ab80301f31 Adding chat components 2022-03-06 15:57:04 -05:00
Hansi Xu
c332594b40 Revert "The chat component"
This reverts commit fa8c2e7cf9.
2022-03-06 15:53:19 -05:00
Hansi Xu
fa8c2e7cf9 The chat component 2022-03-06 15:40:56 -05:00
ffe8dad9ff Added simple suggested matches template. 2022-03-02 03:08:33 -06:00
1e0f79387a Some template design for horizontal Match information. 2022-03-02 02:24:36 -06:00
29 changed files with 902 additions and 27631 deletions

View File

@@ -1 +1,21 @@
# team58 # team58
Sports Matcher is an application that allows users to connect with other athletes, schedule sports meets, and rent sports equipment!
**Built Using**
It is built using the React framework and the Material UI and React Bootstrap libraries.
**Instructions**
To use Sports Matcher, navigate to the sports-matcher directory in the repository and run the commands `npm i` and `npm start` in order. This should launch a localhost window in your browser which shows the homepage.
From here you can Sign In to your account using the username "admin" and password "admin" OR using the username "user" and password "user" as specified in the handout.
Signing in as 'admin' will take you to the admin page. You will be able to see a list of current matches, users and suspended users. You will need to click the appropriate button for the correct table to appear.
Every page has a navbar at the top. There is a chat and profile icon. Clicking on the chat icon will take you to the chat page. From the profile icon you can sign out.

View File

@@ -21,3 +21,5 @@
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
package-lock.json

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,9 @@
"@testing-library/jest-dom": "^5.16.2", "@testing-library/jest-dom": "^5.16.2",
"@testing-library/react": "^12.1.3", "@testing-library/react": "^12.1.3",
"@testing-library/user-event": "^13.5.0", "@testing-library/user-event": "^13.5.0",
"bootstrap": "^5.1.3",
"react": "^17.0.2", "react": "^17.0.2",
"react-bootstrap": "^2.2.0",
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^6.2.2", "react-router-dom": "^6.2.2",
"react-scripts": "^5.0.0", "react-scripts": "^5.0.0",

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -24,6 +24,12 @@
work correctly both with client-side routing and a non-root public URL. work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3"
crossorigin="anonymous"
/>
<title>React App</title> <title>React App</title>
</head> </head>
<body> <body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -1,4 +1,8 @@
.MainTable { .MainTable {
padding : 20px; padding : 20px;
}
.Title {
margin-top: 40px;
} }

View File

@@ -4,6 +4,7 @@ import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography'; import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container'; import Container from '@mui/material/Container';
import { TableContainer, TableCell, Table, TableBody, TableRow, TableHead, Paper } from '@mui/material'; import { TableContainer, TableCell, Table, TableBody, TableRow, TableHead, Paper } from '@mui/material';
import Navbar from './Navbar';
@@ -36,14 +37,14 @@ class AdminTable extends React.Component {
} }
EditButton() { editButton() {
return <Button onClick={() => { return <Button onClick={() => {
alert('clicked'); alert('clicked');
}} variant="contained">Edit</Button>; }} variant="contained">Edit</Button>;
} }
DeleteButtonClick() { deleteButtonClick() {
return ( return (
<Container component="main" maxWidth="xs"> <Container component="main" maxWidth="xs">
@@ -55,20 +56,27 @@ class AdminTable extends React.Component {
) )
} }
NewDeleteButtonClick() { newDeleteButtonClick() {
return (<form onsubmit="console.log('You clicked submit.'); return false"> return (<form onsubmit="console.log('You clicked submit.'); return false">
<button type="submit">Submit</button> <button type="submit">Submit</button>
</form>) </form>)
} }
DeleteButton() { deleteButton() {
return <Button onClick={() => { return <Button onClick={() => {
alert('User deleted.'); alert('User deleted.');
}} variant="contained">Delete</Button>; }} variant="contained">Delete</Button>;
} }
PardonButton() { matchDeleteButton() {
return <Button onClick={() => {
alert('Match deleted.');
}} variant="contained">Delete</Button>;
}
pardonButton() {
return <Button onClick={() => { return <Button onClick={() => {
alert('User pardoned.'); alert('User pardoned.');
}} variant="contained">Pardon</Button>; }} variant="contained">Pardon</Button>;
@@ -85,8 +93,8 @@ class AdminTable extends React.Component {
<TableCell>{name}</TableCell> <TableCell>{name}</TableCell>
<TableCell>{email}</TableCell> <TableCell>{email}</TableCell>
<TableCell>{phone}</TableCell> <TableCell>{phone}</TableCell>
<TableCell>{this.DeleteButton()}</TableCell> <TableCell>{this.deleteButton()}</TableCell>
<TableCell>{this.EditButton()}</TableCell> <TableCell>{this.editButton()}</TableCell>
</TableRow> </TableRow>
) )
}) })
@@ -102,9 +110,9 @@ class AdminTable extends React.Component {
<TableCell>{name}</TableCell> <TableCell>{name}</TableCell>
<TableCell>{email}</TableCell> <TableCell>{email}</TableCell>
<TableCell>{phone}</TableCell> <TableCell>{phone}</TableCell>
<TableCell>{this.DeleteButton()}</TableCell> <TableCell>{this.deleteButton()}</TableCell>
<TableCell>{this.EditButton()}</TableCell> <TableCell>{this.editButton()}</TableCell>
<TableCell>{this.PardonButton()}</TableCell> <TableCell>{this.pardonButton()}</TableCell>
</TableRow> </TableRow>
) )
}) })
@@ -120,8 +128,8 @@ class AdminTable extends React.Component {
<TableCell>{date}</TableCell> <TableCell>{date}</TableCell>
<TableCell>{location}</TableCell> <TableCell>{location}</TableCell>
<TableCell>{description}</TableCell> <TableCell>{description}</TableCell>
<TableCell>{this.DeleteButton()}</TableCell> <TableCell>{this.matchDeleteButton()}</TableCell>
<TableCell>{this.EditButton()}</TableCell> <TableCell>{this.editButton()}</TableCell>
</TableRow> </TableRow>
) )
}) })
@@ -208,7 +216,8 @@ class AdminTable extends React.Component {
render() { render() {
return ( return (
<div> <div>
<h1 id='title'>Administration</h1> <Navbar></Navbar>
<h1 className='Title'>Administration</h1>
<div className='ButtonList'> <div className='ButtonList'>
<Button onClick={() => { <Button onClick={() => {
this.setState({ buttonColors: ['black', '', ''] }); this.setState({ buttonColors: ['black', '', ''] });

View File

@@ -3,13 +3,20 @@ import { Routes, Route, Link } from "react-router-dom";
import SignIn from './SignIn'; import SignIn from './SignIn';
import SignUp from './SignUp'; import SignUp from './SignUp';
import Admin from './Admin'; import Admin from './Admin';
import Home from './Home';
import ChatWindow from './ChatWindow';
import UserDashboard from "./UserDashboard";
function App() { function App() {
return ( return (
<div className="App"> <div className="App">
<Routes> <Routes>
<Route path="" element={<Home />} />
<Route path="dashboard" element={<UserDashboard />} />
<Route path="sign-in" element={<SignIn />} /> <Route path="sign-in" element={<SignIn />} />
<Route path="sign-up" element={<SignUp />} /> <Route path="sign-up" element={<SignUp />} />
<Route path="admin" element={<Admin />} /> <Route path="admin" element={<Admin />} />
<Route path="chat-window" element={<ChatWindow />} />
</Routes> </Routes>
</div> </div>
); );

View File

@@ -0,0 +1,20 @@
import { Stack, Typography } from "@mui/material";
import MatchInfo from "./matchinfo";
export default function CardSuggestedMatches() {
return (
<div style={{ padding: 25 }}>
<Typography variant="h4" component="div">
Suggested
</Typography>
<Stack sx={{ margin: 2 }} direction="row" spacing={2}>
<MatchInfo>
</MatchInfo>
<MatchInfo>
</MatchInfo>
<MatchInfo>
</MatchInfo>
</Stack >
</div>
);
}

View File

@@ -0,0 +1,18 @@
/* Please direct questions to Hansi Xu (Wallace LaWall on Discord) */
import React from 'react';
import './chats.css'
class Chat extends React.Component {
render() {
return (
<div class="chatbubble-container">
<div class= {this.props.side === "left" ? "chatbubble left": "chatbubble right"}>
{this.props.message}
</div>
</div>
)
}
}
export default Chat;

View File

@@ -0,0 +1,115 @@
/* Please direct questions to Hansi Xu (Wallace LaWall on Discord) */
import React from 'react';
import './chats.css'
import Chat from './Chat'
import Contact from './Contact'
import { useState } from "react";
import Navbar from './Navbar';
class ChatWindow extends React.Component {
render() {
return (
<div class="chatcomponent">
<Navbar></Navbar>
<UserList />
<MessageList />
<ChatInput />
</div>
)
}
}
class UserList extends React.Component {
render() {
return (
<div class="contactlist">
<Contact pfpsrc="./chief.jpg" name="Master Chief"/>
<Contact pfpsrc="./freeman.jpg" name="Gordon Freeman" />
<Contact pfpsrc="./shogun.jpg" name="Raiden Shogun" selected="true" />
</div>
)
}
}
class MessageList extends React.Component {
render() {
return (
<div class="messagelist">
<Chat message="Got time for tennis this week, Raiden?" side="right"/>
<Chat message="Foolish question. If I do not even have free time, How am I to pursue eternity and fulfill my promise to the people of Inazuma?" side="left" />
<Chat message="Aiight, see you at 4" side="right" />
<Chat message="As you wish." side="left" />
</div>
)
}
}
// class ChatWindow extends React.Component {
// render() {
// return (
// <div>
// <ChatUserList />
// {/* <MessageList /> */}
// </div>
// )
// }
// }
const ChatInput = () => {
const [message, setMessage] = useState( '' );
// const onKeyPress = (e) => {
// // if(e.key === 'Enter'){
// // e.preventDefault(); // Ensure it is only this code that runs
// // setMessage("")
// // }
// }
const onKeyDown = (e) => {
const keyCode = e.which || e.keyCode;
// 13 represents the Enter key
if (keyCode === 13 && !e.shiftKey) {
e.preventDefault();
setMessage("")
}
}
return (
// onKeyPress={(e) => onKeyPress(e)}
<div>
<textarea
class="chatinput"
value={message}
placeholder="Press ENTER to send, SHIFT + ENTER for new line"
onChange={e => setMessage(e.target.value)}
onKeyDown={onKeyDown}
/>
</div>
);
};
class ChatInput2 extends React.Component {
constructor(props) {
super(props)
this.setState({inputVal : ""})
}
handleUserInput(e) {
this.setState(this.setState({inputVal : e.target.value}));
};
render() {
return (<textarea class="chatinput" placeholder="Press ENTER to send, Ctrl + ENTER for new line"
onKeyPress={(e)=>this.onKeyPress(e)} value="" onChange={(e) => this.handleUserInput(e)} />)
}
onKeyPress(e) {
if(e.key === 'Enter'){
e.preventDefault(); // Ensure it is only this code that runs
this.setState({inputVal : ""});
}
}
}
export default ChatWindow;

View File

@@ -0,0 +1,38 @@
/* Please direct questions to Hansi Xu (Wallace LaWall on Discord) */
import React from 'react';
import './chats.css';
class Contact extends React.Component {
constructor(props) {
super(props)
this.state = {
selected : this.props.selected
}
}
onClick() {
// This toggling of the contact selection is for demo purposes only
// Once backend is implemented, only one contact can be selected
if (this.state.selected === "false") {
this.setState({selected : "true"})
} else {
this.setState({selected : "false"})
}
}
render() {
return (
<div class={this.state.selected === "true" ? "contact dark" : "contact"}>
<div class="profilepiccontainer">
<img src={this.props.pfpsrc} class="profilepic" onClick={() => this.onClick()}
alt="profile" />
</div>
<div class="profilenamecontainer">
<div class="profilename" onClick={() => this.onClick()}>{this.props.name}</div>
</div>
</div>
)
}
}
export default Contact;

View File

@@ -0,0 +1,65 @@
import { InputLabel, MenuItem, Select, TextField, FormControl } from "@mui/material";
export default function Filter() {
return (
<div>
<FormControl sx={{ margin: 2 }}>
<InputLabel id="skill-level-label">Sport</InputLabel>
<Select
labelId="skill-level-label"
id="skill-level"
label="Skill level"
sx={{ width: 100 }}
>
<MenuItem value={-10}>Tennis</MenuItem>
<MenuItem value={10}>Soccer</MenuItem>
<MenuItem value={20}>Golf</MenuItem>
<MenuItem value={30}>Basketball</MenuItem>
</Select>
</FormControl>
<FormControl sx={{ margin: 2 }}>
<InputLabel id="skill-level-label">Level</InputLabel>
<Select
labelId="skill-level-label"
id="skill-level"
label="Skill level"
sx={{ width: 100 }}
>
<MenuItem value={-10}>Everyone</MenuItem>
<MenuItem value={10}>Beginner</MenuItem>
<MenuItem value={20}>Intermediate</MenuItem>
<MenuItem value={30}>Professional</MenuItem>
</Select>
</FormControl>
<FormControl sx={{ margin: 2 }}>
<InputLabel id="skill-level-label">Level</InputLabel>
<Select
labelId="skill-level-label"
id="skill-level"
label="Skill level"
sx={{ width: 100 }}
>
<MenuItem value={-10}>Everyone</MenuItem>
<MenuItem value={10}>Beginner</MenuItem>
<MenuItem value={20}>Intermediate</MenuItem>
<MenuItem value={30}>Professional</MenuItem>
</Select>
</FormControl>
<FormControl sx={{ margin: 2 }}>
<TextField id="outlined-basic" label="Date" variant="outlined" />
</FormControl>
<FormControl sx={{ margin: 2 }}>
<TextField id="outlined-basic" label="Time" variant="outlined" />
</FormControl>
<FormControl sx={{ margin: 2 }}>
<TextField id="outlined-basic" label="Location" variant="outlined" />
</FormControl>
<FormControl sx={{ margin: 2 }}>
<TextField id="outlined-basic" label="Radius" variant="outlined" />
</FormControl>
</div>
);
}

View File

@@ -0,0 +1,4 @@
h1, h2{
-webkit-text-stroke-width: 1px;
-webkit-text-stroke-color: black;
}

View File

@@ -0,0 +1,46 @@
import * as React from 'react';
import Homebar from './Homebar';
import { Carousel } from 'react-bootstrap';
import './Home.css';
export default function Home() {
return(
<React.Fragment>
<Homebar></Homebar>
<Carousel>
<Carousel.Item>
<img
src='https://d39l2hkdp2esp1.cloudfront.net/img/photo/148976/148976_00_2x.jpg'
alt="Connect Slide"
style={{ height: '680px', width: '2000px'}}
/>
<Carousel.Caption>
<h1>Connect</h1>
<h2>Connect with other athletes in your area!</h2>
</Carousel.Caption>
</Carousel.Item>
<Carousel.Item>
<img
src='https://www.groovypost.com/wp-content/uploads/2021/08/sports-calendar-featured.jpg'
alt="Schedule Slide"
style={{ height: '680px', width: '2000px' }}
/>
<Carousel.Caption>
<h1>Schedule</h1>
<h2>Schedule sport meets with other athletes!</h2>
</Carousel.Caption>
</Carousel.Item>
<Carousel.Item>
<img
src='https://i.pinimg.com/736x/dd/80/c3/dd80c3136a96c2fbf6004aef8e9619f3.jpg'
alt="Rent Slide"
style={{ height: '680px', width: '2000px' }}
/>
<Carousel.Caption>
<h1>Rent</h1>
<h2>Rent sports equipment from other athletes!</h2>
</Carousel.Caption>
</Carousel.Item>
</Carousel>
</React.Fragment>
)
}

View File

@@ -0,0 +1,44 @@
import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import Button from '@mui/material/Button';
import { useNavigate } from 'react-router-dom';
export default function Navbar(){
const navigate = useNavigate();
return (
<AppBar position="static" sx={{background: '#00226D'}}>
<Container maxWidth="xl">
<Toolbar disableGutters>
<Typography
variant="h6"
noWrap
component="div"
sx={{ mr: 2, fontSize: '200%', textAlign: 'center', flexGrow: 1, marginLeft: '10%'}}
>
Sports Matcher
</Typography>
<Box sx={{display: { xs: 'none', md: 'flex' }}}>
<Button
sx={{ my: 2, color: 'white', display: 'block', textTransform: 'none', fontSize: '100%'}}
onClick={() => navigate('sign-up')}
>
Sign Up
</Button>
<Button
sx={{ my: 2, color: 'white', display: 'block', textTransform: 'none', fontSize: '100%'}}
onClick={() => navigate('sign-in')}
>
Sign In
</Button>
</Box>
</Toolbar>
</Container>
</AppBar>
);
};

View File

@@ -0,0 +1,31 @@
import * as React from 'react';
import ListItem from '@mui/material/ListItem';
import ListItemText from '@mui/material/ListItemText';
import Typography from '@mui/material/Typography';
import SportsTennisIcon from '@mui/icons-material/SportsTennis';
import { Button, ListItemIcon } from '@mui/material';
export default function ListSuggestedMatch() {
return (<ListItem alignItems="flex-start">
<ListItemIcon>
<SportsTennisIcon />
</ListItemIcon>
<ListItemText
primary="Tennis - King of The Court"
secondary={
<React.Fragment>
<Typography
sx={{ display: 'inline' }}
component="span"
variant="body2"
color="text.primary"
>
12:30PM - 123 Alphabet St. Toronto ON.
</Typography>
{" — John Smith, Alfred Baker, and Samantha Wright"}
<Button size="Medium">Participate</Button>
</React.Fragment>
}
/>
</ListItem>);
}

View File

@@ -0,0 +1,19 @@
import * as React from 'react';
import List from '@mui/material/List';
import Divider from '@mui/material/Divider';
import ListSuggestedMatch from './ListSuggestedMatch';
export default function MatchesList() {
return (
<List sx={{ width: '100%' }}>
<ListSuggestedMatch></ListSuggestedMatch>
<Divider variant="inset" component="li" />
<ListSuggestedMatch></ListSuggestedMatch>
<Divider variant="inset" component="li" />
<ListSuggestedMatch></ListSuggestedMatch>
<Divider variant="inset" component="li" />
<ListSuggestedMatch></ListSuggestedMatch>
<Divider variant="inset" component="li" />
</List>
);
}

View File

@@ -0,0 +1,150 @@
import * as React from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
import IconButton from '@mui/material/IconButton';
import Typography from '@mui/material/Typography';
import Menu from '@mui/material/Menu';
import MenuIcon from '@mui/icons-material/Menu';
import Container from '@mui/material/Container';
import Button from '@mui/material/Button';
import Tooltip from '@mui/material/Tooltip';
import MenuItem from '@mui/material/MenuItem';
import AccountCircle from '@mui/icons-material/AccountCircle';
import ForumIcon from '@mui/icons-material/Forum';
import { useNavigate } from 'react-router-dom';
const pages = ['Dashboard'];
export default function Navbar() {
const [anchorElNav, setAnchorElNav] = React.useState(null);
const [anchorElUser, setAnchorElUser] = React.useState(null);
const handleOpenNavMenu = (event) => {
setAnchorElNav(event.currentTarget);
};
const handleOpenUserMenu = (event) => {
setAnchorElUser(event.currentTarget);
};
const handleCloseNavMenu = () => {
setAnchorElNav(null);
};
const handleCloseUserMenu = () => {
setAnchorElUser(null);
};
const navigate = useNavigate();
return (
<AppBar position="static" sx={{ background: '#00226D' }}>
<Container maxWidth="xl">
<Toolbar disableGutters>
<Typography
variant="h6"
noWrap
component="div"
sx={{ mr: 2, display: { xs: 'none', md: 'flex' }, fontSize: '150%', borderRight: '0.05em solid black', borderColor: 'white', paddingRight: '1.5em' }}
>
Sports Matcher
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}>
<IconButton
size="large"
aria-label="account of current user"
aria-controls="menu-appbar"
aria-haspopup="true"
onClick={handleOpenNavMenu}
color="inherit"
>
<MenuIcon />
</IconButton>
<Menu
id="menu-appbar"
anchorEl={anchorElNav}
anchorOrigin={{
vertical: 'bottom',
horizontal: 'left',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'left',
}}
open={Boolean(anchorElNav)}
onClose={handleCloseNavMenu}
sx={{
display: { xs: 'block', md: 'none' },
}}
>
{pages.map((page) => (
<MenuItem key={page} onClick={handleCloseNavMenu}>
<Typography textAlign="center">{page}</Typography>
</MenuItem>
))}
</Menu>
</Box>
<Typography
variant="h6"
noWrap
component="div"
sx={{ flexGrow: 1, display: { xs: 'flex', md: 'none' } }}
>
Sports Matcher
</Typography>
<Box sx={{ flexGrow: 1, display: { xs: 'none', md: 'flex' }, marginLeft: '2%' }}>
<Button
onClick={() => { navigate("/dashboard") }}
sx={{ my: 2, color: 'white', display: 'block', textTransform: 'none', fontSize: '100%' }}
>
Dashboard
</Button>
</Box>
<Box sx={{ flexGrow: 0, marginRight: '1%' }}>
<Tooltip title="Chats">
<IconButton onClick={() => { navigate('/chat-window') }} sx={{ p: 0 }}>
<ForumIcon sx={{ color: 'white' }}></ForumIcon>
</IconButton>
</Tooltip>
</Box>
<Box sx={{ flexGrow: 0 }}>
<Tooltip title="Settings">
<IconButton onClick={handleOpenUserMenu} sx={{ p: 0 }}>
<AccountCircle sx={{ color: 'white' }}></AccountCircle>
</IconButton>
</Tooltip>
<Menu
sx={{ mt: '30px' }}
id="menu-appbar"
anchorEl={anchorElUser}
anchorOrigin={{
vertical: 'top',
horizontal: 'right',
}}
keepMounted
transformOrigin={{
vertical: 'top',
horizontal: 'right',
}}
open={Boolean(anchorElUser)}
onClose={handleCloseUserMenu}
>
<MenuItem onClick={handleCloseUserMenu}>
<Typography textAlign="center">Profile</Typography>
</MenuItem>
<MenuItem onClick={handleCloseUserMenu}>
<Typography textAlign="center">Account</Typography>
</MenuItem>
<MenuItem onClick={() => navigate('/sign-in')}>
<Typography textAlign="center">Sign Out</Typography>
</MenuItem>
</Menu>
</Box>
</Toolbar>
</Container>
</AppBar>
);
};

View File

@@ -0,0 +1,21 @@
import FormControl from "@mui/material/FormControl";
import OutlinedInput from "@mui/material/OutlinedInput";
import TextField from "@mui/material/TextField";
export default function ReportForm() {
return (
<FormControl sx={{ width: '80%' }}>
<OutlinedInput
sx={{ margin: 1 }}
placeholder="Please enter user email." />
<TextField
id="outlined-multiline-static"
label="Multiline"
multiline
rows={5}
sx={{ margin: 1 }}
defaultValue="Reason for suspension..."
/>
</FormControl>
);
}

View File

@@ -0,0 +1,10 @@
import { Button, TextField } from "@mui/material";
export default function SearchBar() {
return (
<div>
<TextField sx={{ margin: 1 }} id="standard-basic" label="Search" variant="outlined" />
<Button sx={{ margin: 1 }} variant="outlined">Search</Button>
</div>
);
}

View File

@@ -8,58 +8,73 @@ import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container'; import Container from '@mui/material/Container';
import { Link } from '@mui/material'; import { Link } from '@mui/material';
import AccountCircleIcon from '@mui/icons-material/AccountCircle'; import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import { useNavigate } from 'react-router-dom';
export default function SignIn() { export default function SignIn() {
const navigate = useNavigate();
const handleSubmit = (event) => {
event.preventDefault();
// For Phase 1, we have hardcoded the usernames and passwords as specified in the handout
// For the upcoming phases, this will be changed to secure authentication
const data = new FormData(event.currentTarget);
// eslint-disable-next-line no-console
if (data.get('username') === "admin" && data.get('password') === "admin") {
navigate('/admin');
} else if (data.get('username') === "user" && data.get('password') === "user") {
navigate('/chat-window')
}
};
return ( return (
<Container component="main" maxWidth="xs"> <Container component="main" maxWidth="xs">
<CssBaseline /> <CssBaseline />
<Box <Box
sx={{ sx={{
marginTop: 8, marginTop: 8,
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
alignItems: 'center', alignItems: 'center',
}} }}
> >
<Avatar sx={{ m: 1, bgcolor: 'primary.main' }}> <Avatar sx={{ m: 1, bgcolor: 'primary.main' }}>
<AccountCircleIcon /> <AccountCircleIcon />
</Avatar> </Avatar>
<Typography component="h1" variant="h5"> <Typography component="h1" variant="h5">
Sign in Sign in
</Typography> </Typography>
<Box component="form" noValidate sx={{ mt: 1 }}> <Box component="form" noValidate sx={{ mt: 1 }} onSubmit={handleSubmit}>
<TextField <TextField
margin="normal" margin="normal"
required required
fullWidth fullWidth
id="email" id="username"
label="Email Address" label="Username"
name="email" name="username"
autoComplete="email" autoComplete="username"
autoFocus autoFocus
/> />
<TextField <TextField
margin="normal" margin="normal"
required required
fullWidth fullWidth
name="password" name="password"
label="Password" label="Password"
type="password" type="password"
id="password" id="password"
autoComplete="current-password" autoComplete="current-password"
/> />
<Button <Button
type="submit" type="submit"
fullWidth fullWidth
variant="contained" variant="contained"
sx={{ mt: 3, mb: 2 }} sx={{ mt: 3, mb: 2 }}
> >
Sign In Sign In
</Button> </Button>
<Link href="/sign-up" underline="always"> <Link href="/sign-up" underline="always">
{"Don't have an account?"} {"Don't have an account?"}
</Link> </Link>
</Box> </Box>
</Box> </Box>
</Container> </Container>
)} )
}

View File

@@ -9,6 +9,7 @@ import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container'; import Container from '@mui/material/Container';
import { Link } from '@mui/material'; import { Link } from '@mui/material';
import { Grid } from '@mui/material'; import { Grid } from '@mui/material';
import { useNavigate } from 'react-router-dom';
export default function SignUp() { export default function SignUp() {
return ( return (

View File

@@ -0,0 +1,27 @@
import * as React from 'react';
import Avatar from '@mui/material/Avatar';
import Button from '@mui/material/Button';
import CssBaseline from '@mui/material/CssBaseline';
import TextField from '@mui/material/TextField';
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { Link } from '@mui/material';
import AccountCircleIcon from '@mui/icons-material/AccountCircle';
import Filter from "./Filter";
import SearchBar from "./SearchBar";
import { useNavigate } from 'react-router-dom';
import MatchesList from './MatchesList';
import Navbar from './Navbar';
export default function UserDashboard() {
const navigate = useNavigate();
return (
<div>
<Navbar></Navbar>
<SearchBar></SearchBar>
<Filter></Filter>
<MatchesList></MatchesList>
</div>
);
}

View File

@@ -0,0 +1,109 @@
/* Please direct questions to Hansi Xu (Wallace LaWall on Discord) */
.chatcomponent > * {
display: inline-block;
}
.contact {
border-style: solid;
border-width: 1px;
border-bottom: 1px;
border-color:rgb(75, 75, 75);
background-color: rgb(80, 80, 80);
height: 80px;
user-select: none;
}
.contact.dark {
background-color: black;
}
.contactlist {
height: 90%;
width: 13%;
top: 10%;
left: 0;
box-sizing: border-box;
border-radius: 2%;
background: rgb(48, 45, 45);
overflow-y: scroll;
overflow-x: hidden;
position: absolute;
text-align: center;
}
.messagelist {
height: 70%;
width: 87%;
top: 10%;
left: 13%;
position: absolute;
background-color: rgb(80, 80, 80);
overflow-x: hidden;
overflow-y: scroll;
}
.messagelist > * {
display: block;
}
.profilepiccontainer {
height: 60px;
width: 60px;
margin-top: 10px;
margin-left: 10px;
margin-right: 10px;
float: left;
}
.profilepic {
border-radius: 50%;
height: 50px;
width: 50px;
}
.profilenamecontainer {
text-align: center;
padding: 7%;
}
.profilename {
color: white;
}
.chatbubble {
margin-top: 20px;
margin-left: 20px;
display: inline-block;
position: relative;
width: auto;
height: auto;
padding: 10px;
border-radius: 10px;
}
.left {
background-color: rgba(0, 57, 163, 0.637);
margin-left: 20px;
color: white;
float: left;
}
.right {
background-color: khaki;
color: black;
margin-right: 20px;
float: right;
}
.chatbubble-container {
width: 100%;
height: auto;
float: left;
}
.chatinput {
background-color: rgb(75, 75, 75);
top: 80%;
left: 13%;
position: absolute;
height: 20%;
width: 87%;
color: antiquewhite;
border-width: 2px;
border-color: rgb(48, 45, 45);
}

View File

@@ -0,0 +1,54 @@
import * as React from 'react';
import Card from '@mui/material/Card';
import { List, ListItemAvatar } from '@mui/material';
import { ListItem } from '@mui/material';
import { ListItemText } from '@mui/material';
import PeopleIcon from '@mui/icons-material/People';
import SportsIcon from '@mui/icons-material/Sports';
import MapIcon from '@mui/icons-material/Map';
import EventIcon from '@mui/icons-material/Event';
import CardActions from '@mui/material/CardActions';
import CardContent from '@mui/material/CardContent';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
export default function MatchInfo() {
return (
<Card sx={{ maxWidth: 400 }}>
<CardContent>
<Typography sx={{ fontSize: 24 }} component="div">
King of the Court!
</Typography>
<List>
<ListItem>
<ListItemAvatar>
<SportsIcon />
</ListItemAvatar>
<ListItemText primary="Sport" secondary="Tennis" />
</ListItem>
<ListItem>
<ListItemAvatar>
<PeopleIcon />
</ListItemAvatar>
<ListItemText primary="Participants" secondary="John Smith, Bob Williams, and Candice Baker" />
</ListItem>
<ListItem>
<ListItemAvatar>
<MapIcon />
</ListItemAvatar>
<ListItemText primary="Location" secondary="Athletic Center - 55 Harbord St, Toronto, ON M5S 2W6" />
</ListItem>
<ListItem>
<ListItemAvatar>
<EventIcon />
</ListItemAvatar>
<ListItemText primary="Time" secondary="1:00PM Tomorrow (January 13th)" />
</ListItem>
</List>
</CardContent>
<CardActions>
<Button size="Medium">Participate</Button>
</CardActions>
</Card>
);
}