From e17b09edad29706d8d78bfa77e3b4f1bcf012a3c Mon Sep 17 00:00:00 2001 From: ShahriarDhruvo Date: Thu, 12 Nov 2020 21:47:09 +0600 Subject: [PATCH 01/10] Room member's add/remove and pending req func handled --- frontend/src/components/Rooms/RoomMembers.jsx | 241 +++++++++++++++++- .../components/Rooms/Sections/Sections.jsx | 83 +++--- .../src/components/generic/CustomAlert.jsx | 2 +- .../src/components/generic/CustomModal.jsx | 43 ++-- server/items/migrations/0001_initial.py | 4 +- server/items/views/item_views.py | 2 +- server/sections/views.py | 2 +- server/server/settings.py | 20 +- 8 files changed, 320 insertions(+), 77 deletions(-) diff --git a/frontend/src/components/Rooms/RoomMembers.jsx b/frontend/src/components/Rooms/RoomMembers.jsx index 8dcdfe3..526ced3 100644 --- a/frontend/src/components/Rooms/RoomMembers.jsx +++ b/frontend/src/components/Rooms/RoomMembers.jsx @@ -1,5 +1,7 @@ import React, { useState, useEffect } from "react"; import CustomAlert from "../generic/CustomAlert"; +import CustomModal from "../generic/CustomModal"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; const RoomMembers = (props) => { const [status, setStatus] = useState(undefined); @@ -9,9 +11,11 @@ const RoomMembers = (props) => { teachers: [], students: [], }); + const [isCR, setIsCR] = useState(false); + const [pendingUsers, setPendingUsers] = useState([]); useEffect(() => { - const API_URL = `/api/v1/rooms/members/${props.room_pk}/`; + let API_URL = `/api/v1/rooms/members/${props.room_pk}/`; const loadData = async () => { let response = await fetch(API_URL, { @@ -22,14 +26,112 @@ const RoomMembers = (props) => { if (!response.ok) setStatus(data.detail); else setMembers(data[0]); + + // Pending user's list + API_URL = `/api/v1/rooms/pending_requests/${props.room_pk}/list/`; + + response = await fetch(API_URL, { + method: "GET", + }); + + data = await response.json(); + + if (!response.ok && response.status !== 404) setStatus(data.detail); + else if (response.status !== 404) setPendingUsers(data); }; loadData(); }, [props.room_pk]); + const handleAddPendingUser = (pending_request_pk, username, userstatus) => { + let API_URL = `/api/v1/rooms/add/${props.room_pk}/${userstatus}/${username}/`; + + const loadData = async () => { + let response = await fetch(API_URL, { + method: "PATCH", + }); + + let data = await response.json(); + + if (!response.ok) setStatus(data.detail); + + // Deleting from pending users list + API_URL = `/api/v1/rooms/pending_requests/${props.room_pk}/delete/${pending_request_pk}/`; + + response = await fetch(API_URL, { + method: "DELETE", + }); + + if (!response.ok) { + data = await response.json(); + setStatus(data.detail); + } + }; + + loadData(); + }; + + const handleRemovePendingUser = (pending_request_pk) => { + const API_URL = `/api/v1/rooms/pending_requests/${props.room_pk}/delete/${pending_request_pk}/`; + + const loadData = async () => { + const response = await fetch(API_URL, { + method: "DELETE", + }); + + if (!response.ok) { + const data = await response.json(); + setStatus(data.detail); + } + }; + + loadData(); + }; + + const handleAddMember = (username, userstatus) => { + let API_URL = `/api/v1/rooms/add/${props.room_pk}/${userstatus}/${username}/`; + + const loadData = async () => { + let response = await fetch(API_URL, { + method: "PATCH", + }); + + if (!response.ok) { + const data = await response.json(); + setStatus(data.detail); + } + }; + + loadData(); + }; + + const handleRemoveMember = (username, userstatus) => { + const API_URL = `/api/v1/rooms/remove/${props.room_pk}/${userstatus}/${username}/`; + + const loadData = async () => { + const response = await fetch(API_URL, { + method: "PATCH", + }); + + if (!response.ok) { + const data = await response.json(); + setStatus(data.detail); + } + }; + + loadData(); + }; + return (
- {status && } + {status && ( + } + /> + )}
Room's Members @@ -47,8 +149,22 @@ const RoomMembers = (props) => {
{members.teachers.map((teacher) => ( -
- {teacher} +
+
{teacher}
+ + {localStorage.getItem("status") !== "2" && ( + + handleRemoveMember(teacher, "teacher") + } + actionButtonClass="btn btn-outline-danger btn-sm mx-1" + modalBody={`Do you really want to remove ${teacher} from this room?`} + > + + + )}
))}
@@ -59,8 +175,42 @@ const RoomMembers = (props) => {
{members.class_representatives.map((class_representative) => ( -
- {class_representative} +
+
{class_representative}
+ + {localStorage.getItem("status") !== "2" && ( + + handleRemoveMember( + class_representative, + "class_representative" + ) + } + actionButtonClass="btn btn-outline-danger btn-sm mx-1" + modalBody={`Do you want to remove ${class_representative} from Class Representative's list?`} + > + RCR + + )} + + {localStorage.getItem("status") !== "2" && ( + + handleRemoveMember( + class_representative, + "student" + ) + } + actionButtonClass="btn btn-outline-danger btn-sm mx-1" + modalBody={`Do you really want to remove ${class_representative} from this room?`} + > + + + )}
))}
@@ -71,8 +221,83 @@ const RoomMembers = (props) => {
{members.students.map((student) => ( -
- {student} +
+
{student}
+ + {localStorage.getItem("status") !== "2" && ( + + handleAddMember( + student, + "class_representative" + ) + } + actionButtonClass="btn btn-outline-info btn-sm mx-1" + modalBody={`Do you want to add ${student} as a Class Representative of this room?`} + > + CR + + )} + + {(localStorage.getItem("status") !== "2" || isCR) && ( + + handleRemoveMember(student, "student") + } + actionButtonClass="btn btn-outline-danger btn-sm mx-1" + modalBody={`Do you really want to remove ${student} from this room?`} + > + + + )} +
+ ))} +
+ +
+ Pending Requests +
+ +
+ {pendingUsers.map((pendingUser) => ( +
+
{pendingUser.user}
+ + {(localStorage.getItem("status") !== "2" || isCR) && ( + + handleAddPendingUser( + pendingUser.id, + pendingUser.user, + pendingUser.user_status + ) + } + actionButtonClass="btn btn-outline-success btn-sm mx-1" + modalBody={`Do you want to accept ${pendingUser.user}'s request?`} + > + + + )} + + {(localStorage.getItem("status") !== "2" || isCR) && ( + + handleRemovePendingUser(pendingUser.id) + } + actionButtonClass="btn btn-outline-danger btn-sm mx-1" + modalBody={`Do you really want to reject ${pendingUser.user}'s request?`} + > + + + )}
))}
diff --git a/frontend/src/components/Rooms/Sections/Sections.jsx b/frontend/src/components/Rooms/Sections/Sections.jsx index 517d511..0fbdf71 100644 --- a/frontend/src/components/Rooms/Sections/Sections.jsx +++ b/frontend/src/components/Rooms/Sections/Sections.jsx @@ -91,45 +91,54 @@ const Sections = (props) => { - {status && } - - {sections.map((section, index) => ( - - - - - - Create an Item - - - ( + + - Update this Section - - - - Delete this Section - - - - ))} + /> + + {status && ( + + )} + + + + Create an Item + + + + Update this Section + + + + Delete this Section + + + + )) + ) : ( +
{status}
+ )} ); }; diff --git a/frontend/src/components/generic/CustomAlert.jsx b/frontend/src/components/generic/CustomAlert.jsx index c0ba3bb..d931884 100644 --- a/frontend/src/components/generic/CustomAlert.jsx +++ b/frontend/src/components/generic/CustomAlert.jsx @@ -6,7 +6,7 @@ const CustomAlert = (props) => {
{props.status} diff --git a/frontend/src/components/generic/CustomModal.jsx b/frontend/src/components/generic/CustomModal.jsx index 0eb91f2..a598ee8 100644 --- a/frontend/src/components/generic/CustomModal.jsx +++ b/frontend/src/components/generic/CustomModal.jsx @@ -3,8 +3,8 @@ import { Button, Modal } from "react-bootstrap"; import { SettingsContext } from "../../contexts/SettingsContext"; const CustomModal = (props) => { - const [show, setShow] = useState(false); const { isAnimated } = useContext(SettingsContext); + const [show, setShow] = useState(props.show ? props.show : false); const handleClose = () => setShow(false); const handleShow = () => setShow(true); @@ -15,21 +15,25 @@ const CustomModal = (props) => { return ( <> - + {props.noAction ? ( + <> + ) : ( + + )} {props.modalTitle} @@ -38,12 +42,17 @@ const CustomModal = (props) => { {props.modalBody} - + {props.noAction ? ( + <> + ) : ( + + )} + diff --git a/server/items/migrations/0001_initial.py b/server/items/migrations/0001_initial.py index fc4009c..0facc5a 100644 --- a/server/items/migrations/0001_initial.py +++ b/server/items/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.1.2 on 2020-11-12 00:04 +# Generated by Django 3.1.2 on 2020-11-12 12:36 from django.conf import settings from django.db import migrations, models @@ -10,8 +10,8 @@ class Migration(migrations.Migration): initial = True dependencies = [ - migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('sections', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ diff --git a/server/items/views/item_views.py b/server/items/views/item_views.py index 71830bf..041053d 100644 --- a/server/items/views/item_views.py +++ b/server/items/views/item_views.py @@ -51,7 +51,7 @@ def get_queryset(self): if queryset: return queryset else: - raise NotFound("No item has been created yet!") + raise NotFound("No item has been created yet") class ItemCreate(CreateAPIView): diff --git a/server/sections/views.py b/server/sections/views.py index ccb221b..77fed37 100644 --- a/server/sections/views.py +++ b/server/sections/views.py @@ -39,7 +39,7 @@ def get_queryset(self): if queryset: return queryset else: - raise NotFound("No section has been created yet!") + raise NotFound("No section has been created yet") class SectionCreate(CreateAPIView): diff --git a/server/server/settings.py b/server/server/settings.py index 11cdaed..a41414d 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -99,14 +99,14 @@ DATABASES = { 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'du_hackathon', - 'USER': 'postgres', - 'PASSWORD': 'emonsust', - 'HOST': 'localhost', - 'PORT': '', - # 'ENGINE': 'django.db.backends.sqlite3', - # 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), + # 'ENGINE': 'django.db.backends.postgresql_psycopg2', + # 'NAME': 'du_hackathon', + # 'USER': 'postgres', + # 'PASSWORD': 'emonsust', + # 'HOST': 'localhost', + # 'PORT': '', + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } @@ -195,8 +195,8 @@ EMAIL_HOST_USER = os.environ.get('APP_EMAIL_USER') EMAIL_HOST_PASSWORD = os.environ.get('APP_EMAIL_PASS') -EMAIL_HOST_USER = "emonrahman186@gmail.com" -EMAIL_HOST_PASSWORD = "allah...123" +# EMAIL_HOST_USER = "emonrahman186@gmail.com" +# EMAIL_HOST_PASSWORD = "allah...123" OLD_PASSWORD_FIELD_ENABLED = True From 7e78e7d10daf3bd275201dd9c683a2806204e1be Mon Sep 17 00:00:00 2001 From: "Emon(2017831003)" <43314141+emon-swe-sust@users.noreply.github.com> Date: Fri, 13 Nov 2020 00:25:23 +0600 Subject: [PATCH 02/10] sign in and sign up credentials check --- .../src/components/Authentication/SignIn.js | 25 ++++++- .../src/components/Authentication/SignUp.js | 72 +++++-------------- frontend/src/components/Home/Home.js | 15 +++- frontend/src/components/Navbar/Navbar.js | 2 +- 4 files changed, 55 insertions(+), 59 deletions(-) diff --git a/frontend/src/components/Authentication/SignIn.js b/frontend/src/components/Authentication/SignIn.js index 3fbd7a1..972960c 100644 --- a/frontend/src/components/Authentication/SignIn.js +++ b/frontend/src/components/Authentication/SignIn.js @@ -4,6 +4,7 @@ import Modal from "react-bootstrap/Modal"; import Form from "react-bootstrap/Form"; import "./Sign.scss"; import { Link } from "react-router-dom"; +import CustomAlert from "../generic/CustomAlert"; const axios = require("axios"); @@ -41,7 +42,6 @@ export default class SignIn extends Component { axios .post(endpoint, body, config) .then((json) => { - console.log(json.data) localStorage.setItem('username',json.data.user.username); localStorage.setItem('status',json.data.user.status); localStorage.setItem('reg_no',json.data.user.reg_no); @@ -52,10 +52,18 @@ export default class SignIn extends Component { window.location.href = "/"; }) .catch((err) => { - console.log(err); + this.setState({ + errors: err.response.data + },() => {console.log(this.state.errors)}) }); }; + componentWillUnmount() { + this.setState({ + errors: {}, + },() => console.log(this.state.errors,'sdfghs')) + } + render() { return (

Sign In

+ + {Object.keys(this.state.errors).length !== 0 && + this.state.errors['password'] ? ( + // non_field_errors + ) : + this.state.errors['non_field_errors'] ? ( + // non_field_errors + ) : + ( +
+ ) + } +
this.handle_signin(e, this.state)}> {/* Email address */} diff --git a/frontend/src/components/Authentication/SignUp.js b/frontend/src/components/Authentication/SignUp.js index bcfc8d6..9dc1958 100644 --- a/frontend/src/components/Authentication/SignUp.js +++ b/frontend/src/components/Authentication/SignUp.js @@ -45,16 +45,13 @@ class SignUp extends Component { axios.get(endpoint, config) .then((response) => { let tmparray = []; - // console.log(response.data); for (var i = 0; i < response.data.length; i++) { tmparray.push(response.data[i]); } - /*console.log(tmparray)*/ this.setState({ dept: tmparray, department: tmparray[0].id, }); - /*console.log(this.state)*/ }).catch((err) => { this.setState({ errors: err.response.data, @@ -67,12 +64,10 @@ class SignUp extends Component { for (var i = 0; i < response.data.length; i++) { tmparray.push(response.data[i]); } - /*console.log(tmparray)*/ this.setState({ varsity: tmparray, university: tmparray[0].id, }); - /*console.log(this.state)*/ }).catch((err) => { this.setState({ errors: err.response.data, @@ -96,12 +91,6 @@ class SignUp extends Component { university: data.university, reg_no: data.reg_no, status: data.status, - /* password1: "balchalabal", - password2: "balchalabal", - department: 1, - university: 1, - reg_no: 200, - status: 2,*/ }; else obj = { @@ -115,7 +104,6 @@ class SignUp extends Component { status: data.status, }; let body = JSON.stringify(obj); - // console.log(body); let config = { headers: { "Content-Type": "application/json", @@ -141,7 +129,6 @@ class SignUp extends Component { }; handle_change_signin = (e) => { - /*console.log(this.state)*/ const name = e.target.name; const value = e.target.value; this.setState((prevstate) => { @@ -149,7 +136,6 @@ class SignUp extends Component { newState[name] = value; return newState; }); - // console.log(this.state); }; toggleForm = (e) => { @@ -214,17 +200,27 @@ class SignUp extends Component { > - {/* - - -

Welcome

- - */}

Sign Up

- {/* */} {Object.keys(this.state.errors).length !== 0 && ( - + this.state.errors['status'] ? ( + + ) : + this.state.errors['username'] ? ( + + ) : + this.state.errors['email'] ? ( + + ) : + this.state.errors['password1'] ? ( + + ) : + this.state.errors['password2'] ? ( + + ) : + ( + + ) )} - {/* Select Occupation */} @@ -245,19 +240,7 @@ class SignUp extends Component {
{this.state.status === "2" ? ( - /* - - - - - - - - - - */ - {/* Name */} - {/* Registration No */} ) : ( - {/* User Name */} )}
- {/*
*/} - {/* University */} - {/* - - - */} {varsitylist} - {/* Department */} - {/* - - */} {departmentlist} - {/* Email address */} - {/* Password */} - {/* Confirm Password */}
- {/**/} - {/* - - */} diff --git a/frontend/src/components/Home/Home.js b/frontend/src/components/Home/Home.js index cf74cda..100d75a 100644 --- a/frontend/src/components/Home/Home.js +++ b/frontend/src/components/Home/Home.js @@ -187,7 +187,8 @@ export default class Home extends Component {

{iitem.name}

- {this.state.rooms[iitem.id] ? ( + {this.state.rooms[iitem.id] ? + ( this.state.rooms[iitem.id].map((item) => (
@@ -206,7 +207,9 @@ export default class Home extends Component {
)) ) : ( - +
+ +
)}
@@ -248,6 +251,14 @@ export default class Home extends Component {
))} +
+ +

See More...

+ +
) } diff --git a/frontend/src/components/Navbar/Navbar.js b/frontend/src/components/Navbar/Navbar.js index 548a0f9..40c7507 100644 --- a/frontend/src/components/Navbar/Navbar.js +++ b/frontend/src/components/Navbar/Navbar.js @@ -124,7 +124,7 @@ const Navs = () => { )} setSignInShow(false)} /> - setSignUpShow(false)} /> + setSignUpShow(false)} /> ); }; From 18698b265e2665aafa89ca6f7481f912bd7fe15f Mon Sep 17 00:00:00 2001 From: sania51 Date: Fri, 13 Nov 2020 00:34:43 +0600 Subject: [PATCH 03/10] minor changes --- .../components/CreateCourse/CreateCourse.js | 3 +- frontend/src/components/Dept/Dept.js | 42 +++---- frontend/src/components/Header/Header.js | 2 +- frontend/src/components/Header/Header.scss | 2 +- frontend/src/components/Home/Home.js | 107 +++++++++--------- server/server/settings.py | 6 +- 6 files changed, 75 insertions(+), 87 deletions(-) diff --git a/frontend/src/components/CreateCourse/CreateCourse.js b/frontend/src/components/CreateCourse/CreateCourse.js index 3607dc2..064f6d0 100644 --- a/frontend/src/components/CreateCourse/CreateCourse.js +++ b/frontend/src/components/CreateCourse/CreateCourse.js @@ -147,8 +147,7 @@ function CreateCourse() { */} diff --git a/frontend/src/components/Dept/Dept.js b/frontend/src/components/Dept/Dept.js index 827a7a4..b4c4c91 100644 --- a/frontend/src/components/Dept/Dept.js +++ b/frontend/src/components/Dept/Dept.js @@ -3,8 +3,6 @@ import Container from "react-bootstrap/Container"; import Card from "react-bootstrap/Card"; import { CardColumns } from "react-bootstrap"; import Button from "react-bootstrap/Button"; -import { CardGroup } from "react-bootstrap"; -import {Link,useLocation, useParams} from "react-router-dom"; const axios = require("axios"); export default class Dept extends Component { @@ -87,31 +85,25 @@ export default class Dept extends Component { if(this.state.rooms){ courselists = this.state.rooms.map((item) => (
- - - - - - {item.course.split(",")[0]} - - - {item.course.split(",")[1]} - - - - - + + + + {item.course.split(",")[0]} + + + {item.course.split(",")[1]} + + + +
- )); - } - + )); + } return ( -
- -

{this.state.dept_name}

- {courselists} -
-
+ +

{this.state.dept_name}

+ {courselists} +
); } } \ No newline at end of file diff --git a/frontend/src/components/Header/Header.js b/frontend/src/components/Header/Header.js index afc0726..93f8079 100644 --- a/frontend/src/components/Header/Header.js +++ b/frontend/src/components/Header/Header.js @@ -7,7 +7,7 @@ export default class Header extends Component { return (
-

Online Learning Supporter

+

Online Learning

Supporter

All Your Online Learning Essentials at One Place.

diff --git a/frontend/src/components/Header/Header.scss b/frontend/src/components/Header/Header.scss index 81e8c6c..53e5187 100644 --- a/frontend/src/components/Header/Header.scss +++ b/frontend/src/components/Header/Header.scss @@ -28,7 +28,7 @@ } &__heading { width: 50%; - font-size: 4vw; + font-size: 3.5vw; font-family: 'Josefin Sans', sans-serif; } &__intro { diff --git a/frontend/src/components/Home/Home.js b/frontend/src/components/Home/Home.js index cf74cda..300735e 100644 --- a/frontend/src/components/Home/Home.js +++ b/frontend/src/components/Home/Home.js @@ -183,73 +183,70 @@ export default class Home extends Component { let deptcoursel_unauthenticate; if (Object.keys(this.state.dept).length > 0) { deptcoursel_unauthenticate = this.state.dept.map((iitem, i) => ( -
-

{iitem.name}

- - - {this.state.rooms[iitem.id] ? ( - this.state.rooms[iitem.id].map((item) => ( -
- - - - {item.course.split(",")[0]} - - - {item.course.split(",")[1]} - - - - -
- )) - ) : ( - - )} -
-
- -

See More...

- -
+
+

{iitem.name}

+ + + {this.state.rooms[iitem.id] ? ( + this.state.rooms[iitem.id].map((item) => ( +
+ + + + {item.course.split(",")[0]} + + + {item.course.split(",")[1]} + + + + +
+ )) + ) : ( + + )} +
+
+ +

See More...

+
+
)); } let deptcoursel_authenticate; if(localStorage.getItem('dept_id')){ let dept_id = localStorage.getItem('dept_id'); - if(this.state.rooms[dept_id]) ( - deptcoursel_authenticate = -
+ if(this.state.rooms[dept_id]) deptcoursel_authenticate = ( +
-

{localStorage.getItem('dept_name')}

+

+ {localStorage.getItem("dept_name")} +

- {this.state.rooms[dept_id].map((item) => ( + {this.state.rooms[dept_id].map((item) => (
- - - - {item.course.split(",")[0]} - - - {item.course.split(",")[1]} - - - - + + + + {item.course.split(",")[0]} + + + {item.course.split(",")[1]} + + + +
- ))} + ))}
-
- ) +
+ ); } diff --git a/server/server/settings.py b/server/server/settings.py index 11cdaed..2eb1fd8 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -102,7 +102,7 @@ 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'du_hackathon', 'USER': 'postgres', - 'PASSWORD': 'emonsust', + 'PASSWORD': '2369', 'HOST': 'localhost', 'PORT': '', # 'ENGINE': 'django.db.backends.sqlite3', @@ -195,8 +195,8 @@ EMAIL_HOST_USER = os.environ.get('APP_EMAIL_USER') EMAIL_HOST_PASSWORD = os.environ.get('APP_EMAIL_PASS') -EMAIL_HOST_USER = "emonrahman186@gmail.com" -EMAIL_HOST_PASSWORD = "allah...123" +EMAIL_HOST_USER = "proshirahman@gmail.com" +EMAIL_HOST_PASSWORD = "kafljagpgiyvwpmv" OLD_PASSWORD_FIELD_ENABLED = True From 8a90b3d151576f54393545883b6fd7fce5253b49 Mon Sep 17 00:00:00 2001 From: sania51 Date: Fri, 13 Nov 2020 00:56:13 +0600 Subject: [PATCH 04/10] error fix --- frontend/src/components/Home/Home.js | 40 ++++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/Home/Home.js b/frontend/src/components/Home/Home.js index b9476e2..a98b81a 100644 --- a/frontend/src/components/Home/Home.js +++ b/frontend/src/components/Home/Home.js @@ -221,35 +221,35 @@ export default class Home extends Component {
-
)); } let deptcoursel_authenticate; if(localStorage.getItem('dept_id')){ let dept_id = localStorage.getItem('dept_id'); - if(this.state.rooms[dept_id]) deptcoursel_authenticate = ( -
+ if(this.state.rooms[dept_id]) ( + deptcoursel_authenticate = +
-

- {localStorage.getItem("dept_name")} -

+

{localStorage.getItem('dept_name')}

- {this.state.rooms[dept_id].map((item) => ( + {this.state.rooms[dept_id].map((item) => (
- - - - {item.course.split(",")[0]} - - - {item.course.split(",")[1]} - - - - + + + + {item.course.split(",")[0]} + + + {item.course.split(",")[1]} + + + +
- ))} + ))}
Date: Fri, 13 Nov 2020 01:24:14 +0600 Subject: [PATCH 05/10] Room's permission bug fixed (client & server) --- frontend/src/components/Rooms/RoomMembers.jsx | 122 +++++++++++------- frontend/src/components/Rooms/Rooms.jsx | 3 +- server/rooms/views/update_room_user_views.py | 13 ++ .../email/email_confirmation_message.txt | 2 +- 4 files changed, 92 insertions(+), 48 deletions(-) diff --git a/frontend/src/components/Rooms/RoomMembers.jsx b/frontend/src/components/Rooms/RoomMembers.jsx index 526ced3..29dd067 100644 --- a/frontend/src/components/Rooms/RoomMembers.jsx +++ b/frontend/src/components/Rooms/RoomMembers.jsx @@ -27,21 +27,36 @@ const RoomMembers = (props) => { if (!response.ok) setStatus(data.detail); else setMembers(data[0]); - // Pending user's list - API_URL = `/api/v1/rooms/pending_requests/${props.room_pk}/list/`; + // Check isCR + API_URL = `/api/v1/rooms/check_CR/${props.room_pk}/`; response = await fetch(API_URL, { method: "GET", }); - data = await response.json(); + response.ok && setIsCR(true); + }; + + loadData(); + }, [props.room_pk]); + + // Pending user's list + useEffect(() => { + const loadData = async () => { + const API_URL = `/api/v1/rooms/pending_requests/${props.room_pk}/list/`; + + const response = await fetch(API_URL, { + method: "GET", + }); + + const data = await response.json(); if (!response.ok && response.status !== 404) setStatus(data.detail); else if (response.status !== 404) setPendingUsers(data); }; - loadData(); - }, [props.room_pk]); + if (localStorage.getItem("status") !== "2" || isCR) loadData(); + }, [isCR]); const handleAddPendingUser = (pending_request_pk, username, userstatus) => { let API_URL = `/api/v1/rooms/add/${props.room_pk}/${userstatus}/${username}/`; @@ -202,7 +217,7 @@ const RoomMembers = (props) => { handleAction={() => handleRemoveMember( class_representative, - "student" + "class_representative" ) } actionButtonClass="btn btn-outline-danger btn-sm mx-1" @@ -258,49 +273,64 @@ const RoomMembers = (props) => { ))}
-
- Pending Requests -
- -
- {pendingUsers.map((pendingUser) => ( -
-
{pendingUser.user}
- - {(localStorage.getItem("status") !== "2" || isCR) && ( - - handleAddPendingUser( - pendingUser.id, - pendingUser.user, - pendingUser.user_status - ) - } - actionButtonClass="btn btn-outline-success btn-sm mx-1" - modalBody={`Do you want to accept ${pendingUser.user}'s request?`} - > - - - )} + {(localStorage.getItem("status") !== "2" || isCR) && ( + <> +
+ Pending Requests +
- {(localStorage.getItem("status") !== "2" || isCR) && ( - - handleRemovePendingUser(pendingUser.id) - } - actionButtonClass="btn btn-outline-danger btn-sm mx-1" - modalBody={`Do you really want to reject ${pendingUser.user}'s request?`} +
+ {pendingUsers.map((pendingUser) => ( +
- - - )} +
{pendingUser.user}
+ + {(localStorage.getItem("status") !== "2" || + isCR) && ( + + handleAddPendingUser( + pendingUser.id, + pendingUser.user, + pendingUser.user_status + ) + } + actionButtonClass="btn btn-outline-success btn-sm mx-1" + modalBody={`Do you want to accept ${pendingUser.user}'s request?`} + > + + + )} + + {(localStorage.getItem("status") !== "2" || + isCR) && ( + + handleRemovePendingUser( + pendingUser.id + ) + } + actionButtonClass="btn btn-outline-danger btn-sm mx-1" + modalBody={`Do you really want to reject ${pendingUser.user}'s request?`} + > + + + )} +
+ ))}
- ))} -
+ + )}
); }; diff --git a/frontend/src/components/Rooms/Rooms.jsx b/frontend/src/components/Rooms/Rooms.jsx index 1362085..5294784 100644 --- a/frontend/src/components/Rooms/Rooms.jsx +++ b/frontend/src/components/Rooms/Rooms.jsx @@ -10,7 +10,7 @@ import CustomAlert from "../generic/CustomAlert"; import UpdateRoomModal from "./UpdateRoomModal"; import CustomModal from "../generic/CustomModal"; -const Rooms = () => { +const Rooms = (props) => { const [room, setRoom] = useState({}); const [status, setStatus] = useState(undefined); const { handleLogOut } = useContext(AuthenticationContext); @@ -26,6 +26,7 @@ const Rooms = () => { }); if (response.status === 401) handleLogOut(); + else if (response.status === 406) props.history.push("/"); let data = await response.json(); diff --git a/server/rooms/views/update_room_user_views.py b/server/rooms/views/update_room_user_views.py index df8ad1e..243f04d 100644 --- a/server/rooms/views/update_room_user_views.py +++ b/server/rooms/views/update_room_user_views.py @@ -123,12 +123,25 @@ def patch(self, request, *args, **kwargs): except: raise NotFound('User does not exist!') + if user in ('teacher', 'class_representative') and self.request.user.status == 2: + raise PermissionDenied( + 'Only a Teacher can remove other Teachers or Class Representatives') + is_owner = Room.objects.filter(owner=user_id, id=room_pk) if is_owner: raise PermissionDenied( "The owner cannot be removed from the member's list of a room") + # Check if this is user is a CR or not (Because you have to remove him from CR's List first then remove him from student's list) + if user == 'student': + existing_cr_ids = list( + Room.objects.filter(id=room_pk).values("class_representatives")) + + for i in range(len(existing_cr_ids)): + if user_id == existing_cr_ids[i]["class_representatives"]: + raise NotAcceptable("First remove him from CR's list") + existing_users_ids = list( Room.objects.filter(id=room_pk).values(user + 's')) diff --git a/server/templates/account/email/email_confirmation_message.txt b/server/templates/account/email/email_confirmation_message.txt index 646b3f1..04c9857 100644 --- a/server/templates/account/email/email_confirmation_message.txt +++ b/server/templates/account/email/email_confirmation_message.txt @@ -6,4 +6,4 @@ To confirm this is correct, { const [user, setUser] = useState({}); @@ -67,53 +70,100 @@ const Profile = () => { }, [handleLogOut]); return ( - - {status ? ( - - ) : ( -
- { - // e.target.onerror = null; - // e.target.src = "/img/Default.png"; - // }} - alt="profile" - style={{ maxWidth: "10rem" }} - /> - -
- Username: - {user.username} -
- - Department: - {user.department} -
- - Reg. No: - {user.reg_no} -
- - Status: - {user.status} -
- - University: - {user.university} -
- - Email: - {user.email} -
- - Change Password -
- )} -
+ + {status ? ( + + ) : ( +
+
+

+ {" "} + {user.username} {" "} + + ({user.status}) + +

+
+

Account

+
+ + + +
+ {" "} + University:{" "} +
+ + + + +
+
+ + +
+ {" "} + Department:{" "} +
+ + + + +
+
+ + +
+ {" "} + Reg. No:{" "} +
+ + + + +
+
+ + +
+ {" "} + Email:{" "} +
+ + + + +
+
+ Change Password +
+
+ )} +
); }; diff --git a/frontend/src/components/Authentication/Profile.scss b/frontend/src/components/Authentication/Profile.scss new file mode 100644 index 0000000..ddfc81d --- /dev/null +++ b/frontend/src/components/Authentication/Profile.scss @@ -0,0 +1,7 @@ +.profile { + margin-top: 50px; + &__status { + color: #B8B8B8; + font-size: 60%; + } +} \ No newline at end of file From 69cf0896351dec49285767ed98aa75ef373137e0 Mon Sep 17 00:00:00 2001 From: sania51 Date: Fri, 13 Nov 2020 13:00:49 +0600 Subject: [PATCH 07/10] spinner fixed --- frontend/src/App.js | 2 +- frontend/src/components/Navbar/Navbar.scss | 1 - .../src/components/generic/LoadingScreen.jsx | 9 +- frontend/src/styles/base/_base.scss | 3 + .../styles/componentStyles/LoadingScreen.scss | 45 +++ node_modules/normalize.css/CHANGELOG.md | 175 +++++++++ node_modules/normalize.css/LICENSE.md | 21 ++ node_modules/normalize.css/README.md | 102 +++++ node_modules/normalize.css/normalize.css | 349 ++++++++++++++++++ node_modules/normalize.css/package.json | 46 +++ package-lock.json | 11 + 11 files changed, 755 insertions(+), 9 deletions(-) create mode 100644 frontend/src/styles/componentStyles/LoadingScreen.scss create mode 100644 node_modules/normalize.css/CHANGELOG.md create mode 100644 node_modules/normalize.css/LICENSE.md create mode 100644 node_modules/normalize.css/README.md create mode 100644 node_modules/normalize.css/normalize.css create mode 100644 node_modules/normalize.css/package.json create mode 100644 package-lock.json diff --git a/frontend/src/App.js b/frontend/src/App.js index 1a27189..9aba6aa 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,6 +1,6 @@ import React from "react"; +import 'normalize.css'; import "./styles/styles.scss"; -import "./styles/base/_settings.scss"; import { library } from "@fortawesome/fontawesome-svg-core"; import { fas } from "@fortawesome/free-solid-svg-icons"; import Home from "./components/Home/Home"; diff --git a/frontend/src/components/Navbar/Navbar.scss b/frontend/src/components/Navbar/Navbar.scss index 8f0fed0..32abc05 100644 --- a/frontend/src/components/Navbar/Navbar.scss +++ b/frontend/src/components/Navbar/Navbar.scss @@ -3,7 +3,6 @@ &__heading { display: none; } - font-family: "Josefin Sans", sans-serif; &__icon { &__bell { margin-right: 12px; diff --git a/frontend/src/components/generic/LoadingScreen.jsx b/frontend/src/components/generic/LoadingScreen.jsx index cc69461..5111b43 100644 --- a/frontend/src/components/generic/LoadingScreen.jsx +++ b/frontend/src/components/generic/LoadingScreen.jsx @@ -1,13 +1,8 @@ import React from "react"; -import { Spinner } from "react-bootstrap"; +import '../../styles/componentStyles/LoadingScreen.scss'; const LoadingScreen = () => { - return ( -
- - Loading... -
- ); + return
; }; export default LoadingScreen; diff --git a/frontend/src/styles/base/_base.scss b/frontend/src/styles/base/_base.scss index bf060e7..712fd1b 100644 --- a/frontend/src/styles/base/_base.scss +++ b/frontend/src/styles/base/_base.scss @@ -1,3 +1,6 @@ +* { + font-family: "Josefin Sans", sans-serif; +} // @keyframes rotateX { // 0% { // opacity: 0; diff --git a/frontend/src/styles/componentStyles/LoadingScreen.scss b/frontend/src/styles/componentStyles/LoadingScreen.scss new file mode 100644 index 0000000..7d7cb70 --- /dev/null +++ b/frontend/src/styles/componentStyles/LoadingScreen.scss @@ -0,0 +1,45 @@ +.spin { + position: fixed; + width: 100%; + left: 0; + right: 0; + top: 0; + bottom: 0; + background-color: rgba(255, 255, 255, 0.7); + z-index: 9999; + } + + @-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } + } + + @keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } + } + + .spin::after { + content: ""; + position: absolute; + left: 50%; + top: 50%; + width: 47px; + height: 47px; + border-style: solid; + border-color: #A50AFF; + border-top-color: transparent; + border-width: 3px; + border-radius: 50%; + -webkit-animation: spin 0.8s linear infinite; + animation: spin 0.8s linear infinite; + } + \ No newline at end of file diff --git a/node_modules/normalize.css/CHANGELOG.md b/node_modules/normalize.css/CHANGELOG.md new file mode 100644 index 0000000..922f6e3 --- /dev/null +++ b/node_modules/normalize.css/CHANGELOG.md @@ -0,0 +1,175 @@ +# Changes to normalize.css + +### 8.0.1 (November 4, 2018) + +* Fix regression in IE rendering of `main` element. + +### 8.0.0 (February 2, 2018) + +* Remove support for older browsers Android 4, lte IE 9, lte Safari 7. +* Don't remove search input cancel button in Chrome/Safari. +* Form inputs inherit `font-family`. +* Fix text decoration in Safari 8+. + +### 7.0.0 (May 2, 2017) + +* Revert changes in `body` and form elements styles introduced by v6 + +### 6.0.0 (March 26, 2017) + +* Remove all opinionated rules +* Correct document heading comment +* Update `abbr[title]` support + +### 5.0.0 (October 3, 2016) + +* Add normalized sections not already present from + https://html.spec.whatwg.org/multipage/. +* Move unsorted rules into their respective sections. +* Update the `summary` style in all browsers. +* Remove `::placeholder` styles due to a bug in Edge. +* More explicitly define font resets on form controls. +* Remove the `optgroup` normalization needed by the previous font reset. +* Update text-size-adjust documentation
 for IE on Windows Phone +* Update OS X reference to macOS +* Update the semver strategy. + +### 4.2.0 (June 30, 2016) + +* Correct the `line-height` in all browsers. +* Restore `optgroup` font inheritance. +* Update normalize.css heading. + +### 4.1.1 (April 12, 2016) + +* Update normalize.css heading. + +### 4.1.0 (April 11, 2016) + +* Normalize placeholders in Chrome, Edge, and Safari. +* Normalize `text-decoration-skip` property in Safari. +* Normalize file select buttons. +* Normalize search input outlines in Safari. +* Limit Firefox focus normalizations to buttons. +* Restore `main` to package.json. +* Restore proper overflow to certain `select` elements. +* Remove opinionated cursor styles on buttons. +* Update stylelint configuration. +* Update tests. + +### 4.0.0 (March 19, 2016) + +* Add the correct font weight for `b` and `strong` in Chrome, Edge, and Safari. +* Correct inconsistent `overflow` for `hr` in Edge and IE. +* Correct inconsistent `box-sizing` for `hr` in Firefox. +* Correct inconsistent `text-decoration` and `border-bottom` for `abbr[title]` + in Chrome, Edge, Firefox IE, Opera, and Safari. +* Correct inheritance and scaling of `font-size` for preformatted text. +* Correct `legend` text wrapping not present in Edge and IE. +* Remove unnecessary normalization of `line-height` for `input`. +* Remove unnecessary normalization of `color` for form controls. +* Remove unnecessary `box-sizing` for `input[type="search"]` in Chrome, Edge, + Firefox, IE, and Safari. +* Remove opinionated table resets. +* Remove opinionated `pre` overflow. +* Remove selector weight from some input selectors. +* Update normalization of `border-style` for `img`. +* Update normalization of `color` inheritance for `legend`. +* Update normalization of `background-color` for `mark`. +* Update normalization of `outline` for `:-moz-focusring` removed by a previous + normalization in Firefox. +* Update opinionated style of `outline-width` for `a:active` and `a:hover`. +* Update comments to identify opinionated styles. +* Update comments to specify browser/versions affected by all changes. +* Update comments to use one voice. + +--- + +### 3.0.3 (March 30, 2015) + +* Remove unnecessary vendor prefixes. +* Add `main` property. + +### 3.0.2 (October 4, 2014) + +* Only alter `background-color` of links in IE 10. +* Add `menu` element to HTML5 display definitions. + +### 3.0.1 (March 27, 2014) + +* Add package.json for npm support. + +### 3.0.0 (January 28, 2014) + +### 3.0.0-rc.1 (January 26, 2014) + +* Explicit tests for each normalization. +* Fix i18n for `q` element. +* Fix `pre` text formatting and overflow. +* Fix vertical alignment of `progress`. +* Address `button` overflow in IE 8/9/10. +* Revert `textarea` alignment modification. +* Fix number input button cursor in Chrome on OS X. +* Remove `a:focus` outline normalization. +* Fix `figure` margin normalization. +* Normalize `optgroup`. +* Remove default table cell padding. +* Set correct display for `progress` in IE 8/9. +* Fix `font` and `color` inheritance for forms. + +--- + +### 2.1.3 (August 26, 2013) + +* Fix component.json. +* Remove the gray background color from active links in IE 10. + +### 2.1.2 (May 11, 2013) + +* Revert root `color` and `background` normalizations. + +### 2.1.1 (April 8, 2013) + +* Normalize root `color` and `background` to counter the effects of system + color schemes. + +### 2.1.0 (January 21, 2013) + +* Normalize `text-transform` for `button` and `select`. +* Normalize `h1` margin when within HTML5 sectioning elements. +* Normalize `hr` element. +* Remove unnecessary `pre` styles. +* Add `main` element to HTML5 display definitions. +* Fix cursor style for disabled button `input`. + +### 2.0.1 (August 20, 2012) + +* Remove stray IE 6/7 `inline-block` hack from HTML5 display settings. + +### 2.0.0 (August 19, 2012) + +* Remove legacy browser form normalizations. +* Remove all list normalizations. +* Add `quotes` normalizations. +* Remove all heading normalizations except `h1` font size. +* Form elements automatically inherit `font-family` from ancestor. +* Drop support for IE 6/7, Firefox < 4, and Safari < 5. + +--- + +### 1.0.1 (August 19, 2012) + +* Adjust `small` font size normalization. + +### 1.0.0 (August 14, 2012) + +(Only the notable changes since public release) + +* Add MIT License. +* Hide `audio` elements without controls in iOS 5. +* Normalize heading margins and font size. +* Move font-family normalization from `body` to `html`. +* Remove scrollbar normalization. +* Remove excess padding from checkbox and radio inputs in IE 7. +* Add IE9 correction for SVG overflow. +* Add fix for legend not inheriting color in IE 6/7/8/9. diff --git a/node_modules/normalize.css/LICENSE.md b/node_modules/normalize.css/LICENSE.md new file mode 100644 index 0000000..43b5ddc --- /dev/null +++ b/node_modules/normalize.css/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright © Nicolas Gallagher and Jonathan Neal + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/normalize.css/README.md b/node_modules/normalize.css/README.md new file mode 100644 index 0000000..71954f2 --- /dev/null +++ b/node_modules/normalize.css/README.md @@ -0,0 +1,102 @@ +# normalize.css + +
Normalize Logo + +> A modern alternative to CSS resets + +[![npm][npm-image]][npm-url] [![license][license-image]][license-url] +[![changelog][changelog-image]][changelog-url] +[![gitter][gitter-image]][gitter-url] + + +**NPM** + +```sh +npm install --save normalize.css +``` + +**CDN** + +See https://yarnpkg.com/en/package/normalize.css + +**Download** + +See https://necolas.github.io/normalize.css/latest/normalize.css + + +## What does it do? + +* Preserves useful defaults, unlike many CSS resets. +* Normalizes styles for a wide range of elements. +* Corrects bugs and common browser inconsistencies. +* Improves usability with subtle modifications. +* Explains what code does using detailed comments. + + +## Browser support + +* Chrome +* Edge +* Firefox ESR+ +* Internet Explorer 10+ +* Safari 8+ +* Opera + + +## Extended details and known issues + +Additional detail and explanation of the esoteric parts of normalize.css. + +#### `pre, code, kbd, samp` + +The `font-family: monospace, monospace` hack fixes the inheritance and scaling +of font-size for preformatted text. The duplication of `monospace` is +intentional. [Source](https://en.wikipedia.org/wiki/User:Davidgothberg/Test59). + +#### `sub, sup` + +Normally, using `sub` or `sup` affects the line-box height of text in all +browsers. [Source](https://gist.github.com/413930). + +#### `select` + +By default, Chrome on OS X and Safari on OS X allow very limited styling of +`select`, unless a border property is set. The default font weight on `optgroup` +elements cannot safely be changed in Chrome on OSX and Safari on OS X. + +#### `[type="checkbox"]` + +It is recommended that you do not style checkbox and radio inputs as Firefox's +implementation does not respect box-sizing, padding, or width. + +#### `[type="number"]` + +Certain font size values applied to number inputs cause the cursor style of the +decrement button to change from `default` to `text`. + +#### `[type="search"]` + +The search input is not fully stylable by default. In Chrome and Safari on +OSX/iOS you can't control `font`, `padding`, `border`, or `background`. In +Chrome and Safari on Windows you can't control `border` properly. It will apply +`border-width` but will only show a border color (which cannot be controlled) +for the outer 1px of that border. Applying `-webkit-appearance: textfield` +addresses these issues without removing the benefits of search inputs (e.g. +showing past searches). + +## Contributing + +Please read the [contribution guidelines](CONTRIBUTING.md) in order to make the +contribution process easy and effective for everyone involved. + + +[changelog-image]: https://img.shields.io/badge/changelog-md-blue.svg?style=flat-square +[changelog-url]: CHANGELOG.md +[license-image]: https://img.shields.io/npm/l/normalize.css.svg?style=flat-square +[license-url]: LICENSE.md +[npm-image]: https://img.shields.io/npm/v/normalize.css.svg?style=flat-square +[npm-url]: https://www.npmjs.com/package/normalize.css +[gitter-image]: https://img.shields.io/badge/chat-gitter-blue.svg?style=flat-square +[gitter-url]: https://gitter.im/necolas/normalize.css diff --git a/node_modules/normalize.css/normalize.css b/node_modules/normalize.css/normalize.css new file mode 100644 index 0000000..192eb9c --- /dev/null +++ b/node_modules/normalize.css/normalize.css @@ -0,0 +1,349 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ + +/* Document + ========================================================================== */ + +/** + * 1. Correct the line height in all browsers. + * 2. Prevent adjustments of font size after orientation changes in iOS. + */ + +html { + line-height: 1.15; /* 1 */ + -webkit-text-size-adjust: 100%; /* 2 */ +} + +/* Sections + ========================================================================== */ + +/** + * Remove the margin in all browsers. + */ + +body { + margin: 0; +} + +/** + * Render the `main` element consistently in IE. + */ + +main { + display: block; +} + +/** + * Correct the font size and margin on `h1` elements within `section` and + * `article` contexts in Chrome, Firefox, and Safari. + */ + +h1 { + font-size: 2em; + margin: 0.67em 0; +} + +/* Grouping content + ========================================================================== */ + +/** + * 1. Add the correct box sizing in Firefox. + * 2. Show the overflow in Edge and IE. + */ + +hr { + box-sizing: content-box; /* 1 */ + height: 0; /* 1 */ + overflow: visible; /* 2 */ +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +pre { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/* Text-level semantics + ========================================================================== */ + +/** + * Remove the gray background on active links in IE 10. + */ + +a { + background-color: transparent; +} + +/** + * 1. Remove the bottom border in Chrome 57- + * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari. + */ + +abbr[title] { + border-bottom: none; /* 1 */ + text-decoration: underline; /* 2 */ + text-decoration: underline dotted; /* 2 */ +} + +/** + * Add the correct font weight in Chrome, Edge, and Safari. + */ + +b, +strong { + font-weight: bolder; +} + +/** + * 1. Correct the inheritance and scaling of font size in all browsers. + * 2. Correct the odd `em` font sizing in all browsers. + */ + +code, +kbd, +samp { + font-family: monospace, monospace; /* 1 */ + font-size: 1em; /* 2 */ +} + +/** + * Add the correct font size in all browsers. + */ + +small { + font-size: 80%; +} + +/** + * Prevent `sub` and `sup` elements from affecting the line height in + * all browsers. + */ + +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; +} + +sub { + bottom: -0.25em; +} + +sup { + top: -0.5em; +} + +/* Embedded content + ========================================================================== */ + +/** + * Remove the border on images inside links in IE 10. + */ + +img { + border-style: none; +} + +/* Forms + ========================================================================== */ + +/** + * 1. Change the font styles in all browsers. + * 2. Remove the margin in Firefox and Safari. + */ + +button, +input, +optgroup, +select, +textarea { + font-family: inherit; /* 1 */ + font-size: 100%; /* 1 */ + line-height: 1.15; /* 1 */ + margin: 0; /* 2 */ +} + +/** + * Show the overflow in IE. + * 1. Show the overflow in Edge. + */ + +button, +input { /* 1 */ + overflow: visible; +} + +/** + * Remove the inheritance of text transform in Edge, Firefox, and IE. + * 1. Remove the inheritance of text transform in Firefox. + */ + +button, +select { /* 1 */ + text-transform: none; +} + +/** + * Correct the inability to style clickable types in iOS and Safari. + */ + +button, +[type="button"], +[type="reset"], +[type="submit"] { + -webkit-appearance: button; +} + +/** + * Remove the inner border and padding in Firefox. + */ + +button::-moz-focus-inner, +[type="button"]::-moz-focus-inner, +[type="reset"]::-moz-focus-inner, +[type="submit"]::-moz-focus-inner { + border-style: none; + padding: 0; +} + +/** + * Restore the focus styles unset by the previous rule. + */ + +button:-moz-focusring, +[type="button"]:-moz-focusring, +[type="reset"]:-moz-focusring, +[type="submit"]:-moz-focusring { + outline: 1px dotted ButtonText; +} + +/** + * Correct the padding in Firefox. + */ + +fieldset { + padding: 0.35em 0.75em 0.625em; +} + +/** + * 1. Correct the text wrapping in Edge and IE. + * 2. Correct the color inheritance from `fieldset` elements in IE. + * 3. Remove the padding so developers are not caught out when they zero out + * `fieldset` elements in all browsers. + */ + +legend { + box-sizing: border-box; /* 1 */ + color: inherit; /* 2 */ + display: table; /* 1 */ + max-width: 100%; /* 1 */ + padding: 0; /* 3 */ + white-space: normal; /* 1 */ +} + +/** + * Add the correct vertical alignment in Chrome, Firefox, and Opera. + */ + +progress { + vertical-align: baseline; +} + +/** + * Remove the default vertical scrollbar in IE 10+. + */ + +textarea { + overflow: auto; +} + +/** + * 1. Add the correct box sizing in IE 10. + * 2. Remove the padding in IE 10. + */ + +[type="checkbox"], +[type="radio"] { + box-sizing: border-box; /* 1 */ + padding: 0; /* 2 */ +} + +/** + * Correct the cursor style of increment and decrement buttons in Chrome. + */ + +[type="number"]::-webkit-inner-spin-button, +[type="number"]::-webkit-outer-spin-button { + height: auto; +} + +/** + * 1. Correct the odd appearance in Chrome and Safari. + * 2. Correct the outline style in Safari. + */ + +[type="search"] { + -webkit-appearance: textfield; /* 1 */ + outline-offset: -2px; /* 2 */ +} + +/** + * Remove the inner padding in Chrome and Safari on macOS. + */ + +[type="search"]::-webkit-search-decoration { + -webkit-appearance: none; +} + +/** + * 1. Correct the inability to style clickable types in iOS and Safari. + * 2. Change font properties to `inherit` in Safari. + */ + +::-webkit-file-upload-button { + -webkit-appearance: button; /* 1 */ + font: inherit; /* 2 */ +} + +/* Interactive + ========================================================================== */ + +/* + * Add the correct display in Edge, IE 10+, and Firefox. + */ + +details { + display: block; +} + +/* + * Add the correct display in all browsers. + */ + +summary { + display: list-item; +} + +/* Misc + ========================================================================== */ + +/** + * Add the correct display in IE 10+. + */ + +template { + display: none; +} + +/** + * Add the correct display in IE 10. + */ + +[hidden] { + display: none; +} diff --git a/node_modules/normalize.css/package.json b/node_modules/normalize.css/package.json new file mode 100644 index 0000000..bf6227b --- /dev/null +++ b/node_modules/normalize.css/package.json @@ -0,0 +1,46 @@ +{ + "_from": "normalize.css", + "_id": "normalize.css@8.0.1", + "_inBundle": false, + "_integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==", + "_location": "/normalize.css", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "normalize.css", + "name": "normalize.css", + "escapedName": "normalize.css", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#USER", + "/" + ], + "_resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "_shasum": "9b98a208738b9cc2634caacbc42d131c97487bf3", + "_spec": "normalize.css", + "_where": "E:\\React Js\\DU_Hackathon", + "bugs": { + "url": "https://github.com/necolas/normalize.css/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "A modern alternative to CSS resets", + "files": [ + "LICENSE.md", + "normalize.css" + ], + "homepage": "https://necolas.github.io/normalize.css", + "license": "MIT", + "main": "normalize.css", + "name": "normalize.css", + "repository": { + "type": "git", + "url": "git+https://github.com/necolas/normalize.css.git" + }, + "style": "normalize.css", + "version": "8.0.1" +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d9aa74a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "normalize.css": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/normalize.css/-/normalize.css-8.0.1.tgz", + "integrity": "sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==" + } + } +} From 106e2642576f04c5254f26d0d90b173168cb4412 Mon Sep 17 00:00:00 2001 From: "Emon(2017831003)" <43314141+emon-swe-sust@users.noreply.github.com> Date: Fri, 13 Nov 2020 19:36:44 +0600 Subject: [PATCH 08/10] myrooms created --- frontend/src/App.js | 11 +- .../components/CreateCourse/CreateCourse.js | 2 - frontend/src/components/Dept/Dept.js | 67 +++++++---- frontend/src/components/Home/Home.js | 107 +++++++++++------- frontend/src/components/My_Rooms/MyRooms.js | 88 ++++++++++++++ frontend/src/components/Navbar/Navbar.js | 21 ++-- server/server/settings.py | 4 +- 7 files changed, 227 insertions(+), 73 deletions(-) create mode 100644 frontend/src/components/My_Rooms/MyRooms.js diff --git a/frontend/src/App.js b/frontend/src/App.js index 1a27189..2833ed4 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -18,6 +18,7 @@ import Navs from './components/Navbar/Navbar'; import Dept from './components/Dept/Dept' import CreateCourse from "./components/CreateCourse/CreateCourse"; import Notifications from "./components/Notifications/Notifications"; +import MyRooms from "./components/My_Rooms/MyRooms"; // import FooterPage from "./components/Footer/Footer"; // import Footer from "./components/generic/Footer"; @@ -36,7 +37,15 @@ function App() { path="/rooms/:room_pk/" component={Rooms} /> - + + { - console.log("HHHIIIII"); let config = { headers: { "Content-Type": "application/json", @@ -128,7 +127,6 @@ function CreateCourse() { create_room(); }; - console.log(courses); if (localStorage.getItem("status") == 1 && courses) { let courselist = courses.length > 0 && diff --git a/frontend/src/components/Dept/Dept.js b/frontend/src/components/Dept/Dept.js index 827a7a4..bc1e831 100644 --- a/frontend/src/components/Dept/Dept.js +++ b/frontend/src/components/Dept/Dept.js @@ -18,21 +18,20 @@ export default class Dept extends Component { rooms_length: null, dept_name:'', dept_id:null, + enrolled_rooms_id : [] } } async componentDidMount() { - console.log("VAUI") const {match:{params}} = this.props; const id = params.id; - console.log(params) + let config = { + headers: { + "Content-Type": "application/json", + }, + }; const fetchcourses = async() => { - let config = { - headers: { - "Content-Type": "application/json", - }, - }; let endpoint = `/api/v1/rooms/${id}/list/`; await axios.get(endpoint, config) .then((response) => { @@ -41,13 +40,11 @@ export default class Dept extends Component { for (var j = 0; j < response.data.length; j++) { tmparray.push(response.data[j]); } - console.log("ASD") - console.log(tmparray) this.setState({ rooms: tmparray, rooms_length: response.data.length, - },() => {console.log(this.state)}) + }) }) .catch((err)=>{ console.log(err) @@ -55,29 +52,44 @@ export default class Dept extends Component { } const fetch_dept_details = async() => { - let config = { - headers: { - "Content-Type": "application/json", - }, - }; let endpoint = `/api/v1/university/departments/details/${id}/`; await axios.get(endpoint, config) .then((response) => { - console.log("HIIIIII") - console.log(response.data[0].name) this.setState({ dept_id: response.data.id, dept_name: response.data[0].name }) - },()=>{console.log(this.state)}) + }) .catch((err) => { - console.log("ERROR") console.log(err) }); } + const fetchuserrooms = async () => { + let endpoint2 = '/api/v1/rooms/user_room_list/'; + await axios + .get(endpoint2, config) + .then((response) => { + let tmprooms = []; + + for(let k=0; k { + console.log(err); + }); + }; + if(id){ await fetchcourses(); + await fetchuserrooms(); } await fetch_dept_details(); } @@ -97,7 +109,22 @@ export default class Dept extends Component { {item.course.split(",")[1]} - + {localStorage.getItem('isAuthenticated') && this.state.enrolled_rooms_id.includes(item.id) ? + ( +
+ + + +
+ ) : + ( + + ) + } diff --git a/frontend/src/components/Home/Home.js b/frontend/src/components/Home/Home.js index 100d75a..b3f8366 100644 --- a/frontend/src/components/Home/Home.js +++ b/frontend/src/components/Home/Home.js @@ -22,12 +22,12 @@ export default class Home extends Component { promise: false, dept_id: null, dept_size: null, + enrolled_rooms_id: [], }; } async componentDidMount() { - console.log(localStorage.getItem("status")); - let endpoint = "api/v1/university/departments/list/"; + let endpoint = "/api/v1/university/departments/list/"; let config = { headers: { "Content-Type": "application/json", @@ -46,7 +46,7 @@ export default class Home extends Component { this.setState({ dept: tmparray, dept_size: response.data.length, - },()=>{console.log(this.state.dept, "here")}); + }); }) .catch((err) => { console.log(err); @@ -54,18 +54,17 @@ export default class Home extends Component { }; await fetchdept(); - const fetchcourse_unauthenticated = async () => { + const fetchrooms = async () => { for (let i = 0; i < this.state.dept.length; i++) { - let endpoint1 = `api/v1/rooms/${this.state.dept[i].id}/list/`; + let endpoint1 = `/api/v1/rooms/${this.state.dept[i].id}/list/`; let current_dept_id = this.state.dept[i].id; await axios .get(endpoint1, config) .then((response) => { let tmparray = []; - for (var j = 0; j < response.data.length; j++) { + for (let j = 0; j < response.data.length; j++) { tmparray.push(response.data[j]); } - this.setState({ rooms: { ...this.state.rooms, @@ -79,34 +78,30 @@ export default class Home extends Component { } }; - const fetchcourse_authenticated = async () => { - let endpoint2 = `api/v1/rooms/${localStorage.getItem('dept_id')}/list/`; - let current_dept_id = localStorage.getItem('dept_id'); + const fetchuserrooms = async () => { + let endpoint2 = `/api/v1/rooms/user_room_list/`; await axios .get(endpoint2, config) .then((response) => { - let tmparray = []; - for (var j = 0; j < response.data.length; j++) { - tmparray.push(response.data[j]); + let tmprooms = []; + + for(let k=0; k { console.log(err); }); }; - - if (!localStorage.getItem("isAuthenticated")) { - await fetchcourse_unauthenticated(); - } else { - await fetchcourse_authenticated(); - + await fetchrooms(); + if (localStorage.getItem("isAuthenticated")) { + await fetchuserrooms(); } } @@ -117,7 +112,7 @@ export default class Home extends Component { }, }; const fetch_dept_name = async() => { - let endpoint3 = `api/v1/university/departments/details/${localStorage.getItem('dept_id')}/` + let endpoint3 = `/api/v1/university/departments/details/${localStorage.getItem('dept_id')}/` await axios .get(endpoint3, config) .then((response) => { @@ -133,6 +128,26 @@ export default class Home extends Component { } } + room_enroll(room_id) { + if(localStorage.getItem('status') == 2){ + let config = { + headers: { + "Content-Type": "application/json", + }, + }; + let body = new FormData() + let endpoint = `/api/v1/rooms/pending_requests/${room_id}/create/` + axios + .post(endpoint, body) + .then((response) => { + + }) + .catch((err) => { + console.log(err) + }) + } + } + render() { const settings = { infinite: true, @@ -180,9 +195,9 @@ export default class Home extends Component { }, ], }; - let deptcoursel_unauthenticate; + let deptcoursel; if (Object.keys(this.state.dept).length > 0) { - deptcoursel_unauthenticate = this.state.dept.map((iitem, i) => ( + deptcoursel = this.state.dept.map((iitem, i) => (

{iitem.name}

@@ -199,9 +214,28 @@ export default class Home extends Component { {item.course.split(",")[1]} - + {this.state.enrolled_rooms_id.includes(item.id) && localStorage.getItem('isAuthenticated') ? + ( +
+ + + +
+ ) : + localStorage.getItem('isAuthenticated') ? + ( + + ): + ( + + ) + }
@@ -243,7 +277,7 @@ export default class Home extends Component { {item.course.split(",")[1]} - @@ -267,23 +301,18 @@ export default class Home extends Component { return (
{this.state.rooms && - Object.keys(this.state.rooms).length > 0 && - !localStorage.getItem("isAuthenticated") ? ( + Object.keys(this.state.rooms).length > 0 ? (

All Availabe Rooms

- {deptcoursel_unauthenticate} + {deptcoursel}
) : ( // enrolled courses will be shown here:
-
-

All Availabe Rooms

- - {deptcoursel_authenticate} - +
)}
diff --git a/frontend/src/components/My_Rooms/MyRooms.js b/frontend/src/components/My_Rooms/MyRooms.js new file mode 100644 index 0000000..6c36a51 --- /dev/null +++ b/frontend/src/components/My_Rooms/MyRooms.js @@ -0,0 +1,88 @@ +import React, { Component } from "react"; +import Container from "react-bootstrap/Container"; +import Card from "react-bootstrap/Card"; +import { CardColumns } from "react-bootstrap"; +import Button from "react-bootstrap/Button"; +import { CardGroup } from "react-bootstrap"; +import {Link,useLocation, useParams} from "react-router-dom"; +const axios = require("axios"); + +export default class MyRooms extends Component { + + constructor(props) { + super(props) + + this.state = { + invalid: false, + rooms: [], + rooms_length: null, + enrolled_rooms_id : [] + } + } + + async componentDidMount() { + let config = { + headers: { + "Content-Type": "application/json", + }, + }; + const fetchcourses = async() => { + let endpoint = `/api/v1/rooms/user_room_list/`; + await axios.get(endpoint, config) + .then((response) => { + let tmparray = []; + + for (var j = 0; j < response.data.length; j++) { + tmparray.push(response.data[j]); + } + + this.setState({ + rooms: tmparray, + rooms_length: response.data.length, + }) + }) + .catch((err)=>{ + console.log(err) + }); + } + await fetchcourses(); + } + + render() { + let courselists; + if(this.state.rooms){ + courselists = this.state.rooms.map((item) => ( +
+ + + + + {item.course.split(",")[0]} + + + {item.course.split(",")[1]} + +
+ + + +
+
+
+
+
+ )); + } + + return ( +
+ +

Your Rooms

+ {courselists} +
+
+ ); + } +} \ No newline at end of file diff --git a/frontend/src/components/Navbar/Navbar.js b/frontend/src/components/Navbar/Navbar.js index 40c7507..83a1c34 100644 --- a/frontend/src/components/Navbar/Navbar.js +++ b/frontend/src/components/Navbar/Navbar.js @@ -12,6 +12,7 @@ import { NavLink } from "react-router-dom"; import "../Authentication/Logout"; import {AuthenticationContext} from "../../contexts/AuthenticationContext"; import NavDropdown from 'react-bootstrap/NavDropdown'; +import { Link } from "react-router-dom"; const Navs = () => { const [signInShow, setSignInShow] = React.useState(false); @@ -21,15 +22,17 @@ const Navs = () => {
- {"logo"} + + {"logo"} ClassPortal +
{!localStorage.getItem("isAuthenticated") ? ( @@ -114,7 +117,7 @@ const Navs = () => { Profile - + My Rooms handleLogOut()}> diff --git a/server/server/settings.py b/server/server/settings.py index a41414d..992e310 100644 --- a/server/server/settings.py +++ b/server/server/settings.py @@ -195,8 +195,8 @@ EMAIL_HOST_USER = os.environ.get('APP_EMAIL_USER') EMAIL_HOST_PASSWORD = os.environ.get('APP_EMAIL_PASS') -# EMAIL_HOST_USER = "emonrahman186@gmail.com" -# EMAIL_HOST_PASSWORD = "allah...123" +#EMAIL_HOST_USER = "emonrahman186@gmail.com" +#EMAIL_HOST_PASSWORD = "allah...123" OLD_PASSWORD_FIELD_ENABLED = True From 8417fc2bac3558c92ebb381cb0f9f50d7e707a93 Mon Sep 17 00:00:00 2001 From: ShahriarDhruvo Date: Fri, 13 Nov 2020 21:31:41 +0600 Subject: [PATCH 09/10] Navbar default browser style off --- frontend/src/components/Navbar/Navbar.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Navbar/Navbar.js b/frontend/src/components/Navbar/Navbar.js index 548a0f9..ac2eca7 100644 --- a/frontend/src/components/Navbar/Navbar.js +++ b/frontend/src/components/Navbar/Navbar.js @@ -36,7 +36,7 @@ const Navs = () => {