30 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
Sahni-Arjun
ae1c05c944 admin functionality 2022-03-06 20:49:04 -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
Piyush Sharma
4c75dc2c75 Cleaned up files 2022-03-05 18:51:36 -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
Piyush Sharma
1b86e6260f Added Routing and Sign in/up Pages 2022-03-01 13:32:42 -05:00
26 changed files with 1008 additions and 27600 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.

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "team58",
"lockfileVersion": 2,
"requires": true,
"packages": {}
}

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

@@ -3,11 +3,18 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@emotion/react": "^11.8.1",
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.4.4",
"@mui/material": "^5.4.4",
"@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-scripts": "^5.0.0", "react-scripts": "^5.0.0",
"web-vitals": "^2.1.4" "web-vitals": "^2.1.4"
}, },

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>

View File

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

258
sports-matcher/src/Admin.js Normal file
View File

@@ -0,0 +1,258 @@
import * as React from 'react';
import './Admin.css';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { TableContainer, TableCell, Table, TableBody, TableRow, TableHead, Paper } from '@mui/material';
import Navbar from './Navbar';
class AdminTable extends React.Component {
constructor(props) {
super(props)
this.state = {
users: [
{ id: 1, username: 'username1', name: 'name1', email: 'user1@email.com', phone: '123-456-7890' },
{ id: 2, username: 'username2', name: 'name2', email: 'user2@email.com', phone: '123-456-7890' },
{ id: 3, username: 'username3', name: 'name3', email: 'user3@email.com', phone: '123-456-7890' },
{ id: 4, username: 'username4', name: 'name4', email: 'user4@email.com', phone: '123-456-7890' }
],
suspendedUsers: [
{ id: 1, username: 'suspended1', name: 's1', email: 's1@email.com', phone: '123-456-7890' },
{ id: 2, username: 'suspended2', name: 's2', email: 's2@email.com', phone: '123-456-7890' },
{ id: 3, username: 'suspended3', name: 's3', email: 's3@email.com', phone: '123-456-7890' },
{ id: 4, username: 'suspended4', name: 's4', email: 's4@email.com', phone: '123-456-7890' }
],
matches: [
{ id: 1, sport: "Tennis", date: '08/08/2021', location: 'toronto', description: 'Tennis match' },
{ id: 2, sport: "Basketball", date: '09/09/2021', location: 'toronto', description: 'Basketball match' }
],
buttonColors: ['black', '', '']
}
}
editButton() {
return <Button onClick={() => {
alert('clicked');
}} variant="contained">Edit</Button>;
}
deleteButtonClick() {
return (
<Container component="main" maxWidth="xs">
<Typography>Are you sure you want to delete this user?</Typography>
<Button onClick={() => {
alert('User deleted');
}} variant="contained">Yes</Button>
</Container>
)
}
newDeleteButtonClick() {
return (<form onsubmit="console.log('You clicked submit.'); return false">
<button type="submit">Submit</button>
</form>)
}
deleteButton() {
return <Button onClick={() => {
alert('User deleted.');
}} variant="contained">Delete</Button>;
}
matchDeleteButton() {
return <Button onClick={() => {
alert('Match deleted.');
}} variant="contained">Delete</Button>;
}
pardonButton() {
return <Button onClick={() => {
alert('User pardoned.');
}} variant="contained">Pardon</Button>;
}
userTableData() {
return this.state.users.map((user) => {
const { id, username, name, email, phone } = user;
return (
<TableRow>
<TableCell>{id}</TableCell>
<TableCell>{username}</TableCell>
<TableCell>{name}</TableCell>
<TableCell>{email}</TableCell>
<TableCell>{phone}</TableCell>
<TableCell>{this.deleteButton()}</TableCell>
<TableCell>{this.editButton()}</TableCell>
</TableRow>
)
})
}
suspendedUserTableData() {
return this.state.suspendedUsers.map((user) => {
const { id, username, name, email, phone } = user
return (
<TableRow>
<TableCell>{id}</TableCell>
<TableCell>{username}</TableCell>
<TableCell>{name}</TableCell>
<TableCell>{email}</TableCell>
<TableCell>{phone}</TableCell>
<TableCell>{this.deleteButton()}</TableCell>
<TableCell>{this.editButton()}</TableCell>
<TableCell>{this.pardonButton()}</TableCell>
</TableRow>
)
})
}
matchTableData() {
return this.state.matches.map((match) => {
const { id, sport, date, location, description } = match
return (
<TableRow>
<TableCell>{id}</TableCell>
<TableCell>{sport}</TableCell>
<TableCell>{date}</TableCell>
<TableCell>{location}</TableCell>
<TableCell>{description}</TableCell>
<TableCell>{this.matchDeleteButton()}</TableCell>
<TableCell>{this.editButton()}</TableCell>
</TableRow>
)
})
}
matchTableHead() {
return (
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Sport</TableCell>
<TableCell>Date</TableCell>
<TableCell>Location</TableCell>
<TableCell>Description</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
);
}
suspendedUserTableHead() {
return (
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Username</TableCell>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Phone</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
);
}
userTableHead() {
return (
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Username</TableCell>
<TableCell>Name</TableCell>
<TableCell>Email</TableCell>
<TableCell>Phone</TableCell>
<TableCell></TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
);
}
selectTable() {
this.setState({ buttonColors: ['', '', ''] });
}
renderTableHead() {
if (this.state.buttonColors[0] === 'black') {
return this.matchTableHead();
} else if (this.state.buttonColors[1] === 'black') {
return this.userTableHead();
} else {
return this.suspendedUserTableHead();
}
}
renderTableData() {
if (this.state.buttonColors[0] === 'black') {
return this.matchTableData();
} else if (this.state.buttonColors[1] === 'black') {
return this.userTableData();
} else {
return this.suspendedUserTableData();
}
}
render() {
return (
<div>
<Navbar></Navbar>
<h1 className='Title'>Administration</h1>
<div className='ButtonList'>
<Button onClick={() => {
this.setState({ buttonColors: ['black', '', ''] });
}} sx={{
margin: 3,
backgroundColor: this.state.buttonColors[0],
}} variant="outlined">Matches</Button>
<Button onClick={() => {
this.setState({ buttonColors: ['', 'black', ''] });
}} sx={{
margin: 3,
backgroundColor: this.state.buttonColors[1],
}} variant="outlined">Users</Button>
<Button onClick={() => {
this.setState({ buttonColors: ['', '', 'black'] });
}} sx={{
margin: 3,
backgroundColor: this.state.buttonColors[2],
}} variant="outlined">Suspended Users</Button></div>
<div className='MainTable'>
<TableContainer
component={Paper}
variant="outlined"
>
<Table>
{this.renderTableHead()}
<TableBody>
{this.renderTableData()}
</TableBody>
</Table>
</TableContainer>
</div>
</div>
)
}
}
export default AdminTable

