initial commit

This commit is contained in:
2024-12-17 13:07:06 -08:00
commit 3a3382ffff
183 changed files with 186691 additions and 0 deletions

View File

@@ -0,0 +1,18 @@
# Use Node.js LTS
FROM node:18
# Set the working directory
WORKDIR /app
# Install dependencies
COPY package*.json ./
RUN npm install
# Copy the code
COPY . .
# Expose the frontend port
EXPOSE 3000
# Start the app
CMD ["npm", "run", "dev"]

View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
backend/frontend/apps.py Normal file
View File

@@ -0,0 +1,6 @@
from django.apps import AppConfig
class FrontendConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'frontend'

View File

@@ -0,0 +1,14 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "10"
}
}
],
"@babel/preset-react"
],
"plugins": ["@babel/plugin-proposal-class-properties"]
}

View File

View File

@@ -0,0 +1,3 @@
from django.db import models
# Create your models here.

9601
backend/frontend/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack --mode development --watch",
"build": "webpack --mode production"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.23.9",
"@babel/preset-env": "^7.23.9",
"@babel/preset-react": "^7.23.3",
"autoprefixer": "^10.4.17",
"babel-loader": "^9.1.3",
"css-loader": "^6.10.0",
"file-loader": "^6.2.0",
"postcss-loader": "^8.1.0",
"precss": "^4.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"sass-loader": "^14.1.0",
"style-loader": "^3.3.4",
"webpack": "^5.90.0",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@emotion/react": "^11.11.3",
"@emotion/styled": "^11.11.0",
"@fontsource/roboto": "^5.0.8",
"@mui/material": "^5.15.6",
"bootstrap": "^5.3.2",
"js-cookie": "^3.0.5",
"npm": "^10.5.0",
"react-bootstrap": "^2.10.0",
"react-router-dom": "^6.21.3"
}
}

View File

@@ -0,0 +1,42 @@
import React, { Component } from "react";
import { render } from "react-dom";
import Button from 'react-bootstrap/Button';
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import NavDropdown from 'react-bootstrap/NavDropdown';
import Defaultnavbar from "./Defaultnavbar";
import { BrowserRouter as Router, Routes, Route, Link, Redirect, BrowserRouter } from "react-router-dom";
import Login from "./Login"
import CreateAccount from "./CreateAccount";
// Images
import stupid_pic from "../../static/images/stupid_pic.png"
import HomePage from "./HomePage";
import MainScreen from "./MainScreen/MainScreen";
import Chat from "./MainScreen/testmainscreen";
export default class App extends Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<BrowserRouter>
<Routes>
<Route exact path="/homepage" element={<HomePage />} />
<Route exact path="/login" element={<Login />} />
<Route exact path="/account-creation" element={<CreateAccount />} />
<Route exact path="/" element={<MainScreen />} />
</Routes>
</BrowserRouter>
</div>
)
}
}
const appDiv = document.getElementById("app");
render(<App />, appDiv);

View File

@@ -0,0 +1,102 @@
import React, { Component, useState, useEffect } from "react";
import { Container, Form, Button, Nav } from 'react-bootstrap';
import { useNavigate } from 'react-router-dom';
import Cookies from 'js-cookie';
function CreateAccount() {
const [email, setEmail] = useState('');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [shouldRedirect, setShouldRedirect] = useState(false);
const navigate = useNavigate();
const cancelAccountCreation = () => {
navigate("/login")
};
const handleOnClick = async (event) => {
event.preventDefault();
try {
const response = await fetch('http://127.0.0.1:8000/account_creation/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get("csrftoken")
},
body: JSON.stringify({
email: email,
username: username,
password: password,
})
});
if (!response.ok) {
throw new Error(`Error creating user: ${response.statusText}`);
}
const data = await response.json();
console.log('User created successfully:', data);
Cookies.set("token", data.token)
setShouldRedirect(true);
} catch (error) {
console.error('Error creating user:', error);
}
};
useEffect(() => {
if (shouldRedirect) {
Cookies.set('username', username, { expires: Infinity });
navigate('/'); // Redirect to home page on successful creation
}
}, [shouldRedirect]);
return (
<Container className="d-flex justify-content-center align-items-center">
<div className="login-container p-4 shadow">
<h2 className="text-center mb-4">Create Account</h2>
<Form>
<Form.Group className="mb-3" controlId="formEmail">
<Form.Label>Email</Form.Label>
<Form.Control
type="text"
placeholder="Enter your email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formUsername">
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
placeholder="Enter your username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Enter your password"
value={password}
onChange={(e) => setPassword(e.target.value)} />
</Form.Group>
<Button variant="primary" type="submit" className="w-100" onClick={handleOnClick}>
Create Account
</Button>
<p className="mt-3 text-center"> Changed your mind?</p>
<div className=" d-flex align-items-center justify-content-center">
<Button variant="outline-secondary" type="submit" className="w-50" onClick={cancelAccountCreation}>
Cancel
</Button>
</div>
</Form>
</div>
</Container>
);
}
export default CreateAccount;

View File

@@ -0,0 +1,54 @@
import Container from 'react-bootstrap/Container';
import Navbar from 'react-bootstrap/Navbar';
import React, { Component, useEffect } from "react";
import mesa_logo from "../../static/images/mesa_logo.png"
import Button from 'react-bootstrap/Button';
import Cookies from 'js-cookie';
import { useNavigate } from 'react-router-dom';
export default function Defaultnavbar({ currentChannel, onChannelClick, allChannels }) {
useEffect(() => {
console.log("allchannels: ", allChannels)
}, [allChannels])
const navigate = useNavigate();
return (
<Navbar className="navbar navbar-dark bg-dark">
<Container>
<Navbar.Brand href="#home">
<a href="/">
<img className="main-logo" src={mesa_logo} alt="Logo" />
</a>
</Navbar.Brand>
<Navbar.Toggle />
<Navbar.Collapse className="justify-content-end">
{allChannels.map((channel) => (
<Navbar.Text key={channel["name"]}>
<button
onClick={() => onChannelClick(channel)}
className={currentChannel === channel ? 'active' : ''}
>
{channel["name"]}
</button>
</Navbar.Text>
))}
<Navbar.Text>
<div>
{(Cookies.get("username") !== undefined) ? (
<p>Welcome, {Cookies.get("username")}!</p>
) : (
<Button className="btn btn-primary" onClick={() => navigate('/login')}>
Login
</Button>
)
}
</div>
</Navbar.Text>
</Navbar.Collapse>
</Container>
</Navbar>
);
};

View File

@@ -0,0 +1,35 @@
import React, { Component } from "react";
import Button from 'react-bootstrap/Button';
import { Container, Row, Col } from 'react-bootstrap';
// Images
import stupid_pic from "../../static/images/stupid_pic.png"
export default class HomePage extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Container fluid className="hero-section">
<Row className="justify-content-center align-items-center">
<Col md={6}>
<div className="hero-content-container">
<div className="hero-content">
<h1>Welcome to MESA Collaborator</h1>
<p>Forge study connections effortlessly. Input your preferred subjects and availability, and join your fellow MESA students for collaborative sessions. Elevate your learning experience by sharing insights and tackling challenges together.</p>
<a href="login">
<Button variant="primary">Get Started</Button>
</a>
</div>
<div className="hero-image-col">
<img src={stupid_pic} alt="Hero Image" className="hero-image" />
</div>
</div>
</Col>
</Row>
</Container>
)
}
}

View File

@@ -0,0 +1,91 @@
import React, { Component, useState, useEffect } from "react";
import { Container, Form, Button, Nav } from 'react-bootstrap';
import { useNavigate } from 'react-router-dom';
import Cookies from 'js-cookie';
function Login() {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [shouldRedirect, setShouldRedirect] = useState(false);
const navigate = useNavigate();
const handleOnClick = async (event) => {
event.preventDefault();
console.log("What the skibidi");
try {
const response = await fetch('http://127.0.0.1:8000/login/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get("csrftoken")
},
body: JSON.stringify({
username: username,
password: password,
})
});
if (!response.ok) {
throw new Error(`Error logging in user: ${response.statusText}`);
}
const data = await response.json();
console.log('Successfully logged in:', data);
Cookies.set("token", data.token)
setShouldRedirect(true);
} catch (error) {
console.error('Successfully logged in:', error);
}
};
const navigateToCreation = async () => {
navigate("../account-creation")
}
useEffect(() => {
if (shouldRedirect) {
Cookies.set('username', username, { expires: Infinity });
navigate('/'); // Redirect to home page on successful creation
}
}, [shouldRedirect]);
return (
<Container className="d-flex justify-content-center align-items-center">
<div className="login-container p-4 shadow">
<h2 className="text-center mb-4">Login</h2>
<Form onSubmit={handleOnClick}>
<Form.Group className="mb-3" controlId="formUsername">
<Form.Label>Username</Form.Label>
<Form.Control
type="text"
placeholder="Enter your username"
value={username}
onChange={(e) => setUsername(e.target.value)}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="formPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Enter your password"
value={password}
n onChange={(e) => setPassword(e.target.value)} />
</Form.Group>
<Button variant="primary" type="submit" className="w-100" onClick={handleOnClick}>
Login
</Button>
<p className="mt-3 text-center"> Or Create an Account</p>
<div className=" d-flex align-items-center justify-content-center">
<Button variant="outline-secondary" className="w-50" onClick={navigateToCreation}>
Create Account
</Button>
</div>
</Form>
</div>
</Container>
);
}
export default Login;

View File

@@ -0,0 +1,293 @@
import Cookies from 'js-cookie';
import { useNavigate } from 'react-router-dom';
import React, { useEffect, useState, useRef } from "react";
import Defaultnavbar from '../Defaultnavbar';
export default function MainScreen() {
const navigate = useNavigate();
const [hubs, setHubs] = useState([]);
const [currentHubName, setCurrentHubName] = useState("")
const [messages, setMessages] = useState([]);
const [tempMessage, setTempMessage] = useState("");
const [channels, setChannels] = useState([]);
const [currentChannel, setCurrentChannel] = useState([]);
const [selectedImage, setSelectedImage] = useState(null);
const wsRef = useRef(null);
let url = `ws://localhost:8000/ws/channel//`; // Updated to include channel
const handleSendMessage = () => {
if (tempMessage.trim()) {
setMessage("");
}
};
const handleChannelClick = (channel) => {
// url = `ws://127.0.0.1:8000/ws/channel/1/`; // Updated to include channel
let tempChannel = currentChannel;
setCurrentChannel(channel["id"]);
url = `ws://localhost:8000/ws/channel/${encodeURIComponent(channel["id"])}/`;
console.log(`Navigated to: ${channel["name"]}`);
if (tempChannel !== channel["id"]) {
wsRef.current.close();
}
fetchSpecificChannelHub(channel["id"]);
};
function removeHub(inputString) {
// Split the string by ' '
const words = inputString.split(' ');
// Remove the first word (the 'hub' part)
words.pop();
// Join the remaining words back into a string
const result = words.join(' ');
return result;
}
const sendMessage = async (hId) => {
console.log("Send message ", currentChannel);
wsRef.current.send(JSON.stringify({
"channel": currentChannel,
"content": tempMessage,
'image': selectedImage,
"user": Cookies.get("username"),
"created_at": "0"
}))
setTempMessage("");
setSelectedImage("");
const fileInput = document.querySelector('.image-input');
if (fileInput) {
fileInput.value = ''; // Clear the input field
}
};
const handleKeyDown = (e) => {
if (e.key === "Enter") {
sendMessage();
setTempMessage("");
}
};
const fetchUserHubs = async () => {
try {
const response = await fetch('localhost:8000/gethubs/', { // Replace with your actual API endpoint
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get("csrftoken"),
'Authorization': `Token ${Cookies.get("token")}`, // Assuming you store the token in localStorage
}
});
if (!response.ok) {
throw new Error(`Error fetching user hubs 1: ${response.statusText}`);
}
const data = await response.json();
// console.log(data)
setHubs(data);
fetchSpecificHub(data[0].hub);
} catch (error) {
console.error('Error fetching user hubs:', error);
}
};
const fetchSpecificHub = async (hId) => {
try {
const response = await fetch('http://localhost:8000/getspecifichub/', { // Replace with your actual API endpoint
method: "POST",
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get("csrftoken"),
'Authorization': `Token ${Cookies.get("token")}`, // Assuming you store the token in localStorage
},
body: JSON.stringify({ "name": removeHub(hId) })
});
if (!response.ok) {
throw new Error(`Error fetching user hub 1: ${response.statusText}`);
}
const data = await response.json();
// console.log(data);
setCurrentHubName(data.hub["name"]);
fetchHubChannels(data.hub["name"]);
// setMessages(data.messages)
// console.log(messages)
} catch (error) {
console.error('Error fetching user hub:', error);
}
};
const fetchHubChannels = async (hId) => {
console.log("Channel thing");
console.log(currentHubName)
try {
const response = await fetch('http://localhost:8000/getHubChannels/', { // Replace with your actual API endpoint
method: "POST",
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get("csrftoken"),
'Authorization': `Token ${Cookies.get("token")}`, // Assuming you store the token in localStorage
},
body: JSON.stringify({ "hub": hId })
});
if (!response.ok) {
throw new Error(`Error fetching channel 1: ${response.statusText}`);
}
const data = await response.json();
setChannels(data);
setCurrentChannel(data[0].id);
console.log("My data:", data);
fetchSpecificChannelHub(data[0].id);
} catch (error) {
console.error('Error fetching channel:', error);
}
};
const fetchSpecificChannelHub = async (hId) => {
console.log(hId);
try {
const response = await fetch('http://localhost:8000/getSpecificChannel/', { // Replace with your actual API endpoint
method: "POST",
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': Cookies.get("csrftoken"),
'Authorization': `Token ${Cookies.get("token")}`, // Assuming you store the token in localStorage
},
body: JSON.stringify({ "id": hId })
});
if (!response.ok) {
throw new Error(`Error fetching specific channel hub 1: ${response.statusText}`);
}
const data = await response.json();
console.log(data);
console.log("CURRENT CHANNEL: ", hId)
setMessages(data.messages);
} catch (error) {
console.error('Error fetching specific channel hub:', error);
}
};
useEffect(() => {
console.log("Redone", currentChannel);
if (currentChannel.length !== 0) {
console.log("Nice??");
url = `ws://localhost:8000/ws/channel/${encodeURIComponent(currentChannel)}/`;
}
const ws = new WebSocket(url, [], {
headers: {
Authorization: `Token ${Cookies.get("token")}}`,
},
});
console.log(ws);
wsRef.current = ws;
ws.onmessage = function (e) {
console.log("NEW CURRENT CHANNEL", currentChannel);
// url = `ws://127.0.0.1:8000/ws/channel/1/`; // Updated to include channel
let data = JSON.parse(e.data);
console.log("Data:", data);
console.log("Current messages: ", messages);
setMessages((prevMessages) => [data, ...prevMessages]);
console.log(messages);
}
ws.onopen = function () {
console.log("WebSocket connected to channel:", currentChannel);
};
if (Cookies.get("username") === undefined) {
// console.log("Navigate");
navigate('/homepage');
}
if (currentChannel.length === 0) {
console.log("Nice??");
fetchUserHubs();
}
}, [navigate, currentChannel]);
const handleImageChange = (e) => {
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
reader.onloadend = () => {
setSelectedImage(reader.result); // Set base64-encoded image
};
reader.readAsDataURL(file);
}
};
function ImageOrPDF({url}) {
if (url.slice(-3).toLowerCase() !== "pdf") {
return <img src={`http://localhost:8000${url}`} style={{maxWidth: '300px'}}></img>;
} else {
return <a href={`http://localhost:8000${url}`} target="_blank">{url}</a>
}
}
return (
<div>
<Defaultnavbar allChannels={channels} onChannelClick={handleChannelClick} />
<div className="hub-content">
<h1>{currentHubName}</h1>
<div className="hub-messages">
{messages.map((message) => (
<div className="message" key={message.id}>
<p className="message-user">{message.user}</p>
<p className="message-content">{message.content}</p>
{(message.image !== null) &&
<ImageOrPDF url={message.image}/>
}
</div>
))}
</div>
<div className="message-bar">
<input
type="text"
className="message-input"
placeholder="Type your message here..."
value={tempMessage}
onChange={(e) => setTempMessage(e.target.value)}
onKeyDown={handleKeyDown}
/>
<input
type="file"
accept="*"
className="image-input"
onChange={handleImageChange}
style={{ marginLeft: '10px' }}
/>
<button className="send-button" onClick={sendMessage}>
Send
</button>
</div>
</div>
{/* Check if username cookie exists */}
{Cookies.get("username") !== undefined && (
<>
{/* Render hubs if cookie exists */}
<aside>
{hubs.map(hub => (
<p onClick={() => fetchSpecificHub(hub.hub)} key={hub.id}>{hub.hub}</p>
))}
</aside>
</>
)}
</div>)
}

View File

@@ -0,0 +1,46 @@
import React, { useEffect, useState } from "react";
const Chat = () => {
const [socket, setSocket] = useState(null);
const [messages, setMessages] = useState([]);
useEffect(() => {
const ws = new WebSocket("ws://127.0.0.1:8000/ws/chat/");
setSocket(ws);
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
setMessages((prevMessages) => [...prevMessages, data.message]);
};
return () => ws.close();
}, []);
const sendMessage = (message) => {
if (socket) {
socket.send(JSON.stringify({ message }));
}
};
return (
<div>
<div className="messages">
{messages.map((msg, index) => (
<p key={index}>{msg}</p>
))}
</div>
<input
type="text"
placeholder="Type a message..."
onKeyDown={(e) => {
if (e.key === "Enter") {
sendMessage(e.target.value);
e.target.value = "";
}
}}
/>
</div>
);
};
export default Chat;

View File

@@ -0,0 +1,2 @@
import App from './components/App';
// import 'bootstrap/dist/css/bootstrap.min.css';

View File

@@ -0,0 +1,350 @@
:root {
--black: #050316;
--background: #bbe2c5;
--primary: #7fd781;
--secondary: #eeeed3;
--accent: #ac552a;
--soft-lavender: #a29bfe;
--light-blue: #74b9ff;
}
.ibm-plex-sans-thin {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 100;
font-style: normal;
}
.ibm-plex-sans-extralight {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 200;
font-style: normal;
}
.ibm-plex-sans-light {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 300;
font-style: normal;
}
.ibm-plex-sans-regular {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 400;
font-style: normal;
}
.ibm-plex-sans-medium {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 500;
font-style: normal;
}
.ibm-plex-sans-semibold {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 600;
font-style: normal;
}
.ibm-plex-sans-bold {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 700;
font-style: normal;
}
.ibm-plex-sans-thin-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 100;
font-style: italic;
}
.ibm-plex-sans-extralight-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 200;
font-style: italic;
}
.ibm-plex-sans-light-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 300;
font-style: italic;
}
.ibm-plex-sans-regular-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 400;
font-style: italic;
}
.ibm-plex-sans-medium-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 500;
font-style: italic;
}
.ibm-plex-sans-semibold-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 600;
font-style: italic;
}
.ibm-plex-sans-bold-italic {
font-family: "IBM Plex Sans", sans-serif;
font-weight: 700;
font-style: italic;
}
body {
background-color: var(--background);
background: linear-gradient(to right, var(--soft-lavender), var(--light-blue));
color: #fff;
/* Adjust text color accordingly */
}
.main-logo {
width: 100px;
}
p {
font-family: IBM Plex Sans !important;
}
a {
text-decoration: none;
}
.navbar {
position: fixed;
width: 100%;
}
.login-container {
background-color: #fff;
border-radius: 8px;
max-width: 400px;
width: 100%;
color: black;
margin-top: 10%;
}
/* src/components/HeroSection.css */
.hero-section {
padding: 75px 0;
height: 100vh;
}
.hero-content-container {
margin-top: 10%;
background: #fff;
color: black;
border: 2px solid #fff;
border-radius: 10px;
overflow: hidden;
display: flex;
justify-content: center;
/* Center content horizontally */
align-items: center;
/* Center content vertically */
}
.hero-content {
text-align: left;
max-width: 500px;
padding: 20px;
}
.hero-image {
flex: 1;
}
/* Rest of your styles remain unchanged */
.hero-content button {
font-size: 1.2rem;
padding: 10px 20px;
margin-top: 2em;
margin-left: auto;
/* Adjust the margin as needed */
margin-right: auto;
/* Adjust the margin as needed */
display: block;
/* Make it a block element for auto margins to work */
}
.hero-image-col {
flex: 1;
/* Allow the image to take remaining space */
}
.hero-image {
width: 300px;
}
aside {
position: fixed;
left: 0;
top: 72px;
bottom: 0px;
padding: 10px;
background-color: #212529;
width: 100px;
}
.hub-content {
margin: 0 auto 0 100px;
display: flex;
flex-direction: column;
gap: 15px, 0;
height: 100vh; /* Full viewport height */
overflow: hidden; /* Prevents content from overflowing */
}
@media screen and (max-width: 800px) {
.hub-content {
margin-left: 100px;
}
}
/* General styling for the message bar */
.message-bar {
display: flex;
align-items: center;
padding: 10px;
background-color: #212529;
border-top: 1px solid #23272a;
position: sticky;
bottom: 0;
z-index: 10;
}
/* Input field styling */
.message-input {
flex-grow: 1;
padding: 10px;
margin-right: 10px;
font-size: 16px;
border: 1px solid #40444b;
border-radius: 5px;
background-color: #40444b;
color: white;
outline: none;
}
/* Placeholder color for input */
.message-input::placeholder {
color: #b9bbbe;
}
/* Send button styling */
.send-button {
padding: 10px 15px;
font-size: 16px;
color: white;
background-color: #5865f2; /* Discord-like blue */
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.2s ease;
}
.send-button:hover {
background-color: #4752c4; /* Darker shade on hover */
}
.send-button:active {
background-color: #3c45a5; /* Even darker shade on click */
}
/* Scrollable messages area */
.hub-messages {
flex-grow: 1; /* Fills remaining space */
overflow-y: auto; /* Makes this section scrollable */
display: flex;
flex-direction: column-reverse;
padding: 15px;
background-color: #36393f; /* Discord-like background */
color: #ffffff; /* Default text color */
}
/* Individual message container */
.message {
display: flex;
flex-direction: column;
padding: 8px 12px;
margin-bottom: 10px;
background-color: #2f3136; /* Slightly darker than background */
border-radius: 5px;
transition: background-color 0.2s ease;
}
/* Hover effect for messages */
.message:hover {
background-color: #3c3f45; /* Highlight on hover */
}
/* User's name styling */
.message-user {
font-weight: bold;
color: #7289da; /* Discord-like blue for usernames */
margin-bottom: 4px; /* Space between username and message */
font-size: 14px;
}
/* Message content styling */
.message-content {
color: #dcddde; /* Subtle off-white for message text */
font-size: 14px;
line-height: 1.4; /* Improve readability */
word-wrap: break-word; /* Handle long messages */
}
/* Scrollbar customization */
.hub-messages::-webkit-scrollbar {
width: 8px;
}
.hub-messages::-webkit-scrollbar-thumb {
background-color: #202225; /* Subtle scrollbar */
border-radius: 4px;
}
.hub-messages::-webkit-scrollbar-thumb:hover {
background-color: #2c2f33; /* Slightly brighter on hover */
}
/* Media queries for responsiveness */
@media (max-width: 600px) {
.hub-messages {
padding: 10px;
}
.message {
padding: 6px 10px;
}
.message-user,
.message-content {
font-size: 13px;
}
}
/* Adjustments for small screens */
@media (max-width: 800px) {
.message-bar {
padding: 8px;
}
.message-input {
font-size: 14px;
}
.send-button {
font-size: 14px;
padding: 8px 12px;
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,551 @@
/*!**********************!*\
!*** ./src/index.js ***!
\**********************/
/*!*******************************!*\
!*** ./src/components/App.js ***!
\*******************************/
/*!*********************************!*\
!*** ./src/components/Login.js ***!
\*********************************/
/*!************************************!*\
!*** ./src/components/HomePage.js ***!
\************************************/
/*!*************************************!*\
!*** ./node_modules/react/index.js ***!
\*************************************/
/*!*************************************!*\
!*** ./static/images/mesa_logo.png ***!
\*************************************/
/*!**************************************!*\
!*** ./static/images/stupid_pic.png ***!
\**************************************/
/*!*****************************************!*\
!*** ./node_modules/react-dom/index.js ***!
\*****************************************/
/*!*****************************************!*\
!*** ./node_modules/scheduler/index.js ***!
\*****************************************/
/*!*****************************************!*\
!*** ./node_modules/warning/warning.js ***!
\*****************************************/
/*!*****************************************!*\
!*** ./src/components/CreateAccount.js ***!
\*****************************************/
/*!*****************************************!*\
!*** ./src/components/Defaultnavbar.js ***!
\*****************************************/
/*!******************************************!*\
!*** ./node_modules/classnames/index.js ***!
\******************************************/
/*!******************************************!*\
!*** ./node_modules/prop-types/index.js ***!
\******************************************/
/*!*******************************************!*\
!*** ./node_modules/invariant/browser.js ***!
\*******************************************/
/*!*******************************************!*\
!*** ./node_modules/react/jsx-runtime.js ***!
\*******************************************/
/*!********************************************!*\
!*** ./node_modules/prop-types/lib/has.js ***!
\********************************************/
/*!*********************************************!*\
!*** ./node_modules/dom-helpers/esm/css.js ***!
\*********************************************/
/*!*********************************************!*\
!*** ./node_modules/object-assign/index.js ***!
\*********************************************/
/*!***********************************************!*\
!*** ./node_modules/@restart/ui/esm/Modal.js ***!
\***********************************************/
/*!***********************************************!*\
!*** ./node_modules/@restart/ui/esm/utils.js ***!
\***********************************************/
/*!************************************************!*\
!*** ./node_modules/@restart/ui/esm/Button.js ***!
\************************************************/
/*!************************************************!*\
!*** ./node_modules/dom-helpers/esm/listen.js ***!
\************************************************/
/*!*************************************************!*\
!*** ./node_modules/@restart/ui/esm/DataKey.js ***!
\*************************************************/
/*!*************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Col.js ***!
\*************************************************/
/*!*************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Row.js ***!
\*************************************************/
/*!*************************************************!*\
!*** ./node_modules/react-router/dist/index.js ***!
\*************************************************/
/*!*************************************************!*\
!*** ./src/components/MainScreen/MainScreen.js ***!
\*************************************************/
/*!**************************************************!*\
!*** ./node_modules/dom-helpers/esm/addClass.js ***!
\**************************************************/
/*!**************************************************!*\
!*** ./node_modules/dom-helpers/esm/contains.js ***!
\**************************************************/
/*!**************************************************!*\
!*** ./node_modules/dom-helpers/esm/hasClass.js ***!
\**************************************************/
/*!**************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Fade.js ***!
\**************************************************/
/*!**************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Form.js ***!
\**************************************************/
/*!***************************************************!*\
!*** ./node_modules/@restart/ui/esm/useWindow.js ***!
\***************************************************/
/*!***************************************************!*\
!*** ./node_modules/dom-helpers/esm/canUseDOM.js ***!
\***************************************************/
/*!***************************************************!*\
!*** ./node_modules/dom-helpers/esm/hyphenate.js ***!
\***************************************************/
/*!***************************************************!*\
!*** ./node_modules/js-cookie/dist/js.cookie.mjs ***!
\***************************************************/
/*!***************************************************!*\
!*** ./node_modules/prop-types/checkPropTypes.js ***!
\***************************************************/
/*!****************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Button.js ***!
\****************************************************/
/*!****************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Navbar.js ***!
\****************************************************/
/*!****************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Switch.js ***!
\****************************************************/
/*!*****************************************************!*\
!*** ./node_modules/dom-helpers/esm/isTransform.js ***!
\*****************************************************/
/*!*****************************************************!*\
!*** ./node_modules/dom-helpers/esm/ownerWindow.js ***!
\*****************************************************/
/*!*****************************************************!*\
!*** ./node_modules/dom-helpers/esm/removeClass.js ***!
\*****************************************************/
/*!*****************************************************!*\
!*** ./node_modules/react-router-dom/dist/index.js ***!
\*****************************************************/
/*!*****************************************************!*\
!*** ./node_modules/react/cjs/react.development.js ***!
\*****************************************************/
/*!*****************************************************!*\
!*** ./node_modules/uncontrollable/lib/esm/hook.js ***!
\*****************************************************/
/*!*****************************************************!*\
!*** ./src/components/MainScreen/testmainscreen.js ***!
\*****************************************************/
/*!******************************************************!*\
!*** ./node_modules/@restart/ui/esm/ModalManager.js ***!
\******************************************************/
/*!******************************************************!*\
!*** ./node_modules/dom-helpers/esm/triggerEvent.js ***!
\******************************************************/
/*!******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Collapse.js ***!
\******************************************************/
/*!******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Feedback.js ***!
\******************************************************/
/*!******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormText.js ***!
\******************************************************/
/*!******************************************************!*\
!*** ./node_modules/uncontrollable/lib/esm/index.js ***!
\******************************************************/
/*!******************************************************!*\
!*** ./node_modules/uncontrollable/lib/esm/utils.js ***!
\******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/@remix-run/router/dist/router.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/@restart/ui/esm/RTGTransition.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/dom-helpers/esm/activeElement.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/dom-helpers/esm/ownerDocument.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/dom-helpers/esm/transitionEnd.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Container.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormCheck.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormGroup.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormLabel.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormRange.js ***!
\*******************************************************/
/*!*******************************************************!*\
!*** ./node_modules/react-bootstrap/esm/Offcanvas.js ***!
\*******************************************************/
/*!********************************************************!*\
!*** ./node_modules/@restart/ui/esm/NoopTransition.js ***!
\********************************************************/
/*!********************************************************!*\
!*** ./node_modules/dom-helpers/esm/hyphenateStyle.js ***!
\********************************************************/
/*!********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormSelect.js ***!
\********************************************************/
/*!********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/NavbarText.js ***!
\********************************************************/
/*!*********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/CloseButton.js ***!
\*********************************************************/
/*!*********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormContext.js ***!
\*********************************************************/
/*!*********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormControl.js ***!
\*********************************************************/
/*!*********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/NavbarBrand.js ***!
\*********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/@restart/hooks/esm/useBreakpoint.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/@restart/hooks/esm/useMediaQuery.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/@restart/hooks/esm/useMergedRefs.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/@restart/ui/esm/useWaitForDOMRef.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/dom-helpers/esm/addEventListener.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/dom-helpers/esm/getComputedStyle.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/dom-helpers/esm/querySelectorAll.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormFloating.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/ModalContext.js ***!
\**********************************************************/
/*!**********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/NavbarToggle.js ***!
\**********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/@restart/ui/esm/SelectableContext.js ***!
\***********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/@restart/ui/esm/getScrollbarWidth.js ***!
\***********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FloatingLabel.js ***!
\***********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/NavbarContext.js ***!
\***********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/OffcanvasBody.js ***!
\***********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/react-bootstrap/esm/ThemeProvider.js ***!
\***********************************************************/
/*!***********************************************************!*\
!*** ./node_modules/react-transition-group/esm/config.js ***!
\***********************************************************/
/*!************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/esm/extends.js ***!
\************************************************************/
/*!************************************************************!*\
!*** ./node_modules/@restart/hooks/esm/useCommittedRef.js ***!
\************************************************************/
/*!************************************************************!*\
!*** ./node_modules/prop-types/factoryWithTypeCheckers.js ***!
\************************************************************/
/*!************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormCheckInput.js ***!
\************************************************************/
/*!************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/FormCheckLabel.js ***!
\************************************************************/
/*!************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/NavbarCollapse.js ***!
\************************************************************/
/*!************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/OffcanvasTitle.js ***!
\************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/@restart/hooks/esm/useEventCallback.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/dom-helpers/esm/removeEventListener.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/prop-types/lib/ReactPropTypesSecret.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/ElementChildren.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/NavbarOffcanvas.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/OffcanvasHeader.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/safeFindDOMNode.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/react-dom/cjs/react-dom.development.js ***!
\*************************************************************/
/*!*************************************************************!*\
!*** ./node_modules/scheduler/cjs/scheduler.development.js ***!
\*************************************************************/
/*!**************************************************************!*\
!*** ./node_modules/@restart/ui/esm/ImperativeTransition.js ***!
\**************************************************************/
/*!**************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/divWithClassName.js ***!
\**************************************************************/
/*!***************************************************************!*\
!*** ./node_modules/@restart/ui/esm/useRTGTransitionProps.js ***!
\***************************************************************/
/*!***************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/OffcanvasToggling.js ***!
\***************************************************************/
/*!***************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/TransitionWrapper.js ***!
\***************************************************************/
/*!***************************************************************!*\
!*** ./node_modules/react-transition-group/esm/Transition.js ***!
\***************************************************************/
/*!***************************************************************!*\
!*** ./node_modules/uncontrollable/lib/esm/uncontrollable.js ***!
\***************************************************************/
/*!****************************************************************!*\
!*** ./node_modules/@restart/hooks/esm/useIsomorphicEffect.js ***!
\****************************************************************/
/*!****************************************************************!*\
!*** ./node_modules/prop-types/node_modules/react-is/index.js ***!
\****************************************************************/
/*!*****************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/AbstractModalHeader.js ***!
\*****************************************************************/
/*!*****************************************************************!*\
!*** ./node_modules/react-transition-group/esm/utils/reflow.js ***!
\*****************************************************************/
/*!*****************************************************************!*\
!*** ./node_modules/react/cjs/react-jsx-runtime.development.js ***!
\*****************************************************************/
/*!******************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js ***!
\******************************************************************/
/*!******************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/triggerBrowserReflow.js ***!
\******************************************************************/
/*!*******************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js ***!
\*******************************************************************/
/*!*******************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/BootstrapModalManager.js ***!
\*******************************************************************/
/*!*******************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/createChainedFunction.js ***!
\*******************************************************************/
/*!*******************************************************************!*\
!*** ./node_modules/react-bootstrap/esm/transitionEndListener.js ***!
\*******************************************************************/
/*!********************************************************************!*\
!*** ./node_modules/react-transition-group/esm/utils/PropTypes.js ***!
\********************************************************************/
/*!***************************************************************************!*\
!*** ./node_modules/react-transition-group/esm/TransitionGroupContext.js ***!
\***************************************************************************/
/*!****************************************************************************!*\
!*** ./node_modules/react-lifecycles-compat/react-lifecycles-compat.es.js ***!
\****************************************************************************/
/*!********************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useMounted.js ***!
\********************************************************************************/
/*!*********************************************************************************!*\
!*** ./node_modules/@babel/runtime/helpers/esm/objectWithoutPropertiesLoose.js ***!
\*********************************************************************************/
/*!*********************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/usePrevious.js ***!
\*********************************************************************************/
/*!***********************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useMergedRefs.js ***!
\***********************************************************************************/
/*!***********************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useUpdatedRef.js ***!
\***********************************************************************************/
/*!***********************************************************************************!*\
!*** ./node_modules/prop-types/node_modules/react-is/cjs/react-is.development.js ***!
\***********************************************************************************/
/*!************************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useWillUnmount.js ***!
\************************************************************************************/
/*!*************************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useCommittedRef.js ***!
\*************************************************************************************/
/*!**************************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useEventCallback.js ***!
\**************************************************************************************/
/*!*****************************************************************************************!*\
!*** ./node_modules/@restart/ui/node_modules/@restart/hooks/esm/useIsomorphicEffect.js ***!
\*****************************************************************************************/

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

View File

@@ -0,0 +1,32 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Mesa Site</title>
{% load static %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous" />
<link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}" />
<style>
@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap');
</style>
</head>
<body>
<div id="main">
<div id="app"></div>
</div>
<script src="{% static "frontend/main.js" %}"></script>
<script src="https://cdn.jsdelivr.net/npm/react/umd/react.production.min.js" crossorigin></script>
<script src="https://cdn.jsdelivr.net/npm/react-dom/umd/react-dom.production.min.js" crossorigin></script>
<script src="https://cdn.jsdelivr.net/npm/react-bootstrap@next/dist/react-bootstrap.min.js" crossorigin></script>
<script>var Alert = ReactBootstrap.Alert;</script>
</body>
</html>

View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

8
backend/frontend/urls.py Normal file
View File

@@ -0,0 +1,8 @@
from django.urls import path
from .views import index
urlpatterns = [
path("", index),
path("login", index),
path("account-creation", index)
]

View File

@@ -0,0 +1,5 @@
from django.shortcuts import render
# Create your views here.
def index(request, *args, **kwargs):
return render(request, "frontend/index.html")

View File

@@ -0,0 +1,73 @@
const path = require("path");
const webpack = require("webpack");
module.exports = {
entry: "./src/index.js",
output: {
path: path.resolve(__dirname, "./static/frontend"),
filename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
},
},
, {
test: /\.(css)$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
// {
// loader: 'postcss-loader',
// options: {
// postcssOptions: {
// plugins: () => [
// require('autoprefixer')
// ]
// }
// }
// },
// {
// loader: 'sass-loader'
// }
]
},
{
test: /\.png$/,
loader: "file-loader",
options: {
name: '[name].[ext]',
outputPath: "static/images",
publicPath: 'static/images',
emitFile: true,
esModule: false
}
}
]
},
optimization: {
minimize: true,
},
plugins: [
new webpack.DefinePlugin({
"process.env": {
// This has effect on the react lib size
NODE_ENV: JSON.stringify("development"),
},
}),
],
resolve: {
extensions: [".jsx", ".js"]
},
};