add: generalized css classes and added a dark mode

This commit is contained in:
Lukian 2025-04-27 00:29:26 +02:00
parent 9806fc3b3c
commit 4ca8a21477
28 changed files with 101 additions and 297 deletions

View file

@ -8,7 +8,7 @@ export default function TopBar({ user }: { user: User | undefined }) {
const [burgerMenuOpen, setBurgerMenuOpen] = useState(false)
return (
<div className="topbar">
<div className="forum-section topbar">
<div className="topbar-left">
<Link to="/">Home</Link>
<Link to="/channels">Channels</Link>

View file

@ -3,6 +3,26 @@ html {
min-height: 100vh;
}
.forum-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.forum-section {
width: 97%;
padding: 10px;
display: flex;
flex-direction: column;
align-items: start;
gap: 10px;
border: 1px solid #270722;
background-color: #fff6fd;
}
.cat {
width: 100px;
}
@ -17,4 +37,29 @@ html {
.fish {
width: 300px;
}
@media (prefers-color-scheme: dark) {
html {
background: linear-gradient(#121212, #1e1b29);
}
.forum-section {
border: 1px solid #a678af;
background-color: #1b1b23;
color: #e4d9ec;
}
a {
color: #b88edc;
text-decoration: underline;
}
a:hover {
color: #d4b4f0;
}
a:visited {
color: #a678af;
}
}

View file

@ -26,9 +26,9 @@ export default function NotFoundPage() {
}, []);
return (
<div className="not-found-page">
<div className="forum-page">
<TopBar user={user} />
<div className="not-found-content">
<div className="forum-section">
<h2>404 - Page Not Found</h2>
<p>Sorry, the page you are looking for does not exist.</p>
<Link to="/">Go back to the homepage</Link>

View file

@ -150,9 +150,9 @@ export default function ChannelPage({socket}: {socket: WebSocket}) {
if (noChannel) {
return (
<div className="channel-page">
<div className="forum-page">
<TopBar user={user} />
<div className="channel">
<div className="forum-section">
<h2>Channel Not Found</h2>
<p>Sorry, the channel you are looking for does not exist.</p>
<Link to="/">Go back to the homepage</Link>
@ -163,9 +163,9 @@ export default function ChannelPage({socket}: {socket: WebSocket}) {
if (!channel) {
return (
<div className="channel-page">
<div className="forum-page">
<TopBar user={user} />
<div className="channel">
<div className="forum-section">
<p>Loading...</p>
</div>
</div>
@ -173,9 +173,9 @@ export default function ChannelPage({socket}: {socket: WebSocket}) {
}
return (
<div className="channel-page">
<div className="forum-page">
<TopBar user={user} />
<div className="channel">
<div className="forum-section">
<h2>Channel {channel.name}</h2>
<p>{channel.description}</p>
<p>Owner: <Link to={`/u/${channel.owner_username}`}>{channel.owner_username}</Link></p>

View file

@ -4,8 +4,6 @@ import { Channels, User } from "../types"
import axios from "axios"
import TopBar from "../components/TopBar"
import "../styles/ChannelsPage.css"
export default function ChannelsPage({socket}: {socket: WebSocket}) {
const [channels, setChannels] = useState<Channels>();
const [search, setSearch] = useState<string>("");
@ -64,9 +62,9 @@ export default function ChannelsPage({socket}: {socket: WebSocket}) {
if (!channels) {
return (
<div className="channels-page">
<div className="forum-page">
<TopBar user={user} />
<div className="channels-page-channels">
<div className="forum-section">
<h2>Channels</h2>
<p>Loading...</p>
</div>
@ -75,9 +73,9 @@ export default function ChannelsPage({socket}: {socket: WebSocket}) {
}
return (
<div className="channels-page">
<div className="forum-page">
<TopBar user={user} />
<div className="channels-page-channels">
<div className="forum-section">
<h2>Channels</h2>
<Link to="/create-channel">Create channel</Link>
<input

View file

@ -4,8 +4,6 @@ import { User } from "../types";
import axios from "axios";
import TopBar from "../components/TopBar";
import "../styles/CreateChannel.css";
export default function CreateChannel() {
const navigate = useNavigate();
const [name, setName] = useState("");
@ -39,9 +37,9 @@ export default function CreateChannel() {
}
return (
<div className="create-channel-page">
<div className="forum-page">
<TopBar user={user}/>
<div className="create-channel">
<div className="forum-section">
<h1>Create Channel</h1>
<form onSubmit={handleSubmit}>
<p>

View file

@ -4,8 +4,6 @@ import { User } from "../types";
import axios from "axios";
import TopBar from "../components/TopBar";
import "../styles/CreateEmoji.css";
export default function CreateEmoji() {
const navigate = useNavigate();
const [name, setName] = useState("");
@ -50,9 +48,9 @@ export default function CreateEmoji() {
}
return (
<div className="create-emoji-page">
<div className="forum-page">
<TopBar user={user}/>
<div className="create-emoji">
<div className="forum-section">
<h1>Create Emoji</h1>
<form onSubmit={handleSubmit}>
<p>

View file

@ -4,8 +4,6 @@ import { Link } from "react-router-dom"
import axios from "axios"
import TopBar from "../components/TopBar"
import "../styles/EditProfile.css"
export default function EditProfile() {
const [token, setToken] = useState<string>("");
const [user, setUser] = useState<User>();
@ -92,9 +90,9 @@ export default function EditProfile() {
if (!user) {
return (
<div className="edit-profile-page">
<div className="forum-page">
<TopBar user={user}/>
<div className="edit-login">
<div className="forum-section">
<p>Please log in to edit your profile</p>
<Link to="/login">Login</Link>
</div>
@ -103,9 +101,9 @@ export default function EditProfile() {
}
return (
<div className="edit-profile-page">
<div className="forum-page">
<TopBar user={user}/>
<div className="edit-pfp">
<div className="forum-section">
<h2>Edit Profile Picture</h2>
<form>
<input type="file" name="pfp" id="pfp" />
@ -113,14 +111,14 @@ export default function EditProfile() {
<button onClick={deletePfp}>Delete</button>
</form>
</div>
<div className="edit-username">
<div className="forum-section">
<h2>Edit Username</h2>
<form>
<input type="text" name="username" id="username" placeholder={user?.username} />
<button onClick={editUsername}>Save</button>
</form>
</div>
<div className="edit-password">
<div className="forum-section">
<h2>Edit Password</h2>
<form>
<input type="password" name="old-password" id="old-password" placeholder="Old password" />

View file

@ -4,8 +4,6 @@ import { Emojis, User } from "../types"
import axios from "axios"
import TopBar from "../components/TopBar"
import "../styles/EmojisPage.css"
export default function EmojisPage({socket}: {socket: WebSocket}) {
const [emojis, setEmojis] = useState<Emojis>();
const [search, setSearch] = useState<string>("");
@ -67,9 +65,9 @@ export default function EmojisPage({socket}: {socket: WebSocket}) {
if (!emojis) {
return (
<div className="emojis-page">
<div className="forum-page">
<TopBar user={user} />
<div className="emojis-page-emojis">
<div className="forum-section">
<h2>Emojis</h2>
<p>Loading...</p>
</div>
@ -78,10 +76,10 @@ export default function EmojisPage({socket}: {socket: WebSocket}) {
}
return (
<div className="emojis-page">
<div className="forum-page">
<TopBar user={user} />
<div className="emojis-page-emojis">
<h2>Channels</h2>
<div className="forum-section">
<h2>Emojis</h2>
<Link to="/create-emoji">Create emoji</Link>
<input
type="text"

View file

@ -146,7 +146,7 @@ export default function Home({socket}: {socket: WebSocket}) {
return (
<div className="home">
<TopBar user={user} />
<div className="home-header">
<div className="forum-section home-header">
<div className="home-header-text">
<h2>Welcome to Tanuki's forum !</h2>
<p>
@ -156,7 +156,7 @@ export default function Home({socket}: {socket: WebSocket}) {
<img src="osaka_arch.png" alt="osaka" className="osaka"/>
</div>
<div className="main-content">
<div className="home-messages">
<div className="forum-section messages">
<h2>Last messages</h2>
<div className="messages-list">
{messages?.map((message) => (
@ -170,7 +170,7 @@ export default function Home({socket}: {socket: WebSocket}) {
))}
</div>
</div>
<div className="channels">
<div className="forum-section channels">
<h2>Channels</h2>
<div className="channels-content">
<Link to={'/channels'}>All channels</Link>

View file

@ -3,8 +3,6 @@ import { useState } from "react";
import { useNavigate, Link } from "react-router-dom";
import TopBar from "../components/TopBar";
import "../styles/Login.css";
export default function Login() {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
@ -24,9 +22,9 @@ export default function Login() {
}
return (
<div className="login-page">
<div className="forum-page">
<TopBar user={undefined}/>
<div className="login">
<div className="forum-section">
<h2>Login</h2>
<form onSubmit={handleSubmit}>
<input

View file

@ -3,8 +3,6 @@ import { useState } from "react";
import { useNavigate, Link } from "react-router-dom";
import TopBar from "../components/TopBar";
import "../styles/Register.css";
export default function Register () {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
@ -31,9 +29,9 @@ export default function Register () {
}
return (
<div className="register-page">
<div className="forum-page">
<TopBar user={undefined}/>
<div className="register">
<div className="forum-section">
<h2>Register</h2>
<form onSubmit={handleSubmit}>
<p>

View file

@ -97,9 +97,9 @@ export default function UserPage({socket}: {socket: WebSocket}) {
if (noUser) {
return (
<div className="user-page">
<div className="forum-page">
<TopBar user={user} />
<div className="user">
<div className="forum-section">
<h2>User Not Found</h2>
<p>Sorry, the user you are looking for does not exist.</p>
<Link to="/">Go back to the homepage</Link>
@ -110,9 +110,9 @@ export default function UserPage({socket}: {socket: WebSocket}) {
if (!pageUser) {
return (
<div className="user-page">
<div className="forum-page">
<TopBar user={user} />
<div className="user">
<div className="forum-section">
<h2>Loading...</h2>
</div>
</div>
@ -120,9 +120,9 @@ export default function UserPage({socket}: {socket: WebSocket}) {
}
return (
<div className="user-page">
<div className="forum-page">
<TopBar user={user} />
<div className="user">
<div className="forum-section">
<div className="user-top">
<img src={`/api/users/${pageUser.username}/pfp`} alt="pfp" className="user-page-pfp" />
<h2>{pageUser.username}</h2>
@ -142,7 +142,7 @@ export default function UserPage({socket}: {socket: WebSocket}) {
</div>
)}
</div>
<div className="user-messages">
<div className="forum-section">
<h2>Last messages</h2>
<div className="messages-list">
{messages?.map((message) => (

View file

@ -4,8 +4,6 @@ import { User, Users } from "../types"
import axios from "axios"
import TopBar from "../components/TopBar"
import "../styles/UsersPage.css"
export default function UsersPage({socket}: {socket: WebSocket}) {
const [users, setUsers] = useState<Users>();
const [search, setSearch] = useState<string>("");
@ -64,9 +62,9 @@ export default function UsersPage({socket}: {socket: WebSocket}) {
if (!users) {
return (
<div className="users-page">
<div className="forum-page">
<TopBar user={thisUser} />
<div className="users-page-users">
<div className="forum-section">
<h2>Users</h2>
<p>Loading...</p>
</div>
@ -75,9 +73,9 @@ export default function UsersPage({socket}: {socket: WebSocket}) {
}
return (
<div className="users-page">
<div className="forum-page">
<TopBar user={thisUser} />
<div className="users-page-users">
<div className="forum-section">
<h2>Users</h2>
<input
type="text"

View file

@ -6,10 +6,3 @@
width: 100%;
gap: 20px;
}
.not-found-content {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
}

View file

@ -1,19 +1,3 @@
.channel-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.channel {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
}
.message-form {
margin: 16px 0;
position: relative;

View file

@ -1,19 +0,0 @@
.channels-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.channels-page-channels {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
display: flex;
flex-direction: column;
align-items: start;
gap: 10px;
}

View file

@ -1,15 +0,0 @@
.create-channel-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.create-channel {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
}

View file

@ -1,15 +0,0 @@
.create-emoji-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.create-emoji {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
}

View file

@ -1,44 +0,0 @@
.edit-profile-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.edit-login {
width: 97%;
border: 1px solid #270722;
padding: 10px;
display: flex;
flex-direction: column;
background-color: #fff6fd;
}
.edit-pfp {
width: 97%;
border: 1px solid #270722;
padding: 10px;
display: flex;
flex-direction: column;
background-color: #fff6fd;
}
.edit-username {
width: 97%;
border: 1px solid #270722;
padding: 10px;
display: flex;
flex-direction: column;
background-color: #fff6fd;
}
.edit-password {
width: 97%;
border: 1px solid #270722;
padding: 10px;
display: flex;
flex-direction: column;
background-color: #fff6fd;
}

View file

@ -1,24 +0,0 @@
.emojis-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.emojis-page-emojis {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
display: flex;
flex-direction: column;
align-items: start;
gap: 10px;
}
.emoji {
max-width: 50px;
max-height: 50px;
}

View file

@ -17,22 +17,13 @@
}
.home-header {
width: 97%;
border: 1px solid #270722;
display: flex;
justify-content: space-between;
align-items: top;
padding: 10px;
background-color: #fff6fd;
flex-direction: row;
}
.home-messages {
.messages {
width: 60%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
display: flex;
flex-direction: column;
min-height: 100%;
align-items: center;
}
@ -47,12 +38,7 @@
.channels {
width: 34%;
border: 1px solid #270722;
min-height: 100%;
padding: 10px;
display: flex;
flex-direction: column;
background-color: #fff6fd;
align-items: center;
}

View file

@ -1,15 +0,0 @@
.login-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.login {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
}

View file

@ -36,3 +36,9 @@
max-width: 1em;
max-height: 1em;
}
@media (prefers-color-scheme: dark) {
.message {
border: 1px solid #a678af;
}
}

View file

@ -1,15 +0,0 @@
.register-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.register {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
}

View file

@ -1,11 +1,7 @@
.topbar {
width: 97%;
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
flex-direction: row;
}
.topbar-left {

View file

@ -1,20 +1,5 @@
.user-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.user {
width: 97%;
border: 1px solid #270722;
padding: 10px;
display: flex;
flex-direction: column;
align-items: start;
background-color: #fff6fd;
}
.user-top {
@ -29,15 +14,6 @@
border-radius: 50%;
}
.user-messages {
width: 97%;
border: 1px solid #270722;
padding: 10px;
display: flex;
flex-direction: column;
background-color: #fff6fd;
}
.messages-list {
width: 100%;
display: flex;

View file

@ -1,19 +0,0 @@
.users-page {
display: flex;
flex-direction: column;
justify-content: start;
align-items: center;
width: 100%;
gap: 20px;
}
.users-page-users {
width: 97%;
border: 1px solid #270722;
padding: 10px;
background-color: #fff6fd;
display: flex;
flex-direction: column;
align-items: start;
gap: 10px;
}