View File

@@ -1,23 +1,23 @@
import logo from './logo.svg';
import './App.css'; import './App.css';
import { Routes, Route, Link } from "react-router-dom";
import SignIn from './SignIn';
import SignUp from './SignUp';
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">
<header className="App-header"> <Routes>
<img src={logo} className="App-logo" alt="logo" /> <Route path="" element={<Home />} />
<p> <Route path="dashboard" element={<UserDashboard />} />
Edit <code>src/App.js</code> and save to reload. <Route path="sign-in" element={<SignIn />} />
</p> <Route path="sign-up" element={<SignUp />} />
<a <Route path="admin" element={<Admin />} />
className="App-link" <Route path="chat-window" element={<ChatWindow />} />
href="https://reactjs.org" </Routes>
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</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

@@ -5,11 +5,13 @@ import './chats.css'
import Chat from './Chat' import Chat from './Chat'
import Contact from './Contact' import Contact from './Contact'
import { useState } from "react"; import { useState } from "react";
import Navbar from './Navbar';
class ChatWindow extends React.Component { class ChatWindow extends React.Component {
render() { render() {
return ( return (
<div class="chatcomponent"> <div class="chatcomponent">
<Navbar></Navbar>
<UserList /> <UserList />
<MessageList /> <MessageList />
<ChatInput /> <ChatInput />

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

@@ -0,0 +1,80 @@
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 { useNavigate } from 'react-router-dom';
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 (
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'primary.main' }}>
<AccountCircleIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<Box component="form" noValidate sx={{ mt: 1 }} onSubmit={handleSubmit}>
<TextField
margin="normal"
required
fullWidth
id="username"
label="Username"
name="username"
autoComplete="username"
autoFocus
/>
<TextField
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
Sign In
</Button>
<Link href="/sign-up" underline="always">
{"Don't have an account?"}
</Link>
</Box>
</Box>
</Container>
)
}

View File

@@ -0,0 +1,92 @@
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 AccountBoxIcon from '@mui/icons-material/AccountBox';
import Typography from '@mui/material/Typography';
import Container from '@mui/material/Container';
import { Link } from '@mui/material';
import { Grid } from '@mui/material';
import { useNavigate } from 'react-router-dom';
export default function SignUp() {
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<Box
sx={{
marginTop: 8,
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
}}
>
<Avatar sx={{ m: 1, bgcolor: 'info.main' }}>
<AccountBoxIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign up
</Typography>
<Box component="form" noValidate sx={{ mt: 1 }}>
<Grid container spacing={2}>
<Grid item xs={12} sm={6}>
<TextField
autoComplete="given-name"
name="firstName"
required
fullWidth
id="firstName"
label="First Name"
autoFocus
/>
</Grid>
<Grid item xs={12} sm={6}>
<TextField
required
fullWidth
id="lastName"
label="Last Name"
name="lastName"
autoComplete="family-name"
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
/>
</Grid>
<Grid item xs={12}>
<TextField
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="new-password"
/>
</Grid>
</Grid>
<Button
type="submit"
fullWidth
variant="contained"
color='info'
sx={{ mt: 3, mb: 2 }}
>
Sign Up
</Button>
<Link href="/sign-in" underline="always">
{'Already have an account?'}
</Link>
</Box>
</Box>
</Container>
)}

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

@@ -10,7 +10,7 @@
border-color:rgb(75, 75, 75); border-color:rgb(75, 75, 75);
background-color: rgb(80, 80, 80); background-color: rgb(80, 80, 80);
height: 70px; height: 80px;
user-select: none; user-select: none;
} }
@@ -18,9 +18,9 @@
background-color: black; background-color: black;
} }
.contactlist { .contactlist {
height: 500px; height: 90%;
width: 200px; width: 13%;
top: 0; top: 10%;
left: 0; left: 0;
box-sizing: border-box; box-sizing: border-box;
border-radius: 2%; border-radius: 2%;
@@ -28,13 +28,14 @@
overflow-y: scroll; overflow-y: scroll;
overflow-x: hidden; overflow-x: hidden;
position: absolute;
text-align: center; text-align: center;
} }
.messagelist { .messagelist {
height: 400px; height: 70%;
width: 800px; width: 87%;
top: 0px; top: 10%;
left: 200px; left: 13%;
position: absolute; position: absolute;
background-color: rgb(80, 80, 80); background-color: rgb(80, 80, 80);
@@ -77,29 +78,29 @@
} }
.left { .left {
background-color: rgba(0, 57, 163, 0.637); background-color: rgba(0, 57, 163, 0.637);
margin-right: 35px; margin-left: 20px;
color: white; color: white;
float: auto; float: left;
} }
.right { .right {
background-color: khaki; background-color: khaki;
color: black; color: black;
margin-right: 35px; margin-right: 20px;
float: right; float: right;
} }
.chatbubble-container { .chatbubble-container {
width: 800px; width: 100%;
height: auto; height: auto;
float: left; float: left;
} }
.chatinput { .chatinput {
background-color: rgb(75, 75, 75); background-color: rgb(75, 75, 75);
top: 400px; top: 80%;
left: 200px; left: 13%;
position: absolute; position: absolute;
height: 92px; height: 20%;
width: 793px; width: 87%;
color: antiquewhite; color: antiquewhite;

View File

@@ -1,13 +1,14 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import { BrowserRouter } from "react-router-dom";
import './index.css'; import './index.css';
import App from './App'; import App from './App';
import reportWebVitals from './reportWebVitals'; import reportWebVitals from './reportWebVitals';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <BrowserRouter>
<App /> <App />
</React.StrictMode>, </BrowserRouter>,
document.getElementById('root') document.getElementById('root')
); );

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>
);
}