From 4117c11c356652381a9564688139d9c3f25eb983 Mon Sep 17 00:00:00 2001 From: Zhongheng Liu Date: Wed, 31 Jan 2024 21:07:45 +0200 Subject: [PATCH] CSS styling overhaul FIXED Issue with rendering time - minutes now in fixed 2-digit format ADD Sidebar Topbar components to help with UI/UX ADD Avatar and Menu PNG files for style TODO Improve styling ET AL removed redundant code --- src/App.css | 4 +- src/App.tsx | 18 +++- src/Chat/Chat.css | 8 ++ src/Intl/strings.json | 2 +- src/Login/Login.css | 1 + src/MessageDisplay/MessageDisplay.tsx | 115 ++++++++++++------------- src/Sidebar/Components/Avatar.css | 5 ++ src/Sidebar/Components/Avatar.tsx | 9 ++ src/Sidebar/Components/SidebarMenu.tsx | 50 +++++++++++ src/Sidebar/Components/placeholder.jpg | Bin 0 -> 17203 bytes src/Sidebar/Sidebar.css | 47 ++++++++++ src/Sidebar/Sidebar.tsx | 24 ++++++ src/Topbar/Topbar.css | 10 +++ src/Topbar/Topbar.tsx | 33 +++++++ src/Topbar/menu.png | Bin 0 -> 10450 bytes src/type/messageTypes.ts | 1 + 16 files changed, 261 insertions(+), 66 deletions(-) create mode 100644 src/Sidebar/Components/Avatar.css create mode 100644 src/Sidebar/Components/Avatar.tsx create mode 100644 src/Sidebar/Components/SidebarMenu.tsx create mode 100644 src/Sidebar/Components/placeholder.jpg create mode 100644 src/Sidebar/Sidebar.css create mode 100644 src/Sidebar/Sidebar.tsx create mode 100644 src/Topbar/Topbar.css create mode 100644 src/Topbar/Topbar.tsx create mode 100644 src/Topbar/menu.png diff --git a/src/App.css b/src/App.css index e4849cc..bb372cd 100644 --- a/src/App.css +++ b/src/App.css @@ -1,6 +1,6 @@ body { - background-color: black; - color: #00FF33; + /* background-color: black; + color: #00FF33; */ margin: 1%; min-height: 100vh; } diff --git a/src/App.tsx b/src/App.tsx index 7d908e3..a5f11ac 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,6 +7,8 @@ import strings from "./Intl/strings.json"; import { LangContext, LoginContext, LoginType } from "./context"; import { contentTypes, domain, endpoints, port } from "./consts"; import { Login } from "./Login/Login"; +import { Sidebar } from "./Sidebar/Sidebar"; +import { Topbar } from "./Topbar/Topbar"; // what we "in the business" call type gymnastics const Wrapper = (): React.ReactElement => { const [lang, setLang] = useState("en_US"); @@ -16,11 +18,19 @@ const Wrapper = (): React.ReactElement => { ? `IRC logged in as ${login.username}` : "IRC Chat"; }, [login]); + const [sidebarEnabled, setSidebarEnabled] = useState(false); return ( -

{strings[lang].homepage.title}

-

{strings[lang].homepage.description}

+ + setSidebarEnabled(enabled) + } + > + setSidebarEnabled(enabled)} + > {/* callbacks for altering the Lang/Login contexts */} { @@ -97,8 +107,8 @@ const App = ({ }) .then((responseBody: { success: boolean }) => { if (responseBody.success) { - // TODO Put new username response true handler method stub - } else { + // TODO Put new username response true handler method stub + } else { console.error( "Server POST message failed." ); diff --git a/src/Chat/Chat.css b/src/Chat/Chat.css index 76b19f6..cc5dd7b 100644 --- a/src/Chat/Chat.css +++ b/src/Chat/Chat.css @@ -12,6 +12,14 @@ } .chat { + /* float: left; */ /* min-height: 80vh; */ position: relative; + box-shadow: + 0 2.8px 2.2px rgba(0, 0, 0, 0.034), + 0 6.7px 5.3px rgba(0, 0, 0, 0.048), + 0 12.5px 10px rgba(0, 0, 0, 0.06), + 0 22.3px 17.9px rgba(0, 0, 0, 0.072), + 0 41.8px 33.4px rgba(0, 0, 0, 0.086), + 0 100px 80px rgba(0, 0, 0, 0.12) } diff --git a/src/Intl/strings.json b/src/Intl/strings.json index ceff215..e5081b5 100644 --- a/src/Intl/strings.json +++ b/src/Intl/strings.json @@ -1,6 +1,6 @@ { "variableNames": ["userName", "content"], - "acceptedLangs": ["en_US", "zh_TW", "el_GR"], + "acceptedLangs": ["en_US", "zh_TW", "el_GR", "ar_SA"], "en_US": { "homepage": { "userNamePrompt": "Your username: ", diff --git a/src/Login/Login.css b/src/Login/Login.css index 21bceff..2776f45 100644 --- a/src/Login/Login.css +++ b/src/Login/Login.css @@ -1,3 +1,4 @@ .uname-error-text { color: red; } +.login {} \ No newline at end of file diff --git a/src/MessageDisplay/MessageDisplay.tsx b/src/MessageDisplay/MessageDisplay.tsx index 18a9277..3ebf8af 100644 --- a/src/MessageDisplay/MessageDisplay.tsx +++ b/src/MessageDisplay/MessageDisplay.tsx @@ -5,64 +5,61 @@ import strings from "../Intl/strings.json"; import "./MessageDisplay.css"; import { queryByRole } from "@testing-library/react"; export const MessageDisplay = ({ - type, - fromUserId, - toUserId, - content, - timeMillis, + type, + fromUserId, + toUserId, + content, + timeMillis, }: Message): React.ReactElement => { - const dateTime: Date = new Date(timeMillis); - const lang = useContext(LangContext); - const msgPage = strings[lang].chat; - /* FIXED funny error - * DESCRIPTION - * The line below was - * return (

[{dateTime.toLocaleString(Intl.DateTimeFormat().resolvedOptions().timeZone)}]...

) - * The line incorrectly generated a value of "UTC" as the parameter to toLocaleString() - * While "UTC" is an accepted string value, in EEST, aka. "Europe/Athens" timezone string is not an acceptable parameter. - * This caused the return statement to fail, and the message fails to render, despite it being correctly committed to the db. - * Funny clown moment 🤡 - */ - const timeString = `${ - dateTime.getHours() > 12 - ? dateTime.getHours() - 12 - : dateTime.getHours() - }:${dateTime.getMinutes()} ${dateTime.getHours() > 12 ? "PM" : "AM"}`; - switch (type) { - case MessageType.HELLO as MessageType: - return ( -

- [{timeString}]{" "} - {msgPage.joinMessage.replace( - "$userName", - fromUserId - )} -

- ); - case MessageType.MESSAGE as MessageType: - return ( -

- [{timeString}]{" "} - {msgPage.serverMessage - .replace( - "$userName", - fromUserId - ) - .replace("$content", content)} -

- ); - case MessageType.DATA as MessageType: - return <>; - case MessageType.CHNAME as MessageType: - return <>; - default: - console.error("Illegal MessageType reported!"); - return ( -

- [{timeString}] **THIS MESSAGE CANNOT BE - CORRECTLY SHOWN BECAUSE THE CLIENT - ENCOUNTERED AN ERROR** -

- ); - } + const dateTime: Date = new Date(timeMillis); + const lang = useContext(LangContext); + const msgPage = strings[lang].chat; + /* FIXED funny error + * DESCRIPTION + * The line below was + * return (

[{dateTime.toLocaleString(Intl.DateTimeFormat().resolvedOptions().timeZone)}]...

) + * The line incorrectly generated a value of "UTC" as the parameter to toLocaleString() + * While "UTC" is an accepted string value, in EEST, aka. "Europe/Athens" timezone string is not an acceptable parameter. + * This caused the return statement to fail, and the message fails to render, despite it being correctly committed to the db. + * Funny clown moment 🤡 + */ + const timeString = `${ + dateTime.getHours() > 12 + ? dateTime.getHours() - 12 + : dateTime.getHours() + }:${ + dateTime.getMinutes() >= 10 + ? dateTime.getMinutes() + : `0${dateTime.getMinutes().toString()}` + } ${dateTime.getHours() > 12 ? "PM" : "AM"}`; + switch (type) { + case MessageType.HELLO as MessageType: + return ( +

+ [{timeString}]{" "} + {msgPage.joinMessage.replace("$userName", fromUserId)} +

+ ); + case MessageType.MESSAGE as MessageType: + return ( +

+ [{timeString}]{" "} + {msgPage.serverMessage + .replace("$userName", fromUserId) + .replace("$content", content)} +

+ ); + case MessageType.DATA as MessageType: + return <>; + case MessageType.CHNAME as MessageType: + return <>; + default: + console.error("Illegal MessageType reported!"); + return ( +

+ [{timeString}] **THIS MESSAGE CANNOT BE CORRECTLY SHOWN + BECAUSE THE CLIENT ENCOUNTERED AN ERROR** +

+ ); + } }; diff --git a/src/Sidebar/Components/Avatar.css b/src/Sidebar/Components/Avatar.css new file mode 100644 index 0000000..f2da859 --- /dev/null +++ b/src/Sidebar/Components/Avatar.css @@ -0,0 +1,5 @@ +.avatar { + width: 100%; + display: flex; + justify-content:center; +} \ No newline at end of file diff --git a/src/Sidebar/Components/Avatar.tsx b/src/Sidebar/Components/Avatar.tsx new file mode 100644 index 0000000..700f20d --- /dev/null +++ b/src/Sidebar/Components/Avatar.tsx @@ -0,0 +1,9 @@ +import "./Avatar.css"; +import placeholderImage from "./placeholder.jpg"; +export const Avatar = () => { + return ( +
+ +
+ ); +}; diff --git a/src/Sidebar/Components/SidebarMenu.tsx b/src/Sidebar/Components/SidebarMenu.tsx new file mode 100644 index 0000000..be176d2 --- /dev/null +++ b/src/Sidebar/Components/SidebarMenu.tsx @@ -0,0 +1,50 @@ +import "../Sidebar.css"; +import { Avatar } from "./Avatar"; +export const SidebarMenuItem = ({ + text, + href, + handler, +}: { + text: string; + href?: string; + handler?: () => void; +}) => { + return ( +
{ + handler(); + } + : () => {} + } + > +
  • + + {href ? {text} : text} + +
  • +
    +
    + ); +}; +export const SidebarMenu = ({ + exitHandler, +}: { + exitHandler: (enabled: boolean) => void; +}) => { + return ( +
    + + + + + + exitHandler(false)} + > +
    + ); +}; diff --git a/src/Sidebar/Components/placeholder.jpg b/src/Sidebar/Components/placeholder.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6789d3b92c5186c9a9c91115b33a0c5690c219ed GIT binary patch literal 17203 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 void; +}) => { + return isEnabled ? ( +
    +
    + { + setEnable(value); + }} + > +
    +
    + ) : ( + <> + ); +}; diff --git a/src/Topbar/Topbar.css b/src/Topbar/Topbar.css new file mode 100644 index 0000000..ffd3d68 --- /dev/null +++ b/src/Topbar/Topbar.css @@ -0,0 +1,10 @@ +.topbar { + width: 100vw; + height: 10%; + z-index: 5; + display: flex; + justify-content: baseline; +} +.topbar-span .children { + margin-left: 10px; +} \ No newline at end of file diff --git a/src/Topbar/Topbar.tsx b/src/Topbar/Topbar.tsx new file mode 100644 index 0000000..0c4022f --- /dev/null +++ b/src/Topbar/Topbar.tsx @@ -0,0 +1,33 @@ +import "./Topbar.css"; +import strings from "../Intl/strings.json"; +import { useContext } from "react"; +import { LangContext } from "../context"; +import menu from "./menu.png"; +export const Topbar = ({ + setSidebarEnable, +}: { + setSidebarEnable: (enabled: boolean) => void; +}) => { + const lang = useContext(LangContext); + return ( +
    + { + setSidebarEnable(true); + }} + src={menu} + width="100px" + height="100px" + alt="Open Selection Menu" + > + +

    + {strings[lang].homepage.title} +

    + {/*

    + {strings[lang].homepage.description} +

    */} +
    +
    + ); +}; diff --git a/src/Topbar/menu.png b/src/Topbar/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..ae9b91a1382a9946f89354c78c676aaf7b396ceb GIT binary patch literal 10450 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 V7kAd3_Dtz>VW@XXw~F8r`(HRxX3GEo literal 0 HcmV?d00001 diff --git a/src/type/messageTypes.ts b/src/type/messageTypes.ts index f83594a..0bc76ee 100644 --- a/src/type/messageTypes.ts +++ b/src/type/messageTypes.ts @@ -42,5 +42,6 @@ export type Message = { content: string; timeMillis: number; }; +// Type gymnastics to provide dynamic ESLint support export const acceptedLangs = ["en_US", "zh_TW", "el_GR", "ar_SA"] as const; export type LangType = (typeof acceptedLangs)[number];