Compare commits
	
		
			18 Commits
		
	
	
		
			restructur
			...
			admin_page
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					26abdd6aa5 | ||
| 
						 | 
					468f1cfa31 | ||
| 
						 | 
					7c8e37aea8 | ||
| c738e8044a | |||
| 499cbf3409 | |||
| 
						 | 
					54b01f81c5 | ||
| 30894c59c4 | |||
| 34bbfb3d5d | |||
| 
						 | 
					9f1df7f7f4 | ||
| 
						 | 
					1fd60e39d4 | ||
| 
						 | 
					c691b710b7 | ||
| 6cd421ba01 | |||
| 0a2d513d3c | |||
| bb911173ec | |||
| 
						 | 
					94d3369d4e | ||
| 
						 | 
					859147ea3d | ||
| 8492c82e4f | |||
| 
						 | 
					df2071439d | 
@@ -35,6 +35,7 @@
 | 
			
		||||
        "semi": [
 | 
			
		||||
            "error",
 | 
			
		||||
            "always"
 | 
			
		||||
        ]
 | 
			
		||||
        ],
 | 
			
		||||
        "no-unused-vars": "warn"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -8,6 +8,7 @@ import { Container, Nav, NavbarBrand } from "react-bootstrap";
 | 
			
		||||
import NavbarToggle from "react-bootstrap/esm/NavbarToggle";
 | 
			
		||||
import NavbarCollapse from "react-bootstrap/esm/NavbarCollapse";
 | 
			
		||||
import Dashboard from "./pages/Dashboard";
 | 
			
		||||
import Admin from "./pages/NewAdmin";
 | 
			
		||||
import Login from "./pages/Login";
 | 
			
		||||
import { apiClient } from "./utils/httpClients";
 | 
			
		||||
import { globalContext } from "./context.js";
 | 
			
		||||
@@ -80,6 +81,7 @@ export default function layout() {
 | 
			
		||||
                        <Route path="/" element={<Welcome />} />
 | 
			
		||||
                        <Route path="/dashboard" element={<Dashboard />} />
 | 
			
		||||
                        <Route path="/login" element={<Login />} />
 | 
			
		||||
                        <Route path="/admin" element={<Admin />} />
 | 
			
		||||
                    </Routes>
 | 
			
		||||
                </main>
 | 
			
		||||
                <footer>
 | 
			
		||||
 
 | 
			
		||||
@@ -13,7 +13,7 @@ export default class SportInfoCard extends React.Component {
 | 
			
		||||
                    <Card.Title>{this.props.sport.name}</Card.Title>
 | 
			
		||||
                    <Card.Subtitle className="mb-2 text-muted">{this.props.sport.minPlayers.toString()}</Card.Subtitle>
 | 
			
		||||
                    <Card.Text>
 | 
			
		||||
                        <p>{this.props.sport.description}</p>
 | 
			
		||||
                        {this.props.sport.description}
 | 
			
		||||
                    </Card.Text>
 | 
			
		||||
                </Card.Body>
 | 
			
		||||
            </Card>
 | 
			
		||||
 
 | 
			
		||||
@@ -8,7 +8,7 @@ export default class SportInfoCardDisplay extends React.Component {
 | 
			
		||||
    }
 | 
			
		||||
    render() {
 | 
			
		||||
        let sports = null;
 | 
			
		||||
        if(this.props.recommendedsports && this.props.recommendedsports.length > 0) {
 | 
			
		||||
        if (this.props.recommendedsports.length > 0) {
 | 
			
		||||
            sports = this.props.recommendedsports.map((sport) => <SportInfoCard key={sport._id} sport={sport}></SportInfoCard>);
 | 
			
		||||
        }
 | 
			
		||||
        return (
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,9 @@ import "../styles/Dashboard.css";
 | 
			
		||||
import { apiClient } from "../utils/httpClients.js";
 | 
			
		||||
import MatchInfoCardDisplay from "../components/MatchInfoCardDisplay";
 | 
			
		||||
import SportInfoCardDisplay from "../components/SportInfoCardDisplay";
 | 
			
		||||
// import { needUser } from "../utils/routing.js";
 | 
			
		||||
import { globalContext } from "../context";
 | 
			
		||||
import { needUser } from "../utils/routing";
 | 
			
		||||
 | 
			
		||||
export default class Dashboard extends React.Component {
 | 
			
		||||
    constructor(props) {
 | 
			
		||||
        super(props);
 | 
			
		||||
@@ -14,16 +16,14 @@ export default class Dashboard extends React.Component {
 | 
			
		||||
            displayedEquipment: [],
 | 
			
		||||
            user: null
 | 
			
		||||
        };
 | 
			
		||||
        // this.getFirstName();
 | 
			
		||||
    }
 | 
			
		||||
    // async componentDidMount() {
 | 
			
		||||
    //     this.setState({ user: await needUser() }); // needUser says this page needs a user, and therefore, if there isn't a user, get them to login first. It returns the authenticated user.
 | 
			
		||||
    //     this.setState({ displayedMatches: await this.latestMatches() });
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    static contextType = globalContext;
 | 
			
		||||
 | 
			
		||||
    async componentDidMount() {
 | 
			
		||||
        await needUser(this.context.navigate);
 | 
			
		||||
        await this.latestMatches();
 | 
			
		||||
        await this.availableSports();
 | 
			
		||||
        // await this.availableEquipment();
 | 
			
		||||
    }
 | 
			
		||||
    async latestMatches() {
 | 
			
		||||
        let recentMatchesRes = await apiClient.get("/match/recent/15");
 | 
			
		||||
@@ -35,23 +35,10 @@ export default class Dashboard extends React.Component {
 | 
			
		||||
    async availableSports() {
 | 
			
		||||
        let availableSportsRes = await apiClient.get("/sport");
 | 
			
		||||
        if (availableSportsRes.status === 200) {
 | 
			
		||||
            this.setState({ displayedSports: availableSportsRes.data.recent });
 | 
			
		||||
            this.setState({ displayedSports: availableSportsRes.data });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // async availableEquipment() {
 | 
			
		||||
    //     let availableEquipmentRes = await apiClient.get("/rentals");
 | 
			
		||||
    //     if (availableEquipmentRes.status === 200) {
 | 
			
		||||
    //         this.setState({ displayedEquipment: availableEquipmentRes.data.recent });
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // async getFirstName() {
 | 
			
		||||
    //     // let result = await apiClient.post("/user/login", {"email": "johndoe@gmail.com", "password": "csc309h1"}).then(apiClient.get("/user"));
 | 
			
		||||
    //     let user = await apiClient.get("/user");
 | 
			
		||||
    //     let tags = document.getElementsByTagName("h1");
 | 
			
		||||
    //     tags[0].innerHTML = user.firstName;
 | 
			
		||||
    // }
 | 
			
		||||
    render() {
 | 
			
		||||
        return (
 | 
			
		||||
            <React.Fragment>
 | 
			
		||||
@@ -74,10 +61,7 @@ export default class Dashboard extends React.Component {
 | 
			
		||||
                    <h2>Available Sports</h2>
 | 
			
		||||
                    <SportInfoCardDisplay recommendedsports={this.state.displayedSports} />
 | 
			
		||||
                </div>
 | 
			
		||||
                {/* <div className="p-4">
 | 
			
		||||
                    <h2>Available Equipment</h2>
 | 
			
		||||
                    <MatchInfoCardDisplay recommendedmatches={this.state.displayedEquipment} />
 | 
			
		||||
                </div> */}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            </React.Fragment>
 | 
			
		||||
        );
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										219
									
								
								sports-matcher/client/src/pages/NewAdmin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								sports-matcher/client/src/pages/NewAdmin.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,219 @@
 | 
			
		||||
import React from "react";
 | 
			
		||||
import { Button, Table } from "react-bootstrap";
 | 
			
		||||
import "../styles/Admin.css";
 | 
			
		||||
import { globalContext } from "../context";
 | 
			
		||||
import { needUser } from "../utils/routing";
 | 
			
		||||
//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 { apiClient } from "../utils/httpClients.js";
 | 
			
		||||
// import MatchInfoCardDisplay from "../components/MatchInfoCardDisplay";
 | 
			
		||||
// import { needUser } from "../utils/routing.js";
 | 
			
		||||
export default class Admin 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", "", ""],
 | 
			
		||||
            user: null
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static contextType = globalContext;
 | 
			
		||||
 | 
			
		||||
    async componentDidMount() {
 | 
			
		||||
        await needUser(this.context.navigate);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    DeleteButton() {
 | 
			
		||||
        return <Button onClick={() => {
 | 
			
		||||
            alert("User deleted.");
 | 
			
		||||
        }} variant="outline-secondary">Delete</Button>;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PardonButton() {
 | 
			
		||||
        return <Button onClick={() => {
 | 
			
		||||
            alert("User pardoned.");
 | 
			
		||||
        }} variant="outline-secondary">Pardon</Button>;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    EditButton() {
 | 
			
		||||
        return <Button onClick={() => {
 | 
			
		||||
            alert("clicked");
 | 
			
		||||
        }} variant="outline-secondary">Edit</Button>;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    userTableHead() {
 | 
			
		||||
        return (
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th>ID</th>
 | 
			
		||||
                    <th>Username</th>
 | 
			
		||||
                    <th>Name</th>
 | 
			
		||||
                    <th>Email</th>
 | 
			
		||||
                    <th>Phone</th>
 | 
			
		||||
                    <th></th>
 | 
			
		||||
                    <th></th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    matchTableHead() {
 | 
			
		||||
        return (
 | 
			
		||||
            <thead>
 | 
			
		||||
                <tr>
 | 
			
		||||
                    <th>ID</th>
 | 
			
		||||
                    <th>Sport</th>
 | 
			
		||||
                    <th>Date</th>
 | 
			
		||||
                    <th>Location</th>
 | 
			
		||||
                    <th>Description</th>
 | 
			
		||||
                    <th></th>
 | 
			
		||||
                    <th></th>
 | 
			
		||||
                </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    userTableData() {
 | 
			
		||||
        return this.state.users.map((user) => {
 | 
			
		||||
            const { id, username, name, email, phone } = user;
 | 
			
		||||
            return (
 | 
			
		||||
                <tr key={id}>
 | 
			
		||||
                    <td>{id}</td>
 | 
			
		||||
                    <td>{username}</td>
 | 
			
		||||
                    <td>{name}</td>
 | 
			
		||||
                    <td>{email}</td>
 | 
			
		||||
                    <td>{phone}</td>
 | 
			
		||||
                    <td>{this.DeleteButton()}</td>
 | 
			
		||||
                    <td>{this.EditButton()}</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    susUserTableData() {
 | 
			
		||||
        return this.state.suspendedUsers.map((user) => {
 | 
			
		||||
            const { id, username, name, email, phone } = user;
 | 
			
		||||
            return (
 | 
			
		||||
                <tr key={id}>
 | 
			
		||||
                    <td>{id}</td>
 | 
			
		||||
                    <td>{username}</td>
 | 
			
		||||
                    <td>{name}</td>
 | 
			
		||||
                    <td>{email}</td>
 | 
			
		||||
                    <td>{phone}</td>
 | 
			
		||||
                    <td>{this.DeleteButton()}</td>
 | 
			
		||||
                    <td>{this.EditButton()}</td>
 | 
			
		||||
                    <td>{this.PardonButton()}</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    matchTableData() {
 | 
			
		||||
        return this.state.matches.map((match) => {
 | 
			
		||||
            const { id, sport, date, location, description } = match;
 | 
			
		||||
            return (
 | 
			
		||||
                <tr key={id}>
 | 
			
		||||
                    <td>{id}</td>
 | 
			
		||||
                    <td>{sport}</td>
 | 
			
		||||
                    <td>{date}</td>
 | 
			
		||||
                    <td>{location}</td>
 | 
			
		||||
                    <td>{description}</td>
 | 
			
		||||
                    <td>{this.DeleteButton()}</td>
 | 
			
		||||
                    <td>{this.EditButton()}</td>
 | 
			
		||||
                    <td>{this.PardonButton()}</td>
 | 
			
		||||
                </tr>
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    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.userTableHead();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    renderTableData() {
 | 
			
		||||
        if (this.state.buttonColors[0] === "black") {
 | 
			
		||||
            return this.matchTableData();
 | 
			
		||||
        } else if (this.state.buttonColors[1] === "black") {
 | 
			
		||||
            return this.userTableData();
 | 
			
		||||
        } else {
 | 
			
		||||
            return this.susUserTableData();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    render() {
 | 
			
		||||
        return (
 | 
			
		||||
            <React.Fragment>
 | 
			
		||||
 | 
			
		||||
                <div className='center'>
 | 
			
		||||
                    <h1 id='title'>Administration</h1>
 | 
			
		||||
                    <Button onClick={() => {
 | 
			
		||||
                        this.setState({ buttonColors: ["black", "", ""] });
 | 
			
		||||
                    }} sx={{
 | 
			
		||||
                        margin: 3,
 | 
			
		||||
                        backgroundColor: this.state.buttonColors[0],
 | 
			
		||||
                    }} variant="outline-secondary">Matches</Button>
 | 
			
		||||
                    <Button onClick={() => {
 | 
			
		||||
                        this.setState({ buttonColors: ["", "black", ""] });
 | 
			
		||||
                    }} sx={{
 | 
			
		||||
                        margin: 3,
 | 
			
		||||
                        backgroundColor: this.state.buttonColors[1],
 | 
			
		||||
                    }} variant="outline-secondary">Users</Button>
 | 
			
		||||
                    <Button onClick={() => {
 | 
			
		||||
                        this.setState({ buttonColors: ["", "", "black"] });
 | 
			
		||||
                    }} sx={{
 | 
			
		||||
                        margin: 3,
 | 
			
		||||
                        backgroundColor: this.state.buttonColors[2],
 | 
			
		||||
                    }} variant="outline-secondary">Suspended Users</Button></div>
 | 
			
		||||
                <Table striped bordered hover>
 | 
			
		||||
                    {this.renderTableHead()}
 | 
			
		||||
                    <tbody>
 | 
			
		||||
                        {this.renderTableData()}
 | 
			
		||||
                        {/* {this.matchUserTableData()} */}
 | 
			
		||||
                    </tbody>
 | 
			
		||||
                </Table>
 | 
			
		||||
 | 
			
		||||
            </React.Fragment>
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										15
									
								
								sports-matcher/client/src/styles/Admin.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								sports-matcher/client/src/styles/Admin.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
			
		||||
 | 
			
		||||
.MainTable {
 | 
			
		||||
    padding : 20px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.center {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    padding: 21px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.somespace {
 | 
			
		||||
    padding: 17px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1,7 +1,10 @@
 | 
			
		||||
import axios from "axios";
 | 
			
		||||
 | 
			
		||||
export const apiClient = axios.create({
 | 
			
		||||
    baseURL: process.env.REACT_APP_API_HOST + "/api/",
 | 
			
		||||
    baseURL: (process.env.REACT_APP_API_HOST || "") + "/api/",
 | 
			
		||||
    timeout: 5000,
 | 
			
		||||
    withCredentials: process.env.NODE_ENV === "development",
 | 
			
		||||
    validateStatus: function (status) {
 | 
			
		||||
        return status === 401 || status == 200;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
            4
 | 
			
		||||
        ],
 | 
			
		||||
        "linebreak-style": [
 | 
			
		||||
            "error",
 | 
			
		||||
            "warn",
 | 
			
		||||
            "unix"
 | 
			
		||||
        ],
 | 
			
		||||
        "quotes": [
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
        "semi": [
 | 
			
		||||
            "error",
 | 
			
		||||
            "always"
 | 
			
		||||
        ]
 | 
			
		||||
        ],
 | 
			
		||||
        "no-unused-vars": "warn"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user