Merge pull request #15 from nbenaglia/feature/css-light-and-switch

Add themeSelector and switcher (dark and light styles)
This commit is contained in:
Phillip 2025-04-11 09:40:38 +03:00 committed by GitHub
commit 60474c2867
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
49 changed files with 2050 additions and 1707 deletions

View File

@ -2,17 +2,17 @@ module.exports = {
root: true, root: true,
env: { browser: true, es2020: true }, env: { browser: true, es2020: true },
extends: [ extends: [
'eslint:recommended', "eslint:recommended",
'plugin:@typescript-eslint/recommended', "plugin:@typescript-eslint/recommended",
'plugin:react-hooks/recommended', "plugin:react-hooks/recommended",
], ],
ignorePatterns: ['dist', '.eslintrc.cjs'], ignorePatterns: ["dist", ".eslintrc.cjs"],
parser: '@typescript-eslint/parser', parser: "@typescript-eslint/parser",
plugins: ['react-refresh'], plugins: ["react-refresh"],
rules: { rules: {
'react-refresh/only-export-components': [ "react-refresh/only-export-components": [
'off', "off",
{ allowConstantExport: true }, { allowConstantExport: true },
], ],
}, },
} };

1
.gitignore vendored
View File

@ -9,6 +9,7 @@ lerna-debug.log*
node_modules node_modules
dist dist
dist.zip
dist-ssr dist-ssr
*.local *.local

3
.prettierignore Normal file
View File

@ -0,0 +1,3 @@
node_modules
build
dist

View File

@ -1,15 +1,15 @@
import type { CapacitorConfig } from '@capacitor/cli'; import type { CapacitorConfig } from "@capacitor/cli";
const config: CapacitorConfig = { const config: CapacitorConfig = {
appId: 'org.Qortal.Qortal-Hub', appId: "org.Qortal.Qortal-Hub",
appName: 'Qortal-Hub', appName: "Qortal-Hub",
webDir: 'dist', webDir: "dist",
"plugins": { plugins: {
"LocalNotifications": { LocalNotifications: {
"smallIcon": "qort", smallIcon: "qort",
"iconColor": "#09b6e8" iconColor: "#09b6e8",
} },
} },
}; };
export default config; export default config;

BIN
dist.zip

Binary file not shown.

View File

@ -1,12 +1,9 @@
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" /> <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Qortal Hub</title> <title>Qortal Hub</title>
</head> </head>
<body> <body>

17
package-lock.json generated
View File

@ -106,6 +106,7 @@
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5", "eslint-plugin-react-refresh": "^0.4.5",
"prettier": "^3.5.3",
"rename-cli": "^6.2.1", "rename-cli": "^6.2.1",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^5.1.6", "vite": "^5.1.6",
@ -15990,6 +15991,22 @@
"node": ">= 0.8.0" "node": ">= 0.8.0"
} }
}, },
"node_modules/prettier": {
"version": "3.5.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
"dev": true,
"license": "MIT",
"bin": {
"prettier": "bin/prettier.cjs"
},
"engines": {
"node": ">=14"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/pretty-bytes": { "node_modules/pretty-bytes": {
"version": "6.1.1", "version": "6.1.1",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-6.1.1.tgz",

View File

@ -6,6 +6,7 @@
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build",
"format": "prettier --write .",
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
"preview": "vite preview", "preview": "vite preview",
"test": "vitest", "test": "vitest",
@ -110,6 +111,7 @@
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5", "eslint-plugin-react-refresh": "^0.4.5",
"prettier": "^3.5.3",
"rename-cli": "^6.2.1", "rename-cli": "^6.2.1",
"typescript": "^5.2.2", "typescript": "^5.2.2",
"vite": "^5.1.6", "vite": "^5.1.6",

View File

@ -1,46 +1,49 @@
import { import { Typography, Box, TextField, InputLabel } from "@mui/material";
AppBar,
Button,
Toolbar,
Typography,
Box,
TextField,
InputLabel,
} from "@mui/material";
import { styled } from "@mui/system"; import { styled } from "@mui/system";
export const AppContainer = styled(Box)(({ theme }) => ({ export const AppContainer = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
flexDirection: 'column', flexDirection: "column",
width: "100vw", width: "100vw",
background: "rgba(39, 40, 44, 1)", background: "rgba(39, 40, 44, 1)",
height: "100vh", height: "100vh",
radius: "15px", radius: "15px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
overflow: 'hidden' overflow: 'hidden'
})); }));
export const AuthenticatedContainer = styled(Box)(({ theme }) => ({ export const AuthenticatedContainer = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
width: "100%", width: "100%",
height: "100%", height: "100%",
justifyContent: "space-between" justifyContent: "space-between",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const AuthenticatedContainerInnerLeft = styled(Box)(({ theme }) => ({ export const AuthenticatedContainerInnerLeft = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
flexDirection: 'column', flexDirection: "column",
height: "100%", height: "100%",
width: "100%" width: "100%",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const AuthenticatedContainerInnerRight = styled(Box)(({ theme }) => ({ export const AuthenticatedContainerInnerRight = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
flexDirection: 'column', flexDirection: "column",
width: "60px", width: "60px",
height: "100%", height: "100%",
background: "rgba(0, 0, 0, 0.1)" background: "rgba(0, 0, 0, 0.1)",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const AuthenticatedContainerInnerTop = styled(Box)(({ theme }) => ({ export const AuthenticatedContainerInnerTop = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
@ -48,105 +51,129 @@ export const AuthenticatedContainerInnerTop = styled(Box)(({ theme }) => ({
width: "100%px", width: "100%px",
height: "60px", height: "60px",
background: "rgba(0, 0, 0, 0.1)", background: "rgba(0, 0, 0, 0.1)",
padding: '20px' padding: "20px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const TextP = styled(Typography)(({ theme }) => ({ export const TextP = styled(Typography)(({ theme }) => ({
fontSize: "13px", fontSize: "13px",
fontWeight: 600, fontWeight: 600,
fontFamily: "Inter", fontFamily: "Inter",
color: "white" backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const TextItalic = styled("span")(({ theme }) => ({ export const TextItalic = styled("span")(({ theme }) => ({
fontSize: "13px", fontSize: "13px",
fontWeight: 600, fontWeight: 600,
fontFamily: "Inter", fontFamily: "Inter",
color: "white", fontStyle: "italic",
fontStyle: "italic" backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const TextSpan = styled("span")(({ theme }) => ({ export const TextSpan = styled("span")(({ theme }) => ({
fontSize: "13px", fontSize: "13px",
fontFamily: "Inter", fontFamily: "Inter",
fontWeight: 800, fontWeight: 800,
color: "white" backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
})); }));
export const AddressBox = styled(Box)` export const AddressBox = styled(Box)(({ theme }) => ({
display: flex; display: "flex",
border: 1px solid var(--50-white, rgba(255, 255, 255, 0.5)); border: `1px solid ${
justify-content: space-between; theme.palette.mode === "dark"
align-items: center; ? "rgba(255, 255, 255, 0.5)"
width: auto; : "rgba(0, 0, 0, 0.3)"
height: 25px; }`,
padding: 5px 15px 5px 15px; justifyContent: "space-between",
gap: 5px; alignItems: "center",
border-radius: 100px; width: "auto",
font-family: Inter; height: "25px",
font-size: 12px; padding: "5px 15px",
font-weight: 600; gap: "5px",
line-height: 14.52px; borderRadius: "100px",
text-align: left; fontFamily: "Inter",
color: var(--50-white, rgba(255, 255, 255, 0.5)); fontSize: "12px",
cursor: pointer; fontWeight: 600,
transition: all 0.2s; lineHeight: "14.52px",
&:hover { textAlign: "left",
background-color: rgba(41, 41, 43, 1); backgroundColor: theme.palette.background.default,
color: white; color: theme.palette.text.primary,
svg path { cursor: "pointer",
fill: white; // Fill color changes to white on hover transition: "all 0.2s",
}
}
` "&:hover": {
backgroundColor:
theme.palette.mode === "dark"
? "rgba(41, 41, 43, 1)"
: "rgba(240, 240, 240, 1)",
color: theme.palette.mode === "dark" ? "#fff" : "#000",
export const CustomButton = styled(Box)` "svg path": {
fill: theme.palette.mode === "dark" ? "#fff" : "#000",
},
},
}));
/* Authenticate */ export const CustomButton = styled(Box)(({ theme }) => ({
boxSizing: "border-box",
padding: "15px 20px",
gap: "10px",
box-sizing: border-box; border: `0.5px solid ${
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.3)"
}`,
filter: "drop-shadow(1px 4px 10.5px rgba(0, 0, 0, 0.3))",
borderRadius: "5px",
padding: 15px 20px; display: "inline-flex",
gap: 10px; justifyContent: "center",
alignItems: "center",
width: "fit-content",
minWidth: "160px",
cursor: "pointer",
transition: "all 0.2s",
border: 0.5px solid rgba(255, 255, 255, 0.5); fontWeight: 600,
filter: drop-shadow(1px 4px 10.5px rgba(0, 0, 0, 0.3)); fontFamily: "Inter",
border-radius: 5px; textAlign: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
display: inline-flex; "&:hover": {
backgroundColor:
theme.palette.mode === "dark"
? "rgba(41, 41, 43, 1)"
: "rgba(230, 230, 230, 1)",
color: "#fff",
justify-content: center; "svg path": {
align-items: center; fill: "#fff",
},
},
}));
width: fit-content;
transition: all 0.2s;
color: black;
min-width: 160px;
cursor: pointer;
font-weight: 600;
font-family: Inter;
color: white;
text-align: center;
&:hover {
background-color: rgba(41, 41, 43, 1);
color: white;
svg path {
fill: white; // Fill color changes to white on hover
}
}
`;
interface CustomButtonProps { interface CustomButtonProps {
bgColor?: string; bgColor?: string;
color?: string; color?: string;
} }
export const CustomButtonAccept = styled(Box)<CustomButtonProps>( export const CustomButtonAccept = styled(Box)<CustomButtonProps>(
({ bgColor, color }) => ({ ({ bgColor, color, theme }) => ({
boxSizing: "border-box", boxSizing: "border-box",
padding: "15px 20px", padding: "15px 20px",
gap: "10px", gap: "10px",
border: "0.5px solid rgba(255, 255, 255, 0.5)", border: `0.5px solid ${
theme.palette.mode === "dark"
? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.3)"
}`,
filter: "drop-shadow(1px 4px 10.5px rgba(0,0,0,0.3))", filter: "drop-shadow(1px 4px 10.5px rgba(0,0,0,0.3))",
borderRadius: 5, borderRadius: 5,
display: "inline-flex", display: "inline-flex",
@ -160,31 +187,31 @@ export const CustomButtonAccept = styled(Box)<CustomButtonProps>(
fontFamily: "Inter", fontFamily: "Inter",
textAlign: "center", textAlign: "center",
opacity: 0.7, opacity: 0.7,
// Use the passed-in props or fallback defaults
backgroundColor: bgColor || "transparent", // Color and backgroundColor with fallbacks
color: color || "white", backgroundColor: bgColor || (theme.palette.mode === "dark" ? "#1d1d1d" : "#f5f5f5"),
color: color || (theme.palette.mode === "dark" ? "#fff" : "#000"),
"&:hover": { "&:hover": {
opacity: 1, opacity: 1,
backgroundColor: bgColor backgroundColor: bgColor || (theme.palette.mode === "dark" ? "rgba(41, 41, 43, 1)" : "rgba(230, 230, 230, 1)"),
? bgColor color: color || "#fff",
: "rgba(41, 41, 43, 1)", // fallback hover bg
color: color || "white",
svg: { svg: {
path: { path: {
fill: color || "white", fill: color || "#fff",
}, },
}, },
}, },
}) })
); );
export const CustomInput = styled(TextField)(({ theme }) => ({
export const CustomInput = styled(TextField)({
width: "183px", // Adjust the width as needed width: "183px", // Adjust the width as needed
borderRadius: "5px", borderRadius: "5px",
// backgroundColor: "rgba(30, 30, 32, 1)", // backgroundColor: "rgba(30, 30, 32, 1)",
outline: "none", outline: "none",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
input: { input: {
fontSize: 10, fontSize: 10,
fontFamily: "Inter", fontFamily: "Inter",
@ -199,13 +226,13 @@ export const CustomInput = styled(TextField)({
}, },
"& .MuiOutlinedInput-root": { "& .MuiOutlinedInput-root": {
"& fieldset": { "& fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)', border: "0.5px solid rgba(255, 255, 255, 0.5)",
}, },
"&:hover fieldset": { "&:hover fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)', border: "0.5px solid rgba(255, 255, 255, 0.5)",
}, },
"&.Mui-focused fieldset": { "&.Mui-focused fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)', border: "0.5px solid rgba(255, 255, 255, 0.5)",
}, },
}, },
"& .MuiInput-underline:before": { "& .MuiInput-underline:before": {
@ -217,13 +244,15 @@ export const CustomInput = styled(TextField)({
"& .MuiInput-underline:after": { "& .MuiInput-underline:after": {
borderBottom: "none", borderBottom: "none",
}, },
}); }));
export const CustomLabel = styled(InputLabel)` export const CustomLabel = styled(InputLabel)(({ theme }) => ({
font-weight: 400; fontWeight: 400,
font-family: Inter; fontFamily: "Inter",
font-size: 10px; fontSize: "10px",
line-height: 12px; lineHeight: "12px",
color: rgba(255, 255, 255, 0.5); color:
theme.palette.mode === "dark"
` ? "rgba(255, 255, 255, 0.5)"
: "rgba(0, 0, 0, 0.5)",
}));

View File

View File

@ -6,7 +6,6 @@ import {
useRef, useRef,
useState, useState,
} from "react"; } from "react";
import "./App.css";
import { useDropzone } from "react-dropzone"; import { useDropzone } from "react-dropzone";
import { import {
Box, Box,
@ -3562,4 +3561,4 @@ function App() {
); );
} }
export default App; export default App;

View File

@ -1008,4 +1008,4 @@ export const NotAuthenticated = ({
</ButtonBase> </ButtonBase>
</> </>
); );
}; };

View File

@ -1,6 +1,8 @@
import React from "react"; import { useTheme } from "@mui/material";
export const AppsIcon = ({ height = 31, width = 31 }) => {
const theme = useTheme();
export const AppsIcon = ({ color, height = 31, width = 31 }) => {
return ( return (
<svg <svg
width={width} width={width}
@ -11,39 +13,39 @@ export const AppsIcon = ({ color, height = 31, width = 31 }) => {
> >
<path <path
d="M3.76596 7.53192C5.84584 7.53192 7.53192 5.84584 7.53192 3.76596C7.53192 1.68608 5.84584 0 3.76596 0C1.68608 0 0 1.68608 0 3.76596C0 5.84584 1.68608 7.53192 3.76596 7.53192Z" d="M3.76596 7.53192C5.84584 7.53192 7.53192 5.84584 7.53192 3.76596C7.53192 1.68608 5.84584 0 3.76596 0C1.68608 0 0 1.68608 0 3.76596C0 5.84584 1.68608 7.53192 3.76596 7.53192Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M15 7.53192C17.0799 7.53192 18.766 5.84584 18.766 3.76596C18.766 1.68608 17.0799 0 15 0C12.9201 0 11.2341 1.68608 11.2341 3.76596C11.2341 5.84584 12.9201 7.53192 15 7.53192Z" d="M15 7.53192C17.0799 7.53192 18.766 5.84584 18.766 3.76596C18.766 1.68608 17.0799 0 15 0C12.9201 0 11.2341 1.68608 11.2341 3.76596C11.2341 5.84584 12.9201 7.53192 15 7.53192Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M26.234 7.53192C28.3139 7.53192 30 5.84584 30 3.76596C30 1.68608 28.3139 0 26.234 0C24.1542 0 22.4681 1.68608 22.4681 3.76596C22.4681 5.84584 24.1542 7.53192 26.234 7.53192Z" d="M26.234 7.53192C28.3139 7.53192 30 5.84584 30 3.76596C30 1.68608 28.3139 0 26.234 0C24.1542 0 22.4681 1.68608 22.4681 3.76596C22.4681 5.84584 24.1542 7.53192 26.234 7.53192Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M3.76596 30.0001C5.84584 30.0001 7.53192 28.314 7.53192 26.2341C7.53192 24.1542 5.84584 22.4681 3.76596 22.4681C1.68608 22.4681 0 24.1542 0 26.2341C0 28.314 1.68608 30.0001 3.76596 30.0001Z" d="M3.76596 30.0001C5.84584 30.0001 7.53192 28.314 7.53192 26.2341C7.53192 24.1542 5.84584 22.4681 3.76596 22.4681C1.68608 22.4681 0 24.1542 0 26.2341C0 28.314 1.68608 30.0001 3.76596 30.0001Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M15 30.0002C17.0799 30.0002 18.766 28.3141 18.766 26.2342C18.766 24.1543 17.0799 22.4683 15 22.4683C12.9201 22.4683 11.2341 24.1543 11.2341 26.2342C11.2341 28.3141 12.9201 30.0002 15 30.0002Z" d="M15 30.0002C17.0799 30.0002 18.766 28.3141 18.766 26.2342C18.766 24.1543 17.0799 22.4683 15 22.4683C12.9201 22.4683 11.2341 24.1543 11.2341 26.2342C11.2341 28.3141 12.9201 30.0002 15 30.0002Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M26.234 30.0002C28.3139 30.0002 30 28.3141 30 26.2342C30 24.1543 28.3139 22.4683 26.234 22.4683C24.1542 22.4683 22.4681 24.1543 22.4681 26.2342C22.4681 28.3141 24.1542 30.0002 26.234 30.0002Z" d="M26.234 30.0002C28.3139 30.0002 30 28.3141 30 26.2342C30 24.1543 28.3139 22.4683 26.234 22.4683C24.1542 22.4683 22.4681 24.1543 22.4681 26.2342C22.4681 28.3141 24.1542 30.0002 26.234 30.0002Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M3.76596 18.766C5.84584 18.766 7.53192 17.08 7.53192 15.0001C7.53192 12.9202 5.84584 11.2341 3.76596 11.2341C1.68608 11.2341 0 12.9202 0 15.0001C0 17.08 1.68608 18.766 3.76596 18.766Z" d="M3.76596 18.766C5.84584 18.766 7.53192 17.08 7.53192 15.0001C7.53192 12.9202 5.84584 11.2341 3.76596 11.2341C1.68608 11.2341 0 12.9202 0 15.0001C0 17.08 1.68608 18.766 3.76596 18.766Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M15 18.766C17.0799 18.766 18.766 17.08 18.766 15.0001C18.766 12.9202 17.0799 11.2341 15 11.2341C12.9201 11.2341 11.2341 12.9202 11.2341 15.0001C11.2341 17.08 12.9201 18.766 15 18.766Z" d="M15 18.766C17.0799 18.766 18.766 17.08 18.766 15.0001C18.766 12.9202 17.0799 11.2341 15 11.2341C12.9201 11.2341 11.2341 12.9202 11.2341 15.0001C11.2341 17.08 12.9201 18.766 15 18.766Z"
fill={color} fill={theme.palette.text.primary}
/> />
<path <path
d="M26.234 18.766C28.3139 18.766 30 17.08 30 15.0001C30 12.9202 28.3139 11.2341 26.234 11.2341C24.1542 11.2341 22.4681 12.9202 22.4681 15.0001C22.4681 17.08 24.1542 18.766 26.234 18.766Z" d="M26.234 18.766C28.3139 18.766 30 17.08 30 15.0001C30 12.9202 28.3139 11.2341 26.234 11.2341C24.1542 11.2341 22.4681 12.9202 22.4681 15.0001C22.4681 17.08 24.1542 18.766 26.234 18.766Z"
fill={color} fill={theme.palette.text.primary}
/> />
</svg> </svg>
); );

View File

@ -1,12 +1,20 @@
import React from 'react'; import { useTheme } from "@mui/material";
export const HomeIcon= ({ color, height = 20, width = 23 }) => { export const HomeIcon = ({ height = 20, width = 23 }) => {
return ( const theme = useTheme();
<svg width={width} height={height} viewBox="0 0 23 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.936 11.9842C22.8122 12.2972 22.5127 12.502 22.1801 12.5008H19.7155V19.1668C19.714 19.6263 19.3471 19.9985 18.8939 20H14.7862V14.1673C14.7862 12.3265 13.3149 10.8343 11.5 10.8343C9.68509 10.8343 8.21381 12.3265 8.21381 14.1673V20H4.10607C3.65294 19.9985 3.28596 19.6263 3.28452 19.1668V12.5008H0.819874C0.487346 12.502 0.187777 12.2972 0.0640491 11.9842C-0.0642812 11.6739 0.00375033 11.3157 0.236574 11.076L10.9167 0.243778C11.2395 -0.0812593 11.7605 -0.0812593 12.0833 0.243778L22.7634 11.076C22.9963 11.3157 23.0643 11.6739 22.936 11.9842Z" fill={color}/>
</svg>
); return (
}; <svg
width={width}
height={height}
viewBox="0 0 23 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M22.936 11.9842C22.8122 12.2972 22.5127 12.502 22.1801 12.5008H19.7155V19.1668C19.714 19.6263 19.3471 19.9985 18.8939 20H14.7862V14.1673C14.7862 12.3265 13.3149 10.8343 11.5 10.8343C9.68509 10.8343 8.21381 12.3265 8.21381 14.1673V20H4.10607C3.65294 19.9985 3.28596 19.6263 3.28452 19.1668V12.5008H0.819874C0.487346 12.502 0.187777 12.2972 0.0640491 11.9842C-0.0642812 11.6739 0.00375033 11.3157 0.236574 11.076L10.9167 0.243778C11.2395 -0.0812593 11.7605 -0.0812593 12.0833 0.243778L22.7634 11.076C22.9963 11.3157 23.0643 11.6739 22.936 11.9842Z"
fill={theme.palette.text.primary}
/>
</svg>
);
};

View File

@ -3,7 +3,7 @@ import React from 'react';
export const LogoutIcon= ({ color, height = 20, width = 18}) => { export const LogoutIcon= ({ color, height = 20, width = 18}) => {
return ( return (
<svg width={width} height={height} viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width={width} height={height} viewBox="0 0 18 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.4351 0H1.63891C0.733765 0 0 0.727797 0 1.62558V18.3744C0 19.2722 0.733765 20 1.63891 20H10.4351C11.3403 20 12.0741 19.2722 12.0741 18.3744V12.6013H7.38321C6.54312 12.6013 5.85964 11.9039 5.85964 11.0467V8.87329C5.85964 8.01613 6.54312 7.31875 7.38323 7.31875H12.0741V1.62558C12.0741 0.727797 11.3403 0 10.4351 0ZM6.83334 11.0467C6.83334 11.3719 7.07952 11.6354 7.38321 11.6354H13.1856C13.2548 11.6354 13.3109 11.6955 13.3109 11.7696V12.8632C13.3109 13.3492 13.8299 13.6259 14.1922 13.3329L17.7816 10.4298C18.0728 10.1942 18.0728 9.72579 17.7816 9.49024L14.1922 6.58709C13.8299 6.29409 13.3109 6.57077 13.3109 7.05684V8.1504C13.3109 8.2245 13.2548 8.28454 13.1856 8.28454H7.38322C7.07952 8.28454 6.83334 8.54813 6.83334 8.87329V11.0467Z" fill={color} /> <path fillRule="evenodd" clipRule="evenodd" d="M10.4351 0H1.63891C0.733765 0 0 0.727797 0 1.62558V18.3744C0 19.2722 0.733765 20 1.63891 20H10.4351C11.3403 20 12.0741 19.2722 12.0741 18.3744V12.6013H7.38321C6.54312 12.6013 5.85964 11.9039 5.85964 11.0467V8.87329C5.85964 8.01613 6.54312 7.31875 7.38323 7.31875H12.0741V1.62558C12.0741 0.727797 11.3403 0 10.4351 0ZM6.83334 11.0467C6.83334 11.3719 7.07952 11.6354 7.38321 11.6354H13.1856C13.2548 11.6354 13.3109 11.6955 13.3109 11.7696V12.8632C13.3109 13.3492 13.8299 13.6259 14.1922 13.3329L17.7816 10.4298C18.0728 10.1942 18.0728 9.72579 17.7816 9.49024L14.1922 6.58709C13.8299 6.29409 13.3109 6.57077 13.3109 7.05684V8.1504C13.3109 8.2245 13.2548 8.28454 13.1856 8.28454H7.38322C7.07952 8.28454 6.83334 8.54813 6.83334 8.87329V11.0467Z" fill={color} />
</svg> </svg>

View File

@ -1,13 +1,30 @@
import React from 'react'; import { useTheme } from "@mui/material";
export const MessagingIcon= ({ color, height = 31, width = 31 }) => { export const MessagingIcon = ({ color, height = 31, width = 31 }) => {
return ( const theme = useTheme();
<svg width={width} height={height} viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.3937 4.49877C23.6712 1.56681 3.1922 8.74911 3.20912 11.3714C3.22829 14.345 11.2067 15.2597 13.4181 15.8802C14.748 16.2532 15.1041 16.6357 15.4107 18.0302C16.7995 24.3457 17.4967 27.487 19.0859 27.5571C21.6189 27.6691 29.0507 7.36011 26.3937 4.49877Z" stroke={color} stroke-width="2"/>
<path d="M14.4591 16.3076L18.8341 11.9326" stroke={color} stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
); const setColor = color ? color : theme.palette.text.primary
};
return (
<svg
width={width}
height={height}
viewBox="0 0 31 31"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M26.3937 4.49877C23.6712 1.56681 3.1922 8.74911 3.20912 11.3714C3.22829 14.345 11.2067 15.2597 13.4181 15.8802C14.748 16.2532 15.1041 16.6357 15.4107 18.0302C16.7995 24.3457 17.4967 27.487 19.0859 27.5571C21.6189 27.6691 29.0507 7.36011 26.3937 4.49877Z"
stroke={setColor}
strokeWidth="2"
/>
<path
d="M14.4591 16.3076L18.8341 11.9326"
stroke={setColor}
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};

View File

@ -3,7 +3,7 @@ import React from 'react';
export const MessagingIcon2= ({ color = '#8F8F91', height = 24, width =24 }) => { export const MessagingIcon2= ({ color = '#8F8F91', height = 24, width =24 }) => {
return ( return (
<svg width={width} height={height} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width={width} height={height} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.6636 0.00168233C22.6127 -0.000756257 22.5614 -0.000627677 22.5099 0.00261984C22.3724 0.0112798 22.2331 0.0405753 22.0969 0.093558L1.02096 8.28971C0.362343 8.54585 -0.00366118 9.18408 2.76147e-05 9.79253C0.00371641 10.401 0.377567 11.0341 1.03925 11.2822L9.02065 14.2752C9.34631 14.3974 9.60258 14.6536 9.72471 14.9793L12.7177 22.9607C12.9658 23.6224 13.5989 23.9963 14.2074 24C14.8158 24.0037 15.454 23.6376 15.7102 22.979L23.9063 1.90295C24.1182 1.35797 23.9526 0.768987 23.5917 0.408091C23.3549 0.171254 23.02 0.0187526 22.6636 0.00168233ZM18.4022 4.99812C18.5613 4.99815 18.7139 5.06138 18.8264 5.17391C18.9389 5.28643 19.0021 5.43902 19.0021 5.59813C19.0021 5.75724 18.9389 5.90983 18.8264 6.02235L13.2239 11.6244C13.1114 11.7369 12.9588 11.8001 12.7997 11.8001C12.6406 11.8001 12.488 11.7369 12.3755 11.6244C12.263 11.5119 12.1998 11.3593 12.1998 11.2002C12.1998 11.0411 12.263 10.8885 12.3755 10.776L17.9775 5.17391C18.0333 5.11813 18.0995 5.0739 18.1724 5.04374C18.2452 5.01357 18.3233 4.99807 18.4022 4.99812Z" fill={color}/> <path fillRule="evenodd" clipRule="evenodd" d="M22.6636 0.00168233C22.6127 -0.000756257 22.5614 -0.000627677 22.5099 0.00261984C22.3724 0.0112798 22.2331 0.0405753 22.0969 0.093558L1.02096 8.28971C0.362343 8.54585 -0.00366118 9.18408 2.76147e-05 9.79253C0.00371641 10.401 0.377567 11.0341 1.03925 11.2822L9.02065 14.2752C9.34631 14.3974 9.60258 14.6536 9.72471 14.9793L12.7177 22.9607C12.9658 23.6224 13.5989 23.9963 14.2074 24C14.8158 24.0037 15.454 23.6376 15.7102 22.979L23.9063 1.90295C24.1182 1.35797 23.9526 0.768987 23.5917 0.408091C23.3549 0.171254 23.02 0.0187526 22.6636 0.00168233ZM18.4022 4.99812C18.5613 4.99815 18.7139 5.06138 18.8264 5.17391C18.9389 5.28643 19.0021 5.43902 19.0021 5.59813C19.0021 5.75724 18.9389 5.90983 18.8264 6.02235L13.2239 11.6244C13.1114 11.7369 12.9588 11.8001 12.7997 11.8001C12.6406 11.8001 12.488 11.7369 12.3755 11.6244C12.263 11.5119 12.1998 11.3593 12.1998 11.2002C12.1998 11.0411 12.263 10.8885 12.3755 10.776L17.9775 5.17391C18.0333 5.11813 18.0995 5.0739 18.1724 5.04374C18.2452 5.01357 18.3233 4.99807 18.4022 4.99812Z" fill={color}/>
</svg> </svg>

View File

@ -3,7 +3,7 @@ import React from 'react';
export const NotificationIcon2= ({ color = 'white', height = 15, width = 15 }) => { export const NotificationIcon2= ({ color = 'white', height = 15, width = 15 }) => {
return ( return (
<svg width={width} height={height} viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width={width} height={height} viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.50253 0.80505C8.50253 0.360285 8.14231 0 7.69818 0C7.25348 0 6.89325 0.36027 6.89325 0.80505V1.6142C6.89325 2.05896 7.25346 2.41866 7.69818 2.41866C8.14229 2.41866 8.50253 2.05839 8.50253 1.61361V0.80505ZM7.06691 3.12343C7.45178 2.90163 7.944 3.03366 8.16577 3.41857L12.3049 10.5872C12.5231 10.9715 12.3905 11.4603 12.0074 11.6815C11.6243 11.9027 11.1344 11.773 10.9109 11.3916L10.8517 11.2884L7.53454 12.0588C7.73401 12.7922 7.56388 13.5767 7.07751 14.1606C6.59173 14.7444 5.85192 15.0548 5.09454 14.992C4.33771 14.9286 3.65892 14.5009 3.27588 13.8443L3.27353 13.8414L2.86989 13.1431L1.30986 13.5046L1.31045 13.504C1.08047 13.5574 0.842856 13.4547 0.724941 13.2499L0.0713702 12.118C-0.0459665 11.9138 -0.0166327 11.6562 0.144705 11.4837L6.83346 4.32684L6.77245 4.22298C6.66567 4.03814 6.63633 3.8187 6.69207 3.61216C6.74722 3.40561 6.8821 3.23022 7.06691 3.12343ZM4.50841 12.7617L5.96397 12.4237C6.09539 12.7746 5.9364 13.1683 5.59729 13.3279C5.25819 13.4875 4.85338 13.3602 4.66623 13.0351L4.50841 12.7617ZM15 7.30235C15 7.51593 14.9155 7.72072 14.7647 7.87152C14.614 8.02232 14.4092 8.1074 14.1957 8.1074H13.3866C12.9419 8.1074 12.5823 7.74713 12.5823 7.30235C12.5823 6.85817 12.9425 6.49788 13.3872 6.49788H14.1951C14.6398 6.49788 15 6.85815 15 7.30235ZM2.01088 8.10681C2.45558 8.10681 2.81582 7.74713 2.81582 7.30235C2.81582 6.85817 2.4556 6.49788 2.01088 6.49788H1.20185C0.757149 6.49788 0.397502 6.85815 0.397502 7.30235C0.397502 7.74711 0.75772 8.1074 1.20244 8.1074H2.01147L2.01088 8.10681ZM4.35176 3.95659C4.03789 4.2705 3.52864 4.27109 3.21477 3.95717L2.53481 3.27712C2.37465 3.12808 2.28253 2.92036 2.27843 2.70209C2.27491 2.48381 2.35998 2.27374 2.51428 2.11884C2.66857 1.96453 2.8792 1.87943 3.09744 1.88355C3.31568 1.88766 3.52278 1.97978 3.6718 2.13937L4.35295 2.81826C4.50431 2.96906 4.58879 3.17443 4.58879 3.38802C4.58879 3.60161 4.50431 3.80639 4.35295 3.95719L4.35176 3.95659ZM12.861 3.27653L12.8616 3.27712C13.1567 2.95967 13.1479 2.46562 12.8416 2.15932C12.5354 1.85302 12.0414 1.84422 11.724 2.13937L11.0352 2.82589C10.7214 3.1398 10.7214 3.6503 11.0352 3.9648C11.3497 4.27872 11.8595 4.27872 12.1734 3.9648L12.861 3.27829V3.27653Z" fill={color}/> <path fillRule="evenodd" clipRule="evenodd" d="M8.50253 0.80505C8.50253 0.360285 8.14231 0 7.69818 0C7.25348 0 6.89325 0.36027 6.89325 0.80505V1.6142C6.89325 2.05896 7.25346 2.41866 7.69818 2.41866C8.14229 2.41866 8.50253 2.05839 8.50253 1.61361V0.80505ZM7.06691 3.12343C7.45178 2.90163 7.944 3.03366 8.16577 3.41857L12.3049 10.5872C12.5231 10.9715 12.3905 11.4603 12.0074 11.6815C11.6243 11.9027 11.1344 11.773 10.9109 11.3916L10.8517 11.2884L7.53454 12.0588C7.73401 12.7922 7.56388 13.5767 7.07751 14.1606C6.59173 14.7444 5.85192 15.0548 5.09454 14.992C4.33771 14.9286 3.65892 14.5009 3.27588 13.8443L3.27353 13.8414L2.86989 13.1431L1.30986 13.5046L1.31045 13.504C1.08047 13.5574 0.842856 13.4547 0.724941 13.2499L0.0713702 12.118C-0.0459665 11.9138 -0.0166327 11.6562 0.144705 11.4837L6.83346 4.32684L6.77245 4.22298C6.66567 4.03814 6.63633 3.8187 6.69207 3.61216C6.74722 3.40561 6.8821 3.23022 7.06691 3.12343ZM4.50841 12.7617L5.96397 12.4237C6.09539 12.7746 5.9364 13.1683 5.59729 13.3279C5.25819 13.4875 4.85338 13.3602 4.66623 13.0351L4.50841 12.7617ZM15 7.30235C15 7.51593 14.9155 7.72072 14.7647 7.87152C14.614 8.02232 14.4092 8.1074 14.1957 8.1074H13.3866C12.9419 8.1074 12.5823 7.74713 12.5823 7.30235C12.5823 6.85817 12.9425 6.49788 13.3872 6.49788H14.1951C14.6398 6.49788 15 6.85815 15 7.30235ZM2.01088 8.10681C2.45558 8.10681 2.81582 7.74713 2.81582 7.30235C2.81582 6.85817 2.4556 6.49788 2.01088 6.49788H1.20185C0.757149 6.49788 0.397502 6.85815 0.397502 7.30235C0.397502 7.74711 0.75772 8.1074 1.20244 8.1074H2.01147L2.01088 8.10681ZM4.35176 3.95659C4.03789 4.2705 3.52864 4.27109 3.21477 3.95717L2.53481 3.27712C2.37465 3.12808 2.28253 2.92036 2.27843 2.70209C2.27491 2.48381 2.35998 2.27374 2.51428 2.11884C2.66857 1.96453 2.8792 1.87943 3.09744 1.88355C3.31568 1.88766 3.52278 1.97978 3.6718 2.13937L4.35295 2.81826C4.50431 2.96906 4.58879 3.17443 4.58879 3.38802C4.58879 3.60161 4.50431 3.80639 4.35295 3.95719L4.35176 3.95659ZM12.861 3.27653L12.8616 3.27712C13.1567 2.95967 13.1479 2.46562 12.8416 2.15932C12.5354 1.85302 12.0414 1.84422 11.724 2.13937L11.0352 2.82589C10.7214 3.1398 10.7214 3.6503 11.0352 3.9648C11.3497 4.27872 11.8595 4.27872 12.1734 3.9648L12.861 3.27829V3.27653Z" fill={color}/>
</svg> </svg>
); );

View File

@ -3,7 +3,7 @@ import React from 'react';
export const ThreadsIcon= ({ color = 'white', height = 11, width = 15 }) => { export const ThreadsIcon= ({ color = 'white', height = 11, width = 15 }) => {
return ( return (
<svg width={width} height={height} viewBox="0 0 15 11" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width={width} height={height} viewBox="0 0 15 11" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.76526 1.80943H6.51017C5.91236 1.80943 5.42723 2.37147 5.42723 3.06406V6.55419V6.82615H4L1.90297 9L2.00782 6.82615H0.8482C0.380282 6.82615 0 6.38558 0 5.84347V0.982675C0 0.440572 0.380282 0 0.8482 0H7.1518C7.62128 0 8 0.440572 8 0.982675V1.80943H7.76526ZM8.89437 2H14.0458C14.5722 2 15 2.44057 15 2.98268V7.84166C15 8.38558 14.5722 8.82434 14.0458 8.82434H12.7412L12.8592 11L10.5 8.82434H6.95423C6.42606 8.82434 6 8.38558 6 7.84166V7.01672V6.74476V6.47281V2.98268C6 2.44057 6.42606 2 6.95423 2H8.3662H8.63028H8.89437Z" fill={color}/> <path fillRule="evenodd" clipRule="evenodd" d="M7.76526 1.80943H6.51017C5.91236 1.80943 5.42723 2.37147 5.42723 3.06406V6.55419V6.82615H4L1.90297 9L2.00782 6.82615H0.8482C0.380282 6.82615 0 6.38558 0 5.84347V0.982675C0 0.440572 0.380282 0 0.8482 0H7.1518C7.62128 0 8 0.440572 8 0.982675V1.80943H7.76526ZM8.89437 2H14.0458C14.5722 2 15 2.44057 15 2.98268V7.84166C15 8.38558 14.5722 8.82434 14.0458 8.82434H12.7412L12.8592 11L10.5 8.82434H6.95423C6.42606 8.82434 6 8.38558 6 7.84166V7.01672V6.74476V6.47281V2.98268C6 2.44057 6.42606 2 6.95423 2H8.3662H8.63028H8.89437Z" fill={color}/>
</svg> </svg>

View File

@ -1,12 +1,26 @@
import React from 'react'; import React from "react";
export const WalletIcon= ({ color, height, width }) => { export const WalletIcon = ({ color, height, width }) => {
return ( return (
<svg width={width || 30} height={width || 30} viewBox="0 0 31 31" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg
<path d="M19.0118 22.0891C18.0124 22.8671 16.6997 23.3391 15.2618 23.3391C13.8241 23.3391 12.5113 22.8671 11.5118 22.0891" stroke={color} stroke-width="2" stroke-linecap="round"/> width={width || 30}
<path d="M3.20108 17.356C2.7598 14.4844 2.53917 13.0486 3.08205 11.7758C3.62493 10.503 4.82938 9.63215 7.23827 7.89044L9.03808 6.58911C12.0347 4.42245 13.5331 3.33911 15.2618 3.33911C16.9907 3.33911 18.4889 4.42245 21.4856 6.58911L23.2854 7.89044C25.6943 9.63215 26.8988 10.503 27.4417 11.7758C27.9846 13.0486 27.7639 14.4844 27.3226 17.356L26.9463 19.8046C26.3208 23.8752 26.0079 25.9106 24.5481 27.1249C23.0882 28.3391 20.9539 28.3391 16.6853 28.3391H13.8383C9.56977 28.3391 7.43548 28.3391 5.97559 27.1249C4.5157 25.9106 4.20293 23.8752 3.57738 19.8046L3.20108 17.356Z" stroke={color} stroke-width="2" stroke-linejoin="round"/> height={width || 30}
</svg> viewBox="0 0 31 31"
fill="none"
); xmlns="http://www.w3.org/2000/svg"
}; >
<path
d="M19.0118 22.0891C18.0124 22.8671 16.6997 23.3391 15.2618 23.3391C13.8241 23.3391 12.5113 22.8671 11.5118 22.0891"
stroke={color}
strokeWidth="2"
strokeLinecap="round"
/>
<path
d="M3.20108 17.356C2.7598 14.4844 2.53917 13.0486 3.08205 11.7758C3.62493 10.503 4.82938 9.63215 7.23827 7.89044L9.03808 6.58911C12.0347 4.42245 13.5331 3.33911 15.2618 3.33911C16.9907 3.33911 18.4889 4.42245 21.4856 6.58911L23.2854 7.89044C25.6943 9.63215 26.8988 10.503 27.4417 11.7758C27.9846 13.0486 27.7639 14.4844 27.3226 17.356L26.9463 19.8046C26.3208 23.8752 26.0079 25.9106 24.5481 27.1249C23.0882 28.3391 20.9539 28.3391 16.6853 28.3391H13.8383C9.56977 28.3391 7.43548 28.3391 5.97559 27.1249C4.5157 25.9106 4.20293 23.8752 3.57738 19.8046L3.20108 17.356Z"
stroke={color}
strokeWidth="2"
strokeLinejoin="round"
/>
</svg>
);
};

View File

@ -1,20 +1,27 @@
import React from 'react'; import React from "react";
import { styled } from '@mui/system'; import { styled } from "@mui/system";
import { SVGProps } from './interfaces'; import { SVGProps } from "./interfaces";
// Create a styled container with hover effects // Create a styled container with hover effects
const SvgContainer = styled('svg')({ const SvgContainer = styled("svg")({
'& path': { "& path": {
fill: 'rgba(41, 41, 43, 1)', // Default to red if no color prop fill: "rgba(41, 41, 43, 1)", // Default to red if no color prop
} },
}); });
export const CreateThreadIcon:React.FC<SVGProps> = ({ color, opacity }) => { export const CreateThreadIcon: React.FC<SVGProps> = ({ color, opacity }) => {
return ( return (
<SvgContainer width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <SvgContainer
<path d="M0 9.80209V9.0205C0.0460138 8.67679 0.080024 8.31425 0.144043 7.98466C0.469856 6.30568 1.25577 4.79934 2.38071 3.6977C4.13924 1.88262 6.22987 0.985679 8.52256 0.674927C9.9086 0.485649 11.3116 0.565177 12.6758 0.910345C14.5124 1.34351 16.1889 2.2075 17.6053 3.67886C18.7276 4.84183 19.5319 6.24257 19.858 7.98466C19.918 8.31189 19.952 8.64383 20 8.97577V9.80209C19.9827 9.8676 19.9693 9.93447 19.96 10.0022C19.8708 11.2186 19.5113 12.3861 18.9177 13.3875C17.961 15.0025 16.6297 16.2594 15.0825 17.0082C12.4657 18.3525 9.75693 18.5667 6.98209 17.8346C6.8589 17.8074 6.73157 17.8264 6.61799 17.8887C5.15955 18.7339 3.70511 19.5908 2.24867 20.4501C2.18866 20.4854 2.12464 20.5183 2.0146 20.5748L3.78714 16.3703C3.37301 16.0148 2.96889 15.7017 2.60078 15.3415C1.42243 14.1879 0.556167 12.7895 0.182055 11.0192C0.0980294 10.6213 0.060018 10.2094 0 9.80209ZM14.0042 10.5931C14.1362 10.5968 14.2676 10.5698 14.3907 10.5135C14.5138 10.4572 14.6262 10.3728 14.7214 10.2651C14.8167 10.1574 14.8928 10.0286 14.9455 9.8861C14.9982 9.7436 15.0264 9.59023 15.0285 9.43484V9.4113C15.0285 9.25517 15.0024 9.10058 14.9516 8.95634C14.9008 8.8121 14.8264 8.68104 14.7326 8.57064C14.6388 8.46025 14.5274 8.37268 14.4048 8.31293C14.2823 8.25319 14.1509 8.22243 14.0182 8.22243C13.8855 8.22243 13.7542 8.25319 13.6316 8.31293C13.509 8.37268 13.3976 8.46025 13.3038 8.57064C13.21 8.68104 13.1356 8.8121 13.0848 8.95634C13.034 9.10058 13.0079 9.25517 13.0079 9.4113C13.0074 9.56588 13.0327 9.71906 13.0825 9.86211C13.1323 10.0052 13.2055 10.1353 13.2981 10.245C13.3906 10.3547 13.5005 10.442 13.6217 10.5017C13.7429 10.5614 13.8728 10.5925 14.0042 10.5931ZM10.003 10.5931C10.203 10.5926 10.3983 10.5225 10.5644 10.3915C10.7306 10.2606 10.86 10.0746 10.9364 9.85719C11.0129 9.63976 11.0329 9.40056 10.9939 9.16977C10.9549 8.93898 10.8588 8.72694 10.7175 8.5604C10.5763 8.39385 10.3962 8.28026 10.2002 8.23396C10.0041 8.18765 9.80084 8.21071 9.61591 8.30022C9.43099 8.38973 9.27273 8.54168 9.1611 8.7369C9.04948 8.93212 8.98949 9.16187 8.9887 9.39717C8.98975 9.71356 9.09688 10.0167 9.28682 10.2406C9.47675 10.4646 9.73413 10.5912 10.003 10.5931ZM4.98349 9.3854C4.9836 9.61979 5.04316 9.8488 5.15456 10.0431C5.26595 10.2374 5.42411 10.3882 5.60876 10.476C5.79341 10.5639 5.99616 10.5849 6.19102 10.5364C6.38588 10.4878 6.56399 10.3719 6.70252 10.2035C6.84105 10.0351 6.93371 9.82183 6.96861 9.59108C7.00352 9.36032 6.97909 9.12255 6.89845 8.90823C6.8178 8.69392 6.68463 8.51281 6.51597 8.38811C6.34732 8.26342 6.15087 8.20081 5.95179 8.20831C5.69208 8.21809 5.44579 8.34641 5.26507 8.56611C5.08434 8.78581 4.98336 9.07963 4.98349 9.3854Z" fill="#29292B"/> width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M0 9.80209V9.0205C0.0460138 8.67679 0.080024 8.31425 0.144043 7.98466C0.469856 6.30568 1.25577 4.79934 2.38071 3.6977C4.13924 1.88262 6.22987 0.985679 8.52256 0.674927C9.9086 0.485649 11.3116 0.565177 12.6758 0.910345C14.5124 1.34351 16.1889 2.2075 17.6053 3.67886C18.7276 4.84183 19.5319 6.24257 19.858 7.98466C19.918 8.31189 19.952 8.64383 20 8.97577V9.80209C19.9827 9.8676 19.9693 9.93447 19.96 10.0022C19.8708 11.2186 19.5113 12.3861 18.9177 13.3875C17.961 15.0025 16.6297 16.2594 15.0825 17.0082C12.4657 18.3525 9.75693 18.5667 6.98209 17.8346C6.8589 17.8074 6.73157 17.8264 6.61799 17.8887C5.15955 18.7339 3.70511 19.5908 2.24867 20.4501C2.18866 20.4854 2.12464 20.5183 2.0146 20.5748L3.78714 16.3703C3.37301 16.0148 2.96889 15.7017 2.60078 15.3415C1.42243 14.1879 0.556167 12.7895 0.182055 11.0192C0.0980294 10.6213 0.060018 10.2094 0 9.80209ZM14.0042 10.5931C14.1362 10.5968 14.2676 10.5698 14.3907 10.5135C14.5138 10.4572 14.6262 10.3728 14.7214 10.2651C14.8167 10.1574 14.8928 10.0286 14.9455 9.8861C14.9982 9.7436 15.0264 9.59023 15.0285 9.43484V9.4113C15.0285 9.25517 15.0024 9.10058 14.9516 8.95634C14.9008 8.8121 14.8264 8.68104 14.7326 8.57064C14.6388 8.46025 14.5274 8.37268 14.4048 8.31293C14.2823 8.25319 14.1509 8.22243 14.0182 8.22243C13.8855 8.22243 13.7542 8.25319 13.6316 8.31293C13.509 8.37268 13.3976 8.46025 13.3038 8.57064C13.21 8.68104 13.1356 8.8121 13.0848 8.95634C13.034 9.10058 13.0079 9.25517 13.0079 9.4113C13.0074 9.56588 13.0327 9.71906 13.0825 9.86211C13.1323 10.0052 13.2055 10.1353 13.2981 10.245C13.3906 10.3547 13.5005 10.442 13.6217 10.5017C13.7429 10.5614 13.8728 10.5925 14.0042 10.5931ZM10.003 10.5931C10.203 10.5926 10.3983 10.5225 10.5644 10.3915C10.7306 10.2606 10.86 10.0746 10.9364 9.85719C11.0129 9.63976 11.0329 9.40056 10.9939 9.16977C10.9549 8.93898 10.8588 8.72694 10.7175 8.5604C10.5763 8.39385 10.3962 8.28026 10.2002 8.23396C10.0041 8.18765 9.80084 8.21071 9.61591 8.30022C9.43099 8.38973 9.27273 8.54168 9.1611 8.7369C9.04948 8.93212 8.98949 9.16187 8.9887 9.39717C8.98975 9.71356 9.09688 10.0167 9.28682 10.2406C9.47675 10.4646 9.73413 10.5912 10.003 10.5931ZM4.98349 9.3854C4.9836 9.61979 5.04316 9.8488 5.15456 10.0431C5.26595 10.2374 5.42411 10.3882 5.60876 10.476C5.79341 10.5639 5.99616 10.5849 6.19102 10.5364C6.38588 10.4878 6.56399 10.3719 6.70252 10.2035C6.84105 10.0351 6.93371 9.82183 6.96861 9.59108C7.00352 9.36032 6.97909 9.12255 6.89845 8.90823C6.8178 8.69392 6.68463 8.51281 6.51597 8.38811C6.34732 8.26342 6.15087 8.20081 5.95179 8.20831C5.69208 8.21809 5.44579 8.34641 5.26507 8.56611C5.08434 8.78581 4.98336 9.07963 4.98349 9.3854Z"
fill="#29292B"
/>
</SvgContainer> </SvgContainer>
); );
}; };

View File

@ -1,10 +1,24 @@
import React from 'react' import { useTheme } from "@mui/material";
export const SaveIcon = ({ color }) => {
const theme = useTheme();
const setColor = color ? color : theme.palette.text.primary
export const SaveIcon = ({color = '#8F8F91'}) => {
return ( return (
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.18182 0C0.976833 0 0 0.976833 0 2.18182V21.8182C0 23.0232 0.976833 24 2.18182 24H21.8182C23.0232 24 24 23.0232 24 21.8182V7.4492C24 6.87053 23.7701 6.31559 23.3609 5.90641L18.0936 0.639044C17.6844 0.229866 17.1295 0 16.5508 0H16.3636C15.7611 0 15.2727 0.488422 15.2727 1.09091V5.45455C15.2727 6.65953 14.2959 7.63636 13.0909 7.63636H6.54545C5.34047 7.63636 4.36364 6.65953 4.36364 5.45455V1.09091C4.36364 0.488422 3.87521 0 3.27273 0H2.18182ZM12 18.5455C13.8075 18.5455 15.2727 17.0803 15.2727 15.2727C15.2727 13.4652 13.8075 12 12 12C10.1925 12 8.72727 13.4652 8.72727 15.2727C8.72727 17.0803 10.1925 18.5455 12 18.5455Z" fill={color}/> width="24"
</svg> height="24"
viewBox="0 0 24 24"
) fill="none"
} xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M2.18182 0C0.976833 0 0 0.976833 0 2.18182V21.8182C0 23.0232 0.976833 24 2.18182 24H21.8182C23.0232 24 24 23.0232 24 21.8182V7.4492C24 6.87053 23.7701 6.31559 23.3609 5.90641L18.0936 0.639044C17.6844 0.229866 17.1295 0 16.5508 0H16.3636C15.7611 0 15.2727 0.488422 15.2727 1.09091V5.45455C15.2727 6.65953 14.2959 7.63636 13.0909 7.63636H6.54545C5.34047 7.63636 4.36364 6.65953 4.36364 5.45455V1.09091C4.36364 0.488422 3.87521 0 3.27273 0H2.18182ZM12 18.5455C13.8075 18.5455 15.2727 17.0803 15.2727 15.2727C15.2727 13.4652 13.8075 12 12 12C10.1925 12 8.72727 13.4652 8.72727 15.2727C8.72727 17.0803 10.1925 18.5455 12 18.5455Z"
fill={setColor}
/>
</svg>
);
};

View File

@ -12,7 +12,7 @@ const SvgContainer = styled('svg')({
export const SendNewMessage:React.FC<SVGProps> = ({ color, opacity }) => { export const SendNewMessage:React.FC<SVGProps> = ({ color, opacity }) => {
return ( return (
<SvgContainer width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> <SvgContainer width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.33271 10.2306C2.88006 10.001 2.89088 9.65814 3.3554 9.46527L16.3563 4.06742C16.8214 3.87427 17.0961 4.11004 16.9689 4.59692L14.1253 15.4847C13.9985 15.9703 13.5515 16.1438 13.1241 15.8705L10.0773 13.9219C9.8629 13.7848 9.56272 13.8345 9.40985 14.0292L8.41215 15.2997C8.10197 15.6946 7.71724 15.6311 7.5525 15.1567L6.67584 12.6326C6.51125 12.1587 6.01424 11.5902 5.55821 11.359L3.33271 10.2306Z" /> <path fillRule="evenodd" clipRule="evenodd" d="M3.33271 10.2306C2.88006 10.001 2.89088 9.65814 3.3554 9.46527L16.3563 4.06742C16.8214 3.87427 17.0961 4.11004 16.9689 4.59692L14.1253 15.4847C13.9985 15.9703 13.5515 16.1438 13.1241 15.8705L10.0773 13.9219C9.8629 13.7848 9.56272 13.8345 9.40985 14.0292L8.41215 15.2997C8.10197 15.6946 7.71724 15.6311 7.5525 15.1567L6.67584 12.6326C6.51125 12.1587 6.01424 11.5902 5.55821 11.359L3.33271 10.2306Z" />
</SvgContainer> </SvgContainer>
); );

View File

@ -1,19 +1,27 @@
/* HTML: <div class="loader"></div> */ /* HTML: <div class="loader"></div> */
.loader-bar { .loader-bar {
width: 45px; width: 45px;
aspect-ratio: .75; aspect-ratio: 0.75;
--c:no-repeat linear-gradient(currentColor 0 0); --c: no-repeat linear-gradient(currentColor 0 0);
background: background: var(--c) 0% 100%, var(--c) 50% 100%, var(--c) 100% 100%;
var(--c) 0% 100%, background-size: 20% 65%;
var(--c) 50% 100%, animation: l8 1s infinite linear;
var(--c) 100% 100%; }
background-size: 20% 65%;
animation: l8 1s infinite linear; @keyframes l8 {
16.67% {
background-position: 0% 0%, 50% 100%, 100% 100%;
} }
@keyframes l8 { 33.33% {
16.67% {background-position: 0% 0% ,50% 100%,100% 100%} background-position: 0% 0%, 50% 0%, 100% 100%;
33.33% {background-position: 0% 0% ,50% 0% ,100% 100%} }
50% {background-position: 0% 0% ,50% 0% ,100% 0% } 50% {
66.67% {background-position: 0% 100%,50% 0% ,100% 0% } background-position: 0% 0%, 50% 0%, 100% 0%;
83.33% {background-position: 0% 100%,50% 100%,100% 0% } }
} 66.67% {
background-position: 0% 100%, 50% 0%, 100% 0%;
}
83.33% {
background-position: 0% 100%, 50% 100%, 100% 0%;
}
}

View File

@ -1,7 +1,6 @@
.lds-ellipsis { .lds-ellipsis {
color: white color: white;
} }
.lds-ellipsis, .lds-ellipsis,
.lds-ellipsis div { .lds-ellipsis div {
box-sizing: border-box; box-sizing: border-box;
@ -61,4 +60,3 @@
transform: translate(24px, 0); transform: translate(24px, 0);
} }
} }

View File

@ -20,7 +20,7 @@ const AppViewerContainer = React.forwardRef(({ app, isSelected, hide, isDevMode,
padding: 0; padding: 0;
} }
* { * {
-ms-overflow-style: none; /* IE and Edge */ -msOverflowStyle: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */ scrollbar-width: none; /* Firefox */
} }
*::-webkit-scrollbar { *::-webkit-scrollbar {

View File

@ -1,315 +1,381 @@
import { import { Typography, Box, ButtonBase } from "@mui/material";
AppBar, import { styled } from "@mui/system";
Button,
Toolbar,
Typography,
Box,
TextField,
InputLabel,
ButtonBase,
} from "@mui/material";
import { styled } from "@mui/system";
export const AppsParent = styled(Box)(({ theme }) => ({
display: "flex",
width: "100%",
flexDirection: "column",
height: "100%",
alignItems: "center",
overflow: 'auto',
// For WebKit-based browsers (Chrome, Safari, etc.)
"::-webkit-scrollbar": {
width: "0px", // Set the width to 0 to hide the scrollbar
height: "0px", // Set the height to 0 for horizontal scrollbar
},
// For Firefox
scrollbarWidth: "none", // Hides the scrollbar in Firefox
// Optional for better cross-browser consistency
"-ms-overflow-style": "none" // Hides scrollbar in IE and Edge
}));
export const AppsContainer = styled(Box)(({ theme }) => ({
display: "flex",
width: "90%",
justifyContent: 'space-evenly',
gap: '24px',
flexWrap: 'wrap',
alignItems: 'flex-start',
alignSelf: 'center'
}));
export const AppsLibraryContainer = styled(Box)(({ theme }) => ({
display: "flex",
width: "100%",
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'center',
}));
export const AppsWidthLimiter = styled(Box)(({ theme }) => ({
display: "flex",
width: "90%",
flexDirection: 'column',
justifyContent: 'flex-start',
alignItems: 'flex-start',
}));
export const AppsSearchContainer = styled(Box)(({ theme }) => ({
display: "flex",
width: "90%",
justifyContent: 'space-between',
alignItems: 'center',
backgroundColor: '#434343',
borderRadius: '8px',
padding: '0px 10px',
height: '36px'
}));
export const AppsSearchLeft = styled(Box)(({ theme }) => ({
display: "flex",
width: "90%",
justifyContent: 'flex-start',
alignItems: 'center',
gap: '10px',
flexGrow: 1,
flexShrink: 0
}));
export const AppsSearchRight = styled(Box)(({ theme }) => ({
display: "flex",
width: "90%",
justifyContent: 'flex-end',
alignItems: 'center',
flexShrink: 1
}));
export const AppCircleContainer = styled(Box)(({ theme }) => ({
display: "flex",
flexDirection: "column",
gap: '5px',
alignItems: 'center',
width: '100%'
}));
export const Add = styled(Typography)(({ theme }) => ({
fontSize: '36px',
fontWeight: 500,
lineHeight: '43.57px',
textAlign: 'left'
}));
export const AppCircleLabel = styled(Typography)(({ theme }) => ({
fontSize: '14px',
fontWeight: 500,
lineHeight: 1.2,
// whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
width: '120%',
'-webkit-line-clamp': '2',
'-webkit-box-orient': 'vertical',
'display': '-webkit-box',
}));
export const AppLibrarySubTitle = styled(Typography)(({ theme }) => ({
fontSize: '16px',
fontWeight: 500,
lineHeight: 1.2,
}));
export const AppCircle = styled(Box)(({ theme }) => ({
display: "flex",
width: "75px",
flexDirection: "column",
height: "75px",
alignItems: 'center',
justifyContent: 'center',
borderRadius: '50%',
backgroundColor: "var(--apps-circle)",
border: '1px solid #FFFFFF'
}));
export const AppInfoSnippetContainer = styled(Box)(({ theme }) => ({ export const AppsParent = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
justifyContent: 'space-between', width: "100%",
alignItems: 'center', flexDirection: "column",
width: '100%' height: "100%",
})); alignItems: "center",
overflow: "auto",
// For WebKit-based browsers (Chrome, Safari, etc.)
"::-webkit-scrollbar": {
width: "0px", // Set the width to 0 to hide the scrollbar
height: "0px", // Set the height to 0 for horizontal scrollbar
},
export const AppInfoSnippetLeft = styled(Box)(({ theme }) => ({ // For Firefox
display: "flex", scrollbarWidth: "none", // Hides the scrollbar in Firefox
justifyContent: 'flex-start',
alignItems: 'center',
gap: '12px'
}));
export const AppInfoSnippetRight = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: 'flex-end',
alignItems: 'center',
}));
export const AppDownloadButton = styled(ButtonBase)(({ theme }) => ({ // Optional for better cross-browser consistency
backgroundColor: "#247C0E", "-msOverflowStyle": "none", // Hides scrollbar in IE and Edge
width: '101px',
height: '29px',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
borderRadius: '25px',
alignSelf: 'center'
}));
export const AppDownloadButtonText = styled(Typography)(({ theme }) => ({ backgroundColor: theme.palette.background.default,
fontSize: '14px', color: theme.palette.text.primary,
fontWeight: 500, }));
lineHeight: 1.2,
}));
export const AppPublishTagsContainer = styled(Box)(({theme})=> ({ export const AppsContainer = styled(Box)(({ theme }) => ({
gap: '10px', display: "flex",
flexWrap: 'wrap', width: "90%",
justifyContent: 'flex-start', justifyContent: "space-evenly",
width: '100%', gap: "24px",
display: 'flex' flexWrap: "wrap",
})) alignItems: "flex-start",
alignSelf: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsLibraryContainer = styled(Box)(({ theme }) => ({
display: "flex",
width: "100%",
flexDirection: "column",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: theme.palette.background.paper,
}));
export const AppInfoSnippetMiddle = styled(Box)(({ theme }) => ({ export const AppsWidthLimiter = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
flexDirection: "column", width: "90%",
justifyContent: 'center', flexDirection: "column",
alignItems: 'flex-start', justifyContent: "flex-start",
})); alignItems: "flex-start",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppInfoAppName = styled(Typography)(({ theme }) => ({ export const AppsSearchContainer = styled(Box)(({ theme }) => ({
fontSize: '16px', display: "flex",
fontWeight: 500, width: "90%",
lineHeight: 1.2, justifyContent: "space-between",
textAlign: 'start' alignItems: "center",
})); borderRadius: "8px",
export const AppInfoUserName = styled(Typography)(({ theme }) => ({ padding: "0px 10px",
fontSize: '13px', height: "36px",
fontWeight: 400, backgroundColor: theme.palette.background.default,
lineHeight: 1.2, color: theme.palette.text.primary,
color: '#8D8F93', }));
textAlign: 'start'
}));
export const AppsSearchLeft = styled(Box)(({ theme }) => ({
display: "flex",
width: "90%",
justifyContent: "flex-start",
alignItems: "center",
gap: "10px",
flexGrow: 1,
flexShrink: 0,
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsNavBarParent = styled(Box)(({ theme }) => ({ export const AppsSearchRight = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
justifyContent: 'space-between', width: "90%",
alignItems: 'center', justifyContent: "flex-end",
width: '100%', alignItems: "center",
height: '60px', flexShrink: 1,
backgroundColor: '#1F2023', backgroundColor: theme.palette.background.default,
padding: '0px 10px', color: theme.palette.text.primary,
position: "fixed", }));
bottom: 0,
zIndex: 1,
}));
export const AppsNavBarLeft = styled(Box)(({ theme }) => ({ export const AppCircleContainer = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
justifyContent: 'flex-start', flexDirection: "column",
alignItems: 'center', gap: "5px",
flexGrow: 1 alignItems: "center",
})); width: "100%",
export const AppsNavBarRight = styled(Box)(({ theme }) => ({ backgroundColor: theme.palette.background.default,
display: "flex", color: theme.palette.text.primary,
justifyContent: 'flex-end', }));
alignItems: 'center',
}));
export const TabParent = styled(Box)(({ theme }) => ({ export const Add = styled(Typography)(({ theme }) => ({
height: '36px', fontSize: "36px",
width: '36px', fontWeight: 500,
backgroundColor: '#434343', lineHeight: "43.57px",
position: 'relative', textAlign: "left",
borderRadius: '50%', backgroundColor: theme.palette.background.default,
display: 'flex', color: theme.palette.text.primary,
alignItems: 'center', }));
justifyContent: 'center'
}));
export const PublishQAppCTAParent = styled(Box)(({ theme }) => ({ export const AppCircleLabel = styled(Typography)(({ theme }) => ({
display: "flex", fontSize: "14px",
justifyContent: 'space-between', fontWeight: 500,
alignItems: 'center', lineHeight: 1.2,
width: '100%', // whiteSpace: 'nowrap',
backgroundColor: '#181C23' overflow: "hidden",
})); textOverflow: "ellipsis",
width: "120%",
"-webkit-line-clamp": "2",
"-webkit-box-orient": "vertical",
display: "-webkit-box",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppCTALeft = styled(Box)(({ theme }) => ({ export const AppLibrarySubTitle = styled(Typography)(({ theme }) => ({
display: "flex", fontSize: "16px",
justifyContent: 'flex-start', fontWeight: 500,
alignItems: 'center', lineHeight: 1.2,
})); backgroundColor: theme.palette.background.default,
export const PublishQAppCTARight = styled(Box)(({ theme }) => ({ color: theme.palette.text.primary,
display: "flex", }));
justifyContent: 'flex-end',
alignItems: 'center',
}));
export const PublishQAppCTAButton = styled(ButtonBase)(({ theme }) => ({ export const AppCircle = styled(Box)(({ theme }) => ({
width: '101px', display: "flex",
height: '29px', width: "75px",
display: 'flex', flexDirection: "column",
justifyContent: 'center', height: "75px",
alignItems: 'center', alignItems: "center",
borderRadius: '25px', justifyContent: "center",
border: '1px solid #FFFFFF' borderRadius: "50%",
})); backgroundColor: theme.palette.background.default,
export const PublishQAppDotsBG = styled(Box)(({ theme }) => ({ color: theme.palette.text.primary,
display: "flex", border: "1px solid #FFFFFF",
justifyContent: 'center', }));
alignItems: 'center',
width: '60px',
height: '60px',
backgroundColor: '#4BBCFE'
}));
export const PublishQAppInfo = styled(Typography)(({ theme }) => ({
fontSize: '10px',
fontWeight: 400,
lineHeight: 1.2,
fontStyle: 'italic'
}));
export const PublishQAppChoseFile = styled(ButtonBase)(({ theme }) => ({ export const AppInfoSnippetContainer = styled(Box)(({ theme }) => ({
width: '101px', display: "flex",
height: '30px', justifyContent: "space-between",
display: 'flex', alignItems: "center",
justifyContent: 'center', width: "100%",
alignItems: 'center', backgroundColor: theme.palette.background.default,
borderRadius: '5px', color: theme.palette.text.primary,
backgroundColor: '#0091E1', }));
color: 'white',
fontWeight: 600,
fontSize: '10px'
}));
export const AppInfoSnippetLeft = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
gap: "12px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsCategoryInfo = styled(Box)(({ theme }) => ({ export const AppInfoSnippetRight = styled(Box)(({ theme }) => ({
display: "flex", display: "flex",
alignItems: 'center', justifyContent: "flex-end",
width: '100%', alignItems: "center",
})); backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsCategoryInfoSub = styled(Box)(({ theme }) => ({ export const AppDownloadButton = styled(ButtonBase)(({ theme }) => ({
display: "flex", backgroundColor: "#247C0E",
flexDirection: 'column', color: theme.palette.text.primary,
})); width: "101px",
export const AppsCategoryInfoLabel = styled(Typography)(({ theme }) => ({ height: "29px",
fontSize: '12px', display: "flex",
fontWeight: 700, justifyContent: "center",
lineHeight: 1.2, alignItems: "center",
color: '#8D8F93', borderRadius: "25px",
})); alignSelf: "center",
export const AppsCategoryInfoValue = styled(Typography)(({ theme }) => ({ }));
fontSize: '12px',
fontWeight: 500, export const AppDownloadButtonText = styled(Typography)(({ theme }) => ({
lineHeight: 1.2, fontSize: "14px",
color: '#8D8F93', fontWeight: 500,
})); lineHeight: 1.2,
export const AppsInfoDescription = styled(Typography)(({ theme }) => ({ backgroundColor: theme.palette.background.default,
fontSize: '13px', color: theme.palette.text.primary,
fontWeight: 300, }));
lineHeight: 1.2,
width: '90%', export const AppPublishTagsContainer = styled(Box)(({ theme }) => ({
textAlign: 'start' gap: "10px",
})); flexWrap: "wrap",
justifyContent: "flex-start",
width: "100%",
display: "flex",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppInfoSnippetMiddle = styled(Box)(({ theme }) => ({
display: "flex",
flexDirection: "column",
justifyContent: "center",
alignItems: "flex-start",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppInfoAppName = styled(Typography)(({ theme }) => ({
fontSize: "16px",
fontWeight: 500,
lineHeight: 1.2,
textAlign: "start",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppInfoUserName = styled(Typography)(({ theme }) => ({
fontSize: "13px",
fontWeight: 400,
lineHeight: 1.2,
textAlign: "start",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsNavBarParent = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
height: "60px",
padding: "0px 10px",
position: "fixed",
bottom: 0,
zIndex: 1,
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsNavBarLeft = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
flexGrow: 1,
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsNavBarRight = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "flex-end",
alignItems: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const TabParent = styled(Box)(({ theme }) => ({
height: "36px",
width: "36px",
position: "relative",
borderRadius: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppCTAParent = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "space-between",
alignItems: "center",
width: "100%",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppCTALeft = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppCTARight = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "flex-end",
alignItems: "center",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppCTAButton = styled(ButtonBase)(({ theme }) => ({
width: "101px",
height: "29px",
display: "flex",
justifyContent: "center",
alignItems: "center",
borderRadius: "25px",
border: "1px solid #FFFFFF",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppDotsBG = styled(Box)(({ theme }) => ({
display: "flex",
justifyContent: "center",
alignItems: "center",
width: "60px",
height: "60px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppInfo = styled(Typography)(({ theme }) => ({
fontSize: "10px",
fontWeight: 400,
lineHeight: 1.2,
fontStyle: "italic",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const PublishQAppChoseFile = styled(ButtonBase)(({ theme }) => ({
width: "101px",
height: "30px",
display: "flex",
justifyContent: "center",
alignItems: "center",
borderRadius: "5px",
fontWeight: 600,
fontSize: "10px",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsCategoryInfo = styled(Box)(({ theme }) => ({
display: "flex",
alignItems: "center",
width: "100%",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsCategoryInfoSub = styled(Box)(({ theme }) => ({
display: "flex",
flexDirection: "column",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsCategoryInfoLabel = styled(Typography)(({ theme }) => ({
fontSize: "12px",
fontWeight: 700,
lineHeight: 1.2,
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsCategoryInfoValue = styled(Typography)(({ theme }) => ({
fontSize: "12px",
fontWeight: 500,
lineHeight: 1.2,
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));
export const AppsInfoDescription = styled(Typography)(({ theme }) => ({
fontSize: "13px",
fontWeight: 300,
lineHeight: 1.2,
width: "90%",
textAlign: "start",
backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary,
}));

View File

@ -56,7 +56,7 @@ const ScrollerStyled = styled('div')({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
const StyledVirtuosoContainer = styled('div')({ const StyledVirtuosoContainer = styled('div')({
@ -75,7 +75,7 @@ const ScrollerStyled = styled('div')({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
export const AppsCategory = ({ availableQapps, myName, category, isShow }) => { export const AppsCategory = ({ availableQapps, myName, category, isShow }) => {

View File

@ -64,7 +64,7 @@ const ScrollerStyled = styled("div")({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
const StyledVirtuosoContainer = styled("div")({ const StyledVirtuosoContainer = styled("div")({
@ -83,7 +83,7 @@ const StyledVirtuosoContainer = styled("div")({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
export const AppsCategoryDesktop = ({ export const AppsCategoryDesktop = ({

View File

@ -1,7 +1,13 @@
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import React, {
useContext,
useEffect,
useMemo,
useRef,
useState,
} from "react";
import { AppsHomeDesktop } from "./AppsHomeDesktop"; import { AppsHomeDesktop } from "./AppsHomeDesktop";
import { Spacer } from "../../common/Spacer"; import { Spacer } from "../../common/Spacer";
import { GlobalContext, MyContext, getBaseApiReact } from "../../App"; import { GlobalContext, getBaseApiReact } from "../../App";
import { AppInfo } from "./AppInfo"; import { AppInfo } from "./AppInfo";
import { import {
executeEvent, executeEvent,
@ -15,47 +21,58 @@ import { AppPublish } from "./AppPublish";
import { AppsLibraryDesktop } from "./AppsLibraryDesktop"; import { AppsLibraryDesktop } from "./AppsLibraryDesktop";
import { AppsCategoryDesktop } from "./AppsCategoryDesktop"; import { AppsCategoryDesktop } from "./AppsCategoryDesktop";
import { AppsNavBarDesktop } from "./AppsNavBarDesktop"; import { AppsNavBarDesktop } from "./AppsNavBarDesktop";
import { Box, ButtonBase } from "@mui/material"; import { Box, ButtonBase, useTheme } from "@mui/material";
import { HomeIcon } from "../../assets/Icons/HomeIcon"; import { HomeIcon } from "../../assets/Icons/HomeIcon";
import { MessagingIcon } from "../../assets/Icons/MessagingIcon"; import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
import { Save } from "../Save/Save"; import { Save } from "../Save/Save";
import { HubsIcon } from "../../assets/Icons/HubsIcon";
import { CoreSyncStatus } from "../CoreSyncStatus";
import { IconWrapper } from "../Desktop/DesktopFooter"; import { IconWrapper } from "../Desktop/DesktopFooter";
import AppIcon from "../../assets/svgs/AppIcon.svg";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import { enabledDevModeAtom } from "../../atoms/global"; import { enabledDevModeAtom } from "../../atoms/global";
import { AppsIcon } from "../../assets/Icons/AppsIcon"; import { AppsIcon } from "../../assets/Icons/AppsIcon";
const uid = new ShortUniqueId({ length: 8 }); const uid = new ShortUniqueId({ length: 8 });
export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktopSideView, hasUnreadDirects, isDirects, isGroups, hasUnreadGroups, toggleSideViewGroups, toggleSideViewDirects, setDesktopViewMode, isApps, desktopViewMode}) => { export const AppsDesktop = ({
mode,
setMode,
show,
myName,
goToHome,
hasUnreadDirects,
hasUnreadGroups,
setDesktopViewMode,
desktopViewMode,
}) => {
const [availableQapps, setAvailableQapps] = useState([]); const [availableQapps, setAvailableQapps] = useState([]);
const [selectedAppInfo, setSelectedAppInfo] = useState(null); const [selectedAppInfo, setSelectedAppInfo] = useState(null);
const [selectedCategory, setSelectedCategory] = useState(null) const [selectedCategory, setSelectedCategory] = useState(null);
const [tabs, setTabs] = useState([]); const [tabs, setTabs] = useState([]);
const [selectedTab, setSelectedTab] = useState(null); const [selectedTab, setSelectedTab] = useState(null);
const [isNewTabWindow, setIsNewTabWindow] = useState(false); const [isNewTabWindow, setIsNewTabWindow] = useState(false);
const [categories, setCategories] = useState([]) const [categories, setCategories] = useState([]);
const iframeRefs = useRef({}); const iframeRefs = useRef({});
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom) const [isEnabledDevMode, setIsEnabledDevMode] =
useRecoilState(enabledDevModeAtom);
const { showTutorial } = useContext(GlobalContext); const { showTutorial } = useContext(GlobalContext);
const theme = useTheme();
const myApp = useMemo(()=> { const myApp = useMemo(() => {
return availableQapps.find(
return availableQapps.find((app)=> app.name === myName && app.service === 'APP') (app) => app.name === myName && app.service === "APP"
}, [myName, availableQapps]) );
const myWebsite = useMemo(()=> { }, [myName, availableQapps]);
return availableQapps.find((app)=> app.name === myName && app.service === 'WEBSITE')
}, [myName, availableQapps])
const myWebsite = useMemo(() => {
return availableQapps.find(
(app) => app.name === myName && app.service === "WEBSITE"
);
}, [myName, availableQapps]);
useEffect(()=> { useEffect(() => {
if(show){ if (show) {
showTutorial('qapps') showTutorial("qapps");
} }
}, [show]) }, [show]);
useEffect(() => { useEffect(() => {
setTimeout(() => { setTimeout(() => {
@ -81,10 +98,10 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
}); });
if (!response?.ok) return; if (!response?.ok) return;
const responseData = await response.json(); const responseData = await response.json();
setCategories(responseData); setCategories(responseData);
} catch (error) { } catch (error) {
console.log(error);
} finally { } finally {
// dispatch(setIsLoadingGlobal(false)) // dispatch(setIsLoadingGlobal(false))
} }
@ -115,18 +132,19 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
}); });
if (!responseWebsites?.ok) return; if (!responseWebsites?.ok) return;
const responseDataWebsites = await responseWebsites.json(); const responseDataWebsites = await responseWebsites.json();
apps = responseData; apps = responseData;
websites = responseDataWebsites; websites = responseDataWebsites;
const combine = [...apps, ...websites]; const combine = [...apps, ...websites];
setAvailableQapps(combine); setAvailableQapps(combine);
} catch (error) { } catch (error) {
console.log(error);
} finally { } finally {
// dispatch(setIsLoadingGlobal(false)) // dispatch(setIsLoadingGlobal(false))
} }
}, []); }, []);
useEffect(() => { useEffect(() => {
getCategories() getCategories();
}, [getCategories]); }, [getCategories]);
useEffect(() => { useEffect(() => {
@ -163,12 +181,13 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
subscribeToEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc); subscribeToEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc);
return () => { return () => {
unsubscribeFromEvent("selectedAppInfoCategory", selectedAppInfoCategoryFunc); unsubscribeFromEvent(
"selectedAppInfoCategory",
selectedAppInfoCategoryFunc
);
}; };
}, []); }, []);
const selectedCategoryFunc = (e) => { const selectedCategoryFunc = (e) => {
const data = e.detail?.data; const data = e.detail?.data;
setSelectedCategory(data); setSelectedCategory(data);
@ -183,35 +202,37 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
}; };
}, []); }, []);
const navigateBackFunc = (e) => { const navigateBackFunc = (e) => {
if (['category', 'appInfo-from-category', 'appInfo', 'library', 'publish'].includes(mode)) { if (
[
"category",
"appInfo-from-category",
"appInfo",
"library",
"publish",
].includes(mode)
) {
// Handle the various modes as needed // Handle the various modes as needed
if (mode === 'category') { if (mode === "category") {
setMode('library'); setMode("library");
setSelectedCategory(null); setSelectedCategory(null);
} else if (mode === 'appInfo-from-category') { } else if (mode === "appInfo-from-category") {
setMode('category'); setMode("category");
} else if (mode === 'appInfo') { } else if (mode === "appInfo") {
setMode('library'); setMode("library");
} else if (mode === 'library') { } else if (mode === "library") {
if (isNewTabWindow) { if (isNewTabWindow) {
setMode('viewer'); setMode("viewer");
} else { } else {
setMode('home'); setMode("home");
} }
} else if (mode === 'publish') { } else if (mode === "publish") {
setMode('library'); setMode("library");
} }
} else if(selectedTab?.tabId) { } else if (selectedTab?.tabId) {
executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {}) executeEvent(`navigateBackApp-${selectedTab?.tabId}`, {});
} }
}; };
useEffect(() => { useEffect(() => {
subscribeToEvent("navigateBack", navigateBackFunc); subscribeToEvent("navigateBack", navigateBackFunc);
@ -234,8 +255,6 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
setIsNewTabWindow(false); setIsNewTabWindow(false);
}; };
useEffect(() => { useEffect(() => {
subscribeToEvent("addTab", addTabFunc); subscribeToEvent("addTab", addTabFunc);
@ -245,7 +264,7 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
}, [tabs]); }, [tabs]);
const setSelectedTabFunc = (e) => { const setSelectedTabFunc = (e) => {
const data = e.detail?.data; const data = e.detail?.data;
if(e.detail?.isDevMode) return if (e.detail?.isDevMode) return;
setSelectedTab(data); setSelectedTab(data);
setTimeout(() => { setTimeout(() => {
@ -259,7 +278,6 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
}, 100); }, 100);
setIsNewTabWindow(false); setIsNewTabWindow(false);
}; };
useEffect(() => { useEffect(() => {
subscribeToEvent("setSelectedTab", setSelectedTabFunc); subscribeToEvent("setSelectedTab", setSelectedTabFunc);
@ -299,7 +317,7 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
const setNewTabWindowFunc = (e) => { const setNewTabWindowFunc = (e) => {
setIsNewTabWindow(true); setIsNewTabWindow(true);
setSelectedTab(null) setSelectedTab(null);
}; };
useEffect(() => { useEffect(() => {
@ -318,67 +336,62 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
flexDirection: 'row' flexDirection: 'row'
}} }}
> >
<Box
<Box sx={{ sx={{
width: '60px', width: "60px",
flexDirection: 'column', flexDirection: "column",
height: '100vh', height: "100vh",
alignItems: 'center', alignItems: "center",
display: 'flex', display: "flex",
gap: '25px' gap: "25px",
}}> }}
>
<ButtonBase <ButtonBase
sx={{ sx={{
width: '60px', width: "60px",
height: '60px', height: "60px",
paddingTop: '23px' paddingTop: "23px",
}} }}
onClick={() => { onClick={() => {
goToHome(); goToHome();
}} }}
> >
<HomeIcon height={34} />
<HomeIcon
height={34}
color={desktopViewMode === 'home' ? 'white': "rgba(250, 250, 250, 0.5)"}
/>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopViewMode('apps') setDesktopViewMode("apps");
}}
>
<IconWrapper label="Apps" disableWidth>
<AppsIcon height={30} />
</IconWrapper>
</ButtonBase>
<ButtonBase
onClick={() => {
setDesktopViewMode("chat");
}} }}
> >
<IconWrapper <IconWrapper
color={isApps ? 'white' :"rgba(250, 250, 250, 0.5)"} color={
label="Apps" hasUnreadDirects || hasUnreadGroups
disableWidth ? "var(--unread)"
> : theme.palette.text.primary
<AppsIcon height={30} color={isApps ? 'white' :"rgba(250, 250, 250, 0.5)"} /> }
</IconWrapper>
</ButtonBase>
<ButtonBase
onClick={() => {
setDesktopViewMode('chat')
}}
>
<IconWrapper
color={(hasUnreadDirects || hasUnreadGroups) ? "var(--unread)" : desktopViewMode === 'chat' ? 'white' :"rgba(250, 250, 250, 0.5)"}
label="Chat" label="Chat"
disableWidth disableWidth
> >
<MessagingIcon <MessagingIcon
height={30} height={30}
color={ color={
(hasUnreadDirects || hasUnreadGroups) hasUnreadDirects || hasUnreadGroups
? "var(--unread)" ? "var(--unread)"
: desktopViewMode === 'chat' : theme.palette.text.primary
? "white"
: "rgba(250, 250, 250, 0.5)"
} }
/> />
</IconWrapper> </IconWrapper>
</ButtonBase> </ButtonBase>
{/* <ButtonBase {/* <ButtonBase
onClick={() => { onClick={() => {
@ -417,65 +430,78 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
/> />
</ButtonBase> */} </ButtonBase> */}
<Save isDesktop disableWidth myName={myName}/> <Save isDesktop disableWidth myName={myName} />
{isEnabledDevMode && ( {isEnabledDevMode && (
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopViewMode('dev') setDesktopViewMode("dev");
}} }}
> >
<IconWrapper <IconWrapper label="Dev" disableWidth>
color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"} <AppsIcon height={30} />
label="Dev" </IconWrapper>
disableWidth </ButtonBase>
>
<AppsIcon color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"} height={30} />
</IconWrapper>
</ButtonBase>
)} )}
{mode !== 'home' && ( {mode !== "home" && (
<AppsNavBarDesktop disableBack={isNewTabWindow && mode === 'viewer'} /> <AppsNavBarDesktop
disableBack={isNewTabWindow && mode === "viewer"}
/>
)} )}
</Box>
</Box>
{mode === "home" && ( {mode === "home" && (
<Box sx={{ <Box
display: 'flex', sx={{
width: '100%', display: "flex",
flexDirection: 'column', width: "100%",
height: '100vh', flexDirection: "column",
overflow: 'auto' height: "100vh",
}}> overflow: "auto",
}}
<Spacer height="30px" /> >
<AppsHomeDesktop myName={myName} availableQapps={availableQapps} setMode={setMode} myApp={myApp} myWebsite={myWebsite} /> <Spacer height="30px" />
<AppsHomeDesktop
myName={myName}
availableQapps={availableQapps}
setMode={setMode}
myApp={myApp}
myWebsite={myWebsite}
/>
</Box> </Box>
)} )}
<AppsLibraryDesktop <AppsLibraryDesktop
isShow={mode === "library" && !selectedTab} isShow={mode === "library" && !selectedTab}
availableQapps={availableQapps} availableQapps={availableQapps}
setMode={setMode} setMode={setMode}
myName={myName} myName={myName}
hasPublishApp={!!(myApp || myWebsite)} hasPublishApp={!!(myApp || myWebsite)}
categories={categories} categories={categories}
getQapps={getQapps} getQapps={getQapps}
/> />
{mode === "appInfo" && !selectedTab && <AppInfo app={selectedAppInfo} myName={myName} />} {mode === "appInfo" && !selectedTab && (
{mode === "appInfo-from-category" && !selectedTab && <AppInfo app={selectedAppInfo} myName={myName} />} <AppInfo app={selectedAppInfo} myName={myName} />
<AppsCategoryDesktop availableQapps={availableQapps} isShow={mode === 'category' && !selectedTab} category={selectedCategory} myName={myName} /> )}
{mode === "publish" && !selectedTab && <AppPublish names={myName ? [myName] : []} categories={categories} />} {mode === "appInfo-from-category" && !selectedTab && (
<AppInfo app={selectedAppInfo} myName={myName} />
)}
<AppsCategoryDesktop
availableQapps={availableQapps}
isShow={mode === "category" && !selectedTab}
category={selectedCategory}
myName={myName}
/>
{mode === "publish" && !selectedTab && (
<AppPublish names={myName ? [myName] : []} categories={categories} />
)}
{tabs.map((tab) => { {tabs.map((tab) => {
if (!iframeRefs.current[tab.tabId]) { if (!iframeRefs.current[tab.tabId]) {
iframeRefs.current[tab.tabId] = React.createRef(); iframeRefs.current[tab.tabId] = React.createRef();
} }
return ( return (
<AppViewerContainer <AppViewerContainer
key={tab?.tabId} key={tab?.tabId}
hide={isNewTabWindow} hide={isNewTabWindow}
isSelected={tab?.tabId === selectedTab?.tabId} isSelected={tab?.tabId === selectedTab?.tabId}
app={tab} app={tab}
@ -487,16 +513,23 @@ export const AppsDesktop = ({ mode, setMode, show , myName, goToHome, setDesktop
{isNewTabWindow && mode === "viewer" && ( {isNewTabWindow && mode === "viewer" && (
<> <>
<Box sx={{ <Box
display: 'flex', sx={{
width: '100%', display: "flex",
flexDirection: 'column', width: "100%",
height: '100vh', flexDirection: "column",
overflow: 'auto' height: "100vh",
}}> overflow: "auto",
}}
<Spacer height="30px" /> >
<AppsHomeDesktop myName={myName} availableQapps={availableQapps} setMode={setMode} myApp={myApp} myWebsite={myWebsite} /> <Spacer height="30px" />
<AppsHomeDesktop
myName={myName}
availableQapps={availableQapps}
setMode={setMode}
myApp={myApp}
myWebsite={myWebsite}
/>
</Box> </Box>
</> </>
)} )}

View File

@ -1,120 +1,122 @@
import React, { useMemo, useState } from "react"; import React, { useState } from "react";
import { import {
AppCircle, AppCircle,
AppCircleContainer, AppCircleContainer,
AppCircleLabel, AppCircleLabel,
AppLibrarySubTitle, AppLibrarySubTitle,
AppsContainer, AppsContainer,
AppsParent,
} from "./Apps-styles"; } from "./Apps-styles";
import { Avatar, Box, ButtonBase, Input } from "@mui/material"; import { Box, ButtonBase, Input } from "@mui/material";
import { Add } from "@mui/icons-material"; import { Add } from "@mui/icons-material";
import { getBaseApiReact, isMobile } from "../../App"; import { isMobile } from "../../App";
import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from "../../utils/events"; import { executeEvent } from "../../utils/events";
import { Spacer } from "../../common/Spacer"; import { Spacer } from "../../common/Spacer";
import { SortablePinnedApps } from "./SortablePinnedApps"; import { SortablePinnedApps } from "./SortablePinnedApps";
import { extractComponents } from "../Chat/MessageDisplay"; import { extractComponents } from "../Chat/MessageDisplay";
import ArrowOutwardIcon from '@mui/icons-material/ArrowOutward'; import ArrowOutwardIcon from "@mui/icons-material/ArrowOutward";
import { AppsPrivate } from "./AppsPrivate"; import { AppsPrivate } from "./AppsPrivate";
import ThemeSelector from "../Theme/ThemeSelector";
export const AppsHomeDesktop = ({ export const AppsHomeDesktop = ({
setMode, setMode,
myApp, myApp,
myWebsite, myWebsite,
availableQapps, availableQapps,
myName myName,
}) => { }) => {
const [qortalUrl, setQortalUrl] = useState('') const [qortalUrl, setQortalUrl] = useState("");
const openQortalUrl = ()=> { const openQortalUrl = () => {
try { try {
if(!qortalUrl) return if (!qortalUrl) return;
const res = extractComponents(qortalUrl); const res = extractComponents(qortalUrl);
if (res) { if (res) {
const { service, name, identifier, path } = res; const { service, name, identifier, path } = res;
executeEvent("addTab", { data: { service, name, identifier, path } }); executeEvent("addTab", { data: { service, name, identifier, path } });
executeEvent("open-apps-mode", { }); executeEvent("open-apps-mode", {});
setQortalUrl('qortal://') setQortalUrl("qortal://");
} }
} catch (error) { } catch (error) {}
};
}
}
return ( return (
<> <>
<AppsContainer
sx={{
justifyContent: "flex-start",
}}
>
<AppLibrarySubTitle
sx={{
fontSize: "30px",
}}
>
Apps Dashboard
</AppLibrarySubTitle>
</AppsContainer>
<Spacer height="20px" />
<AppsContainer <AppsContainer
sx={{ sx={{
justifyContent: "flex-start", justifyContent: "flex-start",
}} }}
> >
<Box sx={{ <AppLibrarySubTitle
display: 'flex', sx={{
gap: '20px', fontSize: "30px",
alignItems: 'center', }}
backgroundColor: '#1f2023', >
padding: '7px', Apps Dashboard
borderRadius: '20px', </AppLibrarySubTitle>
width: '100%', </AppsContainer>
maxWidth: '500px'
}}> <Spacer height="20px" />
<Input
id="standard-adornment-name" <AppsContainer
value={qortalUrl} sx={{
onChange={(e) => { justifyContent: "flex-start",
setQortalUrl(e.target.value) }}
}} >
disableUnderline <Box
autoComplete='off' sx={{
autoCorrect='off' display: "flex",
placeholder="qortal://" gap: "20px",
alignItems: "center",
backgroundColor: "#1f2023",
padding: "7px",
borderRadius: "20px",
width: "100%",
maxWidth: "500px",
}}
>
<Input
id="standard-adornment-name"
value={qortalUrl}
onChange={(e) => {
setQortalUrl(e.target.value);
}}
disableUnderline
autoComplete="off"
autoCorrect="off"
placeholder="qortal://"
sx={{
width: "100%",
color: "white",
"& .MuiInput-input::placeholder": {
color: "rgba(84, 84, 84, 0.70) !important",
fontSize: "20px",
fontStyle: "normal",
fontWeight: 400,
lineHeight: "120%", // 24px
letterSpacing: "0.15px",
opacity: 1,
},
"&:focus": {
outline: "none",
},
// Add any additional styles for the input here
}}
onKeyDown={(e) => {
if (e.key === "Enter" && qortalUrl) {
openQortalUrl();
}
}}
/>
<ButtonBase onClick={() => openQortalUrl()}>
<ArrowOutwardIcon
sx={{ sx={{
width: '100%', color: qortalUrl ? "white" : "rgba(84, 84, 84, 0.70)",
color: 'white',
'& .MuiInput-input::placeholder': {
color: 'rgba(84, 84, 84, 0.70) !important',
fontSize: '20px',
fontStyle: 'normal',
fontWeight: 400,
lineHeight: '120%', // 24px
letterSpacing: '0.15px',
opacity: 1
},
'&:focus': {
outline: 'none',
},
// Add any additional styles for the input here
}}
onKeyDown={(e) => {
if (e.key === 'Enter' && qortalUrl) {
openQortalUrl();
}
}} }}
/> />
<ButtonBase onClick={()=> openQortalUrl()}> </ButtonBase>
<ArrowOutwardIcon sx={{ </Box>
color: qortalUrl ? 'white' : 'rgba(84, 84, 84, 0.70)' </AppsContainer>
}} />
</ButtonBase>
</Box>
</AppsContainer>
<Spacer height="45px" /> <Spacer height="45px" />
<AppsContainer <AppsContainer
sx={{ sx={{
gap: "50px", gap: "50px",
@ -137,7 +139,9 @@ export const AppsHomeDesktop = ({
<AppCircleLabel>Library</AppCircleLabel> <AppCircleLabel>Library</AppCircleLabel>
</AppCircleContainer> </AppCircleContainer>
</ButtonBase> </ButtonBase>
<AppsPrivate myName={myName} />
<AppsPrivate myName={myName} />
<SortablePinnedApps <SortablePinnedApps
isDesktop={true} isDesktop={true}
availableQapps={availableQapps} availableQapps={availableQapps}
@ -145,6 +149,8 @@ export const AppsHomeDesktop = ({
myApp={myApp} myApp={myApp}
/> />
</AppsContainer> </AppsContainer>
<ThemeSelector style={{ position: "fixed", bottom: "1%", left: "0%" }} />
</> </>
); );
}; };

View File

@ -58,7 +58,7 @@ const ScrollerStyled = styled('div')({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
const StyledVirtuosoContainer = styled('div')({ const StyledVirtuosoContainer = styled('div')({
@ -77,7 +77,7 @@ const ScrollerStyled = styled('div')({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, isShow, categories={categories} }) => { export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, isShow, categories={categories} }) => {
@ -290,7 +290,7 @@ export const AppsLibrary = ({ availableQapps, setMode, myName, hasPublishApp, i
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}}> }}>
{categories?.map((category)=> { {categories?.map((category)=> {
return ( return (

View File

@ -74,7 +74,7 @@ const ScrollerStyled = styled("div")({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
const StyledVirtuosoContainer = styled("div")({ const StyledVirtuosoContainer = styled("div")({
@ -93,7 +93,7 @@ const StyledVirtuosoContainer = styled("div")({
scrollbarWidth: "none", scrollbarWidth: "none",
// Hide scrollbar for IE and older Edge // Hide scrollbar for IE and older Edge
"-ms-overflow-style": "none", "-msOverflowStyle": "none",
}); });
export const AppsLibraryDesktop = ({ export const AppsLibraryDesktop = ({

View File

@ -1,41 +1,43 @@
import React from 'react' import { TabParent } from "./Apps-styles";
import { TabParent } from './Apps-styles'
import NavCloseTab from "../../assets/svgs/NavCloseTab.svg"; import NavCloseTab from "../../assets/svgs/NavCloseTab.svg";
import { getBaseApiReact } from '../../App'; import { getBaseApiReact } from "../../App";
import { Avatar, ButtonBase } from '@mui/material'; import { Avatar, ButtonBase } from "@mui/material";
import LogoSelected from "../../assets/svgs/LogoSelected.svg"; import LogoSelected from "../../assets/svgs/LogoSelected.svg";
import { executeEvent } from '../../utils/events'; import { executeEvent } from "../../utils/events";
import LockIcon from "@mui/icons-material/Lock"; import LockIcon from "@mui/icons-material/Lock";
const TabComponent = ({isSelected, app}) => { const TabComponent = ({ isSelected, app }) => {
return ( return (
<ButtonBase onClick={()=> { <ButtonBase
if(isSelected){ onClick={() => {
executeEvent('removeTab', { if (isSelected) {
data: app executeEvent("removeTab", {
}) data: app,
return });
return;
} }
executeEvent('setSelectedTab', { executeEvent("setSelectedTab", {
data: app data: app,
}) });
}}> }}
<TabParent sx={{ >
border: isSelected && '1px solid #FFFFFF' <TabParent
}}> sx={{
border: isSelected && "1px solid #FFFFFF",
}}
>
{isSelected && ( {isSelected && (
<img
<img style={ style={{
{ position: "absolute",
position: 'absolute', top: "-5px",
top: '-5px', right: "-5px",
right: '-5px', zIndex: 1,
zIndex: 1 }}
} src={NavCloseTab}
} src={NavCloseTab}/> />
)}
) } {app?.isPrivate && !app?.privateAppProperties?.logo ? (
{app?.isPrivate && !app?.privateAppProperties?.logo ? (
<LockIcon <LockIcon
sx={{ sx={{
height: "28px", height: "28px",
@ -49,9 +51,13 @@ const TabComponent = ({isSelected, app}) => {
width: "28px", width: "28px",
}} }}
alt={app?.name} alt={app?.name}
src={app?.privateAppProperties?.logo ? app?.privateAppProperties?.logo :`${getBaseApiReact()}/arbitrary/THUMBNAIL/${ src={
app?.name app?.privateAppProperties?.logo
}/qortal_avatar?async=true`} ? app?.privateAppProperties?.logo
: `${getBaseApiReact()}/arbitrary/THUMBNAIL/${
app?.name
}/qortal_avatar?async=true`
}
> >
<img <img
style={{ style={{
@ -63,9 +69,9 @@ const TabComponent = ({isSelected, app}) => {
/> />
</Avatar> </Avatar>
)} )}
</TabParent> </TabParent>
</ButtonBase> </ButtonBase>
) );
} };
export default TabComponent export default TabComponent;

View File

@ -74,7 +74,6 @@ const {getIndividualUserInfo} = useContext(MyContext)
const [selectedReaction, setSelectedReaction] = useState(null); const [selectedReaction, setSelectedReaction] = useState(null);
const [userInfo, setUserInfo] = useState(null) const [userInfo, setUserInfo] = useState(null)
useEffect(()=> { useEffect(()=> {
const getInfo = async ()=> { const getInfo = async ()=> {
if(!message?.sender) return if(!message?.sender) return

View File

@ -1,59 +1,59 @@
.lineHeight { .lineHeight {
line-height: 33%; line-height: 33%;
} }
.tooltip { .tooltip {
display: inline-block; display: inline-block;
position: relative; position: relative;
text-align: left; text-align: left;
} }
.tooltip .bottom { .tooltip .bottom {
min-width: 225px; min-width: 225px;
max-width: 250px; max-width: 250px;
top: 35px; top: 35px;
right: 0px; right: 0px;
/* transform: translate(-50%, 0); */ /* transform: translate(-50%, 0); */
padding: 10px 10px; padding: 10px 10px;
color: var(--black); color: var(--black);
background-color: var(--bg-2); background-color: var(--bg-2);
font-weight: normal; font-weight: normal;
font-size: 13px; font-size: 13px;
border-radius: 8px; border-radius: 8px;
position: absolute; position: absolute;
z-index: 99999999; z-index: 99999999;
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
border: 1px solid var(--black); border: 1px solid var(--black);
visibility: hidden; visibility: hidden;
opacity: 0; opacity: 0;
transition: opacity 0.2s; transition: opacity 0.2s;
} }
.tooltip:hover .bottom { .tooltip:hover .bottom {
visibility: visible; visibility: visible;
opacity: 1; opacity: 1;
z-index: 100; z-index: 100;
} }
.tooltip .bottom i { .tooltip .bottom i {
position: absolute; position: absolute;
bottom: 100%; bottom: 100%;
left: 50%; left: 50%;
margin-left: -12px; margin-left: -12px;
width: 24px; width: 24px;
height: 12px; height: 12px;
overflow: hidden; overflow: hidden;
} }
.tooltip .bottom i::after { .tooltip .bottom i::after {
content: ''; content: "";
position: absolute; position: absolute;
width: 12px; width: 12px;
height: 12px; height: 12px;
left: 50%; left: 50%;
transform: translate(-50%, 50%) rotate(45deg); transform: translate(-50%, 50%) rotate(45deg);
background-color: var(--white); background-color: var(--white);
border: 1px solid var(--black); border: 1px solid var(--black);
box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5); box-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
} }

View File

@ -1,17 +1,6 @@
import * as React from "react"; import { ButtonBase, Typography, useTheme } from "@mui/material";
import {
BottomNavigation,
BottomNavigationAction,
ButtonBase,
Typography,
} from "@mui/material";
import { Home, Groups, Message, ShowChart } from "@mui/icons-material";
import Box from "@mui/material/Box"; import Box from "@mui/material/Box";
import BottomLogo from "../../assets/svgs/BottomLogo5.svg";
import { CustomSvg } from "../../common/CustomSvg";
import { WalletIcon } from "../../assets/Icons/WalletIcon";
import { HubsIcon } from "../../assets/Icons/HubsIcon"; import { HubsIcon } from "../../assets/Icons/HubsIcon";
import { TradingIcon } from "../../assets/Icons/TradingIcon";
import { MessagingIcon } from "../../assets/Icons/MessagingIcon"; import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
import AppIcon from "../../assets/svgs/AppIcon.svg"; import AppIcon from "../../assets/svgs/AppIcon.svg";
@ -20,19 +9,31 @@ import { Save } from "../Save/Save";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import { enabledDevModeAtom } from "../../atoms/global"; import { enabledDevModeAtom } from "../../atoms/global";
export const IconWrapper = ({ children, label, color, selected, disableWidth, customWidth }) => { export const IconWrapper = ({
children,
label,
color,
selected,
disableWidth,
customWidth,
}) => {
const theme = useTheme();
return ( return (
<Box <Box
sx={{ sx={{
display: "flex", display: "flex",
justifyContent: "center", justifyContent: "center",
alignItems: "center", alignItems: "center",
gap: "5px", gap: "5px",
flexDirection: "column", flexDirection: "column",
height: customWidth ? customWidth : disableWidth ? 'auto' : "89px", height: customWidth ? customWidth : disableWidth ? "auto" : "89px",
width: customWidth? customWidth : disableWidth ? 'auto' : "89px", width: customWidth ? customWidth : disableWidth ? "auto" : "89px",
borderRadius: "50%", borderRadius: "50%",
backgroundColor: selected ? "rgba(28, 29, 32, 1)" : "transparent", backgroundColor: selected
? theme.palette.background.default
: "transparent",
color: color ? color : theme.palette.text.primary,
}} }}
> >
{children} {children}
@ -41,7 +42,7 @@ export const IconWrapper = ({ children, label, color, selected, disableWidth, cu
fontFamily: "Inter", fontFamily: "Inter",
fontSize: "12px", fontSize: "12px",
fontWeight: 500, fontWeight: 500,
color: color, color: theme.palette.text.primary,
}} }}
> >
{label} {label}
@ -51,24 +52,7 @@ export const IconWrapper = ({ children, label, color, selected, disableWidth, cu
}; };
export const DesktopFooter = ({ export const DesktopFooter = ({
selectedGroup,
groupSection,
isUnread,
goToAnnouncements,
isUnreadChat,
goToChat,
goToThreads,
setOpenManageMembers,
groupChatHasUnread,
groupsAnnHasUnread,
directChatHasUnread,
chatMode,
openDrawerGroups,
goToHome, goToHome,
setIsOpenDrawerProfile,
mobileViewMode,
setMobileViewMode,
setMobileViewModeKeepOpen,
hasUnreadGroups, hasUnreadGroups,
hasUnreadDirects, hasUnreadDirects,
isHome, isHome,
@ -77,15 +61,14 @@ export const DesktopFooter = ({
setDesktopSideView, setDesktopSideView,
isApps, isApps,
setDesktopViewMode, setDesktopViewMode,
desktopViewMode,
hide, hide,
setIsOpenSideViewDirects, setIsOpenSideViewDirects,
setIsOpenSideViewGroups setIsOpenSideViewGroups,
}) => { }) => {
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom) const [isEnabledDevMode, setIsEnabledDevMode] =
useRecoilState(enabledDevModeAtom);
if(hide) return if (hide) return;
return ( return (
<Box <Box
sx={{ sx={{
@ -110,42 +93,31 @@ export const DesktopFooter = ({
goToHome(); goToHome();
}} }}
> >
<IconWrapper <IconWrapper label="Home" selected={isHome}>
color="rgba(250, 250, 250, 0.5)"
label="Home"
selected={isHome}
>
<HomeIcon <HomeIcon
height={30} height={30}
color={isHome ? "white" : "rgba(250, 250, 250, 0.5)"}
/> />
</IconWrapper> </IconWrapper>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopViewMode('apps') setDesktopViewMode("apps");
setIsOpenSideViewDirects(false) setIsOpenSideViewDirects(false);
setIsOpenSideViewGroups(false) setIsOpenSideViewGroups(false);
}} }}
> >
<IconWrapper <IconWrapper label="Apps" selected={isApps}>
color="rgba(250, 250, 250, 0.5)" <img src={AppIcon} />
label="Apps"
selected={isApps}
>
<img src={AppIcon} />
</IconWrapper> </IconWrapper>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopSideView("groups"); setDesktopSideView("groups");
}} }}
> >
<IconWrapper <IconWrapper label="Groups" selected={isGroups}>
color="rgba(250, 250, 250, 0.5)"
label="Groups"
selected={isGroups}
>
<HubsIcon <HubsIcon
height={30} height={30}
color={ color={
@ -158,16 +130,13 @@ export const DesktopFooter = ({
/> />
</IconWrapper> </IconWrapper>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopSideView("directs"); setDesktopSideView("directs");
}} }}
> >
<IconWrapper <IconWrapper label="Messaging" selected={isDirects}>
color="rgba(250, 250, 250, 0.5)"
label="Messaging"
selected={isDirects}
>
<MessagingIcon <MessagingIcon
height={30} height={30}
color={ color={
@ -180,26 +149,21 @@ export const DesktopFooter = ({
/> />
</IconWrapper> </IconWrapper>
</ButtonBase> </ButtonBase>
<Save isDesktop /> <Save isDesktop />
{isEnabledDevMode && ( {isEnabledDevMode && (
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopViewMode('dev') setDesktopViewMode("dev");
setIsOpenSideViewDirects(false) setIsOpenSideViewDirects(false);
setIsOpenSideViewGroups(false) setIsOpenSideViewGroups(false);
}} }}
>
<IconWrapper
color="rgba(250, 250, 250, 0.5)"
label="Dev Mode"
selected={isApps}
> >
<img src={AppIcon} /> <IconWrapper label="Dev Mode" selected={isApps}>
</IconWrapper> <img src={AppIcon} />
</ButtonBase> </IconWrapper>
</ButtonBase>
)} )}
</Box> </Box>
</Box> </Box>
); );

View File

@ -1,86 +1,104 @@
import { Box, ButtonBase } from '@mui/material'; import { Box, ButtonBase, useTheme } from "@mui/material";
import React from 'react'
import { HomeIcon } from "../assets/Icons/HomeIcon"; import { HomeIcon } from "../assets/Icons/HomeIcon";
import { MessagingIcon } from "../assets/Icons/MessagingIcon"; import { MessagingIcon } from "../assets/Icons/MessagingIcon";
import { Save } from "./Save/Save"; import { Save } from "./Save/Save";
import { HubsIcon } from "../assets/Icons/HubsIcon"; import { IconWrapper } from "./Desktop/DesktopFooter";
import { CoreSyncStatus } from "./CoreSyncStatus"; import { useRecoilState } from "recoil";
import { IconWrapper } from './Desktop/DesktopFooter'; import { enabledDevModeAtom } from "../atoms/global";
import AppIcon from "./../assets/svgs/AppIcon.svg"; import { AppsIcon } from "../assets/Icons/AppsIcon";
import { useRecoilState } from 'recoil'; import ThemeSelector from "./Theme/ThemeSelector";
import { enabledDevModeAtom } from '../atoms/global';
import { AppsIcon } from '../assets/Icons/AppsIcon';
export const DesktopSideBar = ({goToHome, setDesktopSideView, toggleSideViewDirects, hasUnreadDirects, isDirects, toggleSideViewGroups,hasUnreadGroups, isGroups, isApps, setDesktopViewMode, desktopViewMode, myName }) => { export const DesktopSideBar = ({
const [isEnabledDevMode, setIsEnabledDevMode] = useRecoilState(enabledDevModeAtom) goToHome,
setDesktopSideView,
toggleSideViewDirects,
hasUnreadDirects,
isDirects,
toggleSideViewGroups,
hasUnreadGroups,
isGroups,
isApps,
setDesktopViewMode,
desktopViewMode,
myName,
}) => {
const [isEnabledDevMode, setIsEnabledDevMode] =
useRecoilState(enabledDevModeAtom);
const theme = useTheme();
return ( return (
<Box sx={{ <Box
width: '60px', sx={{
flexDirection: 'column', width: "60px",
height: '100vh', flexDirection: "column",
alignItems: 'center', height: "100vh",
display: 'flex', alignItems: "center",
gap: '25px' display: "flex",
}}> gap: "25px",
<ButtonBase }}
sx={{ >
width: '60px', <ButtonBase
height: '60px', sx={{
paddingTop: '23px' width: "60px",
}} height: "60px",
onClick={() => { paddingTop: "23px",
goToHome(); }}
onClick={() => {
}} goToHome();
> }}
>
<HomeIcon <HomeIcon
height={34} height={34}
color={desktopViewMode === 'home' ? 'white': "rgba(250, 250, 250, 0.5)"} color={
desktopViewMode === "home" ? "white" : "rgba(250, 250, 250, 0.5)"
/> }
/>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopViewMode('apps') setDesktopViewMode("apps");
// setIsOpenSideViewDirects(false) // setIsOpenSideViewDirects(false)
// setIsOpenSideViewGroups(false) // setIsOpenSideViewGroups(false)
}} }}
> >
<IconWrapper
color={isApps ? 'white' : "rgba(250, 250, 250, 0.5)"}
label="Apps"
selected={isApps}
disableWidth
>
<AppsIcon color={isApps ? 'white' : "rgba(250, 250, 250, 0.5)"} height={30} />
</IconWrapper>
</ButtonBase>
<ButtonBase
onClick={() => {
setDesktopViewMode('chat')
}}
>
<IconWrapper <IconWrapper
color={(hasUnreadDirects || hasUnreadGroups) ? "var(--unread)" : desktopViewMode === 'chat' ? 'white' :"rgba(250, 250, 250, 0.5)"} color={isApps ? "white" : "rgba(250, 250, 250, 0.5)"}
label="Chat" label="Apps"
disableWidth selected={isApps}
> disableWidth
<MessagingIcon >
height={30} <AppsIcon
color={ color={isApps ? "white" : "rgba(250, 250, 250, 0.5)"}
(hasUnreadDirects || hasUnreadGroups) height={30}
? "var(--unread)" />
: desktopViewMode === 'chat' </IconWrapper>
? "white" </ButtonBase>
: "rgba(250, 250, 250, 0.5)" <ButtonBase
} onClick={() => {
/> setDesktopViewMode("chat");
</IconWrapper> }}
</ButtonBase> >
{/* <ButtonBase <IconWrapper
color={
hasUnreadDirects || hasUnreadGroups
? "var(--unread)"
: theme.palette.text.primary
}
label="Chat"
disableWidth
>
<MessagingIcon
height={30}
color={
hasUnreadDirects || hasUnreadGroups
? "var(--unread)"
: theme.palette.text.primary
}
/>
</IconWrapper>
</ButtonBase>
{/* <ButtonBase
onClick={() => { onClick={() => {
setDesktopSideView("groups"); setDesktopSideView("groups");
toggleSideViewGroups() toggleSideViewGroups()
@ -98,23 +116,29 @@ export const DesktopSideBar = ({goToHome, setDesktopSideView, toggleSideViewDire
/> />
</ButtonBase> */} </ButtonBase> */}
<Save isDesktop disableWidth myName={myName} /> <Save isDesktop disableWidth myName={myName} />
{/* <CoreSyncStatus imageSize="30px" position="left" /> */} {/* <CoreSyncStatus imageSize="30px" position="left" /> */}
{isEnabledDevMode && ( {isEnabledDevMode && (
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setDesktopViewMode('dev') setDesktopViewMode("dev");
}} }}
> >
<IconWrapper <IconWrapper
color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"} color={
desktopViewMode === "dev" ? "white" : "rgba(250, 250, 250, 0.5)"
}
label="Dev" label="Dev"
disableWidth disableWidth
> >
<AppsIcon color={desktopViewMode === 'dev' ? 'white' : "rgba(250, 250, 250, 0.5)"} height={30} /> <AppsIcon
height={30}
/>
</IconWrapper> </IconWrapper>
</ButtonBase> </ButtonBase>
)} )}
</Box>
) <ThemeSelector style={{ position: "fixed", bottom: "1%" }} />
} </Box>
);
};

View File

@ -1,71 +1,70 @@
.ql-editor { .ql-editor {
min-height: 200px; min-height: 200px;
width: 100%; width: 100%;
color: black; color: black;
font-size: 16px; font-size: 16px;
font-family: Roboto; font-family: Roboto;
max-height: 225px; max-height: 225px;
overflow-y: scroll; overflow-y: scroll;
padding: 0px !important; padding: 0px !important;
} }
.ql-editor::-webkit-scrollbar-track { .ql-editor::-webkit-scrollbar-track {
background-color: transparent; background-color: transparent;
cursor: default; cursor: default;
} }
.ql-editor::-webkit-scrollbar-track:hover { .ql-editor::-webkit-scrollbar-track:hover {
background-color: transparent; background-color: transparent;
} }
.ql-editor::-webkit-scrollbar {
width: 16px;
height: 10px;
background-color: rgba(229, 229, 229, 0.70);
}
.ql-editor::-webkit-scrollbar-thumb {
background-color: #B0B0B0;
border-radius: 8px;
background-clip: content-box;
border: 4px solid transparent;
}
.ql-editor img {
cursor: default;
}
.ql-editor-display {
min-height: 20px;
width: 100%;
color: black;
font-size: 16px;
font-family: Roboto;
padding: 0px !important;
}
.ql-editor-display img {
cursor: default;
}
.ql-container {
font-size: 16px
}
.ql-toolbar .ql-stroke { .ql-editor::-webkit-scrollbar {
fill: none !important; width: 16px;
stroke: black !important; height: 10px;
background-color: rgba(229, 229, 229, 0.7);
}
.ql-editor::-webkit-scrollbar-thumb {
background-color: #b0b0b0;
border-radius: 8px;
background-clip: content-box;
border: 4px solid transparent;
}
.ql-editor img {
cursor: default;
}
.ql-editor-display {
min-height: 20px;
width: 100%;
color: black;
font-size: 16px;
font-family: Roboto;
padding: 0px !important;
}
.ql-editor-display img {
cursor: default;
}
.ql-container {
font-size: 16px;
}
.ql-toolbar .ql-stroke {
fill: none !important;
stroke: black !important;
} }
.ql-toolbar .ql-fill { .ql-toolbar .ql-fill {
fill: black !important; fill: black !important;
stroke: none !important; stroke: none !important;
} }
.ql-toolbar .ql-picker { .ql-toolbar .ql-picker {
color: black !important; color: black !important;
} }
.ql-toolbar .ql-picker-options { .ql-toolbar .ql-picker-options {
background-color: white !important; background-color: white !important;
} }

View File

@ -20,7 +20,7 @@ import { MessagingIcon } from "../../assets/Icons/MessagingIcon";
import { MessagingIcon2 } from "../../assets/Icons/MessagingIcon2"; import { MessagingIcon2 } from "../../assets/Icons/MessagingIcon2";
import { HubsIcon } from "../../assets/Icons/HubsIcon"; import { HubsIcon } from "../../assets/Icons/HubsIcon";
import { Save } from "../Save/Save"; import { Save } from "../Save/Save";
import CloseFullscreenIcon from '@mui/icons-material/CloseFullscreen'; import CloseFullscreenIcon from "@mui/icons-material/CloseFullscreen";
import { useRecoilState } from "recoil"; import { useRecoilState } from "recoil";
import { fullScreenAtom, hasSettingsChangedAtom } from "../../atoms/global"; import { fullScreenAtom, hasSettingsChangedAtom } from "../../atoms/global";
import { useAppFullScreen } from "../../useAppFullscreen"; import { useAppFullScreen } from "../../useAppFullscreen";
@ -36,12 +36,12 @@ const Header = ({
setMobileViewMode, setMobileViewMode,
myName, myName,
setSelectedDirect, setSelectedDirect,
setNewChat setNewChat,
}) => { }) => {
const [anchorEl, setAnchorEl] = useState(null); const [anchorEl, setAnchorEl] = useState(null);
const open = Boolean(anchorEl); const open = Boolean(anchorEl);
const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom); const [fullScreen, setFullScreen] = useRecoilState(fullScreenAtom);
const {exitFullScreen} = useAppFullScreen(setFullScreen) const { exitFullScreen } = useAppFullScreen(setFullScreen);
const handleClick = (event) => { const handleClick = (event) => {
setAnchorEl(event.currentTarget); setAnchorEl(event.currentTarget);
}; };
@ -77,34 +77,39 @@ const Header = ({
}} }}
> >
<ButtonBase <ButtonBase
onClick={() => { onClick={() => {
setMobileViewModeKeepOpen(""); setMobileViewModeKeepOpen("");
goToHome(); goToHome();
}} }}
// onClick={onHomeClick} // onClick={onHomeClick}
> >
<HomeIcon height={20} width={27} color="rgba(145, 145, 147, 1)" /> <HomeIcon height={20} width={27} />
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase onClick={handleClick}>
<NotificationIcon
onClick={handleClick} height={20}
> width={21}
<NotificationIcon height={20} width={21} color={hasUnreadDirects || hasUnreadGroups ? "var(--danger)" : "rgba(145, 145, 147, 1)"} /> color={
hasUnreadDirects || hasUnreadGroups
? "var(--danger)"
: "rgba(145, 145, 147, 1)"
}
/>
</ButtonBase> </ButtonBase>
{fullScreen && ( {fullScreen && (
<ButtonBase onClick={()=> { <ButtonBase
exitFullScreen() onClick={() => {
setFullScreen(false) exitFullScreen();
}}> setFullScreen(false);
<CloseFullscreenIcon sx={{ }}
color: 'rgba(145, 145, 147, 1)' >
}} /> <CloseFullscreenIcon
</ButtonBase> sx={{
color: "rgba(145, 145, 147, 1)",
}}
/>
</ButtonBase>
)} )}
</Box> </Box>
{/* Center Title */} {/* Center Title */}
@ -135,14 +140,15 @@ const Header = ({
setMobileViewModeKeepOpen("messaging"); setMobileViewModeKeepOpen("messaging");
}} }}
> >
<MessagingIcon2 height={20} color={hasUnreadDirects ? "var(--danger)" : "rgba(145, 145, 147, 1)"} <MessagingIcon2
height={20}
color={
hasUnreadDirects ? "var(--danger)" : "rgba(145, 145, 147, 1)"
}
/> />
</ButtonBase> </ButtonBase>
<Save /> <Save />
<ButtonBase <ButtonBase onClick={logoutFunc}>
onClick={logoutFunc}
>
<LogoutIcon <LogoutIcon
height={20} height={20}
width={21} width={21}
@ -152,83 +158,104 @@ const Header = ({
</Box> </Box>
</Toolbar> </Toolbar>
<Menu <Menu
id="home-menu" id="home-menu"
anchorEl={anchorEl} anchorEl={anchorEl}
open={open} open={open}
onClose={handleClose} onClose={handleClose}
MenuListProps={{ MenuListProps={{
"aria-labelledby": "basic-button", "aria-labelledby": "basic-button",
}} }}
anchorOrigin={{ anchorOrigin={{
vertical: 'bottom', vertical: "bottom",
horizontal: 'center', horizontal: "center",
}} }}
transformOrigin={{ transformOrigin={{
vertical: 'top', vertical: "top",
horizontal: 'center', horizontal: "center",
}} }}
slotProps={{ slotProps={{
paper: { paper: {
sx: { sx: {
backgroundColor: 'var(--bg-primary)', backgroundColor: "var(--bg-primary)",
color: '#fff', color: "#fff",
width: '148px', width: "148px",
borderRadius: '5px' borderRadius: "5px",
}, },
}, },
}} }}
sx={{ sx={{
marginTop: '10px' marginTop: "10px",
}}
>
<MenuItem
onClick={() => {
setSelectedDirect(null)
setNewChat(false)
setMobileViewMode("groups");
setMobileViewModeKeepOpen("")
handleClose();
}} }}
> >
<ListItemIcon sx={{ <MenuItem
onClick={() => {
minWidth: '24px !important' setSelectedDirect(null);
}}> setNewChat(false);
<HubsIcon height={20} color={hasUnreadGroups ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} /> setMobileViewMode("groups");
</ListItemIcon> setMobileViewModeKeepOpen("");
<ListItemText sx={{ handleClose();
"& .MuiTypography-root": { }}
fontSize: "12px", >
fontWeight: 600, <ListItemIcon
color: hasUnreadGroups ? "var(--danger)" :"rgba(250, 250, 250, 0.5)" sx={{
}, minWidth: "24px !important",
}} primary="Groups" /> }}
</MenuItem> >
<MenuItem <HubsIcon
onClick={() => { height={20}
setMobileViewModeKeepOpen("messaging"); color={
hasUnreadGroups ? "var(--danger)" : "rgba(250, 250, 250, 0.5)"
}
/>
</ListItemIcon>
<ListItemText
sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: hasUnreadGroups
? "var(--danger)"
: "rgba(250, 250, 250, 0.5)",
},
}}
primary="Groups"
/>
</MenuItem>
<MenuItem
onClick={() => {
setMobileViewModeKeepOpen("messaging");
handleClose(); handleClose();
}} }}
> >
<ListItemIcon sx={{ <ListItemIcon
sx={{
minWidth: '24px !important' minWidth: "24px !important",
}}> }}
<MessagingIcon height={20} color={hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} /> >
</ListItemIcon> <MessagingIcon
<ListItemText sx={{ height={20}
"& .MuiTypography-root": { color={
fontSize: "12px", hasUnreadDirects
fontWeight: 600, ? "var(--danger)"
color: hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)" : "rgba(250, 250, 250, 0.5)"
}, }
}} primary="Messaging" /> />
</MenuItem> </ListItemIcon>
</Menu> <ListItemText
sx={{
"& .MuiTypography-root": {
fontSize: "12px",
fontWeight: 600,
color: hasUnreadDirects
? "var(--danger)"
: "rgba(250, 250, 250, 0.5)",
},
}}
primary="Messaging"
/>
</MenuItem>
</Menu>
</AppBar> </AppBar>
); );
} }
@ -255,24 +282,27 @@ const Header = ({
width: "75px", width: "75px",
}} }}
> >
<ButtonBase <ButtonBase
onClick={goToHome}
onClick={goToHome} // onClick={onHomeClick}
// onClick={onHomeClick} >
> <HomeIcon />
<HomeIcon color="rgba(145, 145, 147, 1)" /> </ButtonBase>
</ButtonBase> {fullScreen && (
{fullScreen && ( <ButtonBase
<ButtonBase onClick={()=> { onClick={() => {
exitFullScreen() exitFullScreen();
setFullScreen(false) setFullScreen(false);
}}> }}
<CloseFullscreenIcon sx={{ >
color: 'rgba(145, 145, 147, 1)' <CloseFullscreenIcon
}} /> sx={{
</ButtonBase> color: "rgba(145, 145, 147, 1)",
}}
/>
</ButtonBase>
)} )}
</Box> </Box>
{/* Center Title */} {/* Center Title */}
<Typography <Typography
variant="h6" variant="h6"
@ -294,16 +324,15 @@ const Header = ({
justifyContent: "flex-end", justifyContent: "flex-end",
}} }}
> >
{/* Right Logout Icon */} {/* Right Logout Icon */}
<Save /> <Save />
<ButtonBase <ButtonBase
onClick={logoutFunc} onClick={logoutFunc}
// onClick={onLogoutClick}
// onClick={onLogoutClick} >
> <LogoutIcon color="rgba(145, 145, 147, 1)" />
<LogoutIcon color="rgba(145, 145, 147, 1)" /> </ButtonBase>
</ButtonBase>
</Box> </Box>
</Toolbar> </Toolbar>
</AppBar> </AppBar>
@ -357,8 +386,14 @@ const Header = ({
boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.3)", // Optional shadow for the circle boxShadow: "0px 4px 10px rgba(0, 0, 0, 0.3)", // Optional shadow for the circle
}} }}
> >
<IconButton onClick={handleClick} color="inherit"> <IconButton onClick={handleClick} color="inherit">
<NotificationIcon color={hasUnreadDirects || hasUnreadGroups ? "var(--danger)" : "rgba(255, 255, 255, 1)"} /> <NotificationIcon
color={
hasUnreadDirects || hasUnreadGroups
? "var(--danger)"
: "rgba(255, 255, 255, 1)"
}
/>
</IconButton> </IconButton>
</Box> </Box>
@ -389,6 +424,7 @@ const Header = ({
</Box> </Box>
</ButtonBase> */} </ButtonBase> */}
</Box> </Box>
<Menu <Menu
id="home-menu" id="home-menu"
anchorEl={anchorEl} anchorEl={anchorEl}
@ -398,51 +434,60 @@ const Header = ({
"aria-labelledby": "basic-button", "aria-labelledby": "basic-button",
}} }}
anchorOrigin={{ anchorOrigin={{
vertical: 'bottom', vertical: "bottom",
horizontal: 'center', horizontal: "center",
}}
}} transformOrigin={{
transformOrigin={{ vertical: "top",
vertical: 'top', horizontal: "center",
horizontal: 'center', }}
}} slotProps={{
slotProps={{ paper: {
paper: { sx: {
sx: { backgroundColor: "var(--bg-primary)",
backgroundColor: 'var(--bg-primary)', color: "#fff",
color: '#fff', width: "148px",
width: '148px', borderRadius: "5px",
borderRadius: '5px'
},
}, },
},
}} }}
sx={{ sx={{
marginTop: '10px' marginTop: "10px",
}} }}
> >
<MenuItem <MenuItem
onClick={() => { onClick={() => {
setMobileViewMode("groups"); setMobileViewMode("groups");
setMobileViewModeKeepOpen("") setMobileViewModeKeepOpen("");
handleClose(); handleClose();
}} }}
> >
<ListItemIcon sx={{ <ListItemIcon
sx={{
minWidth: '24px !important' minWidth: "24px !important",
}}> }}
<HubsIcon height={20} color={hasUnreadGroups ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} /> >
<HubsIcon
height={20}
color={
hasUnreadGroups ? "var(--danger)" : "rgba(250, 250, 250, 0.5)"
}
/>
</ListItemIcon> </ListItemIcon>
<ListItemText sx={{ <ListItemText
"& .MuiTypography-root": { sx={{
fontSize: "12px", "& .MuiTypography-root": {
fontWeight: 600, fontSize: "12px",
color: hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)" fontWeight: 600,
}, color: hasUnreadDirects
}} primary="Groups" /> ? "var(--danger)"
: "rgba(250, 250, 250, 0.5)",
},
}}
primary="Groups"
/>
</MenuItem> </MenuItem>
<MenuItem <MenuItem
onClick={() => { onClick={() => {
setMobileViewModeKeepOpen("messaging"); setMobileViewModeKeepOpen("messaging");
@ -450,21 +495,32 @@ const Header = ({
handleClose(); handleClose();
}} }}
> >
<ListItemIcon sx={{ <ListItemIcon
sx={{
minWidth: '24px !important' minWidth: "24px !important",
}}> }}
<MessagingIcon height={20} color={hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)"} /> >
<MessagingIcon
height={20}
color={
hasUnreadDirects ? "var(--danger)" : "rgba(250, 250, 250, 0.5)"
}
/>
</ListItemIcon> </ListItemIcon>
<ListItemText sx={{ <ListItemText
"& .MuiTypography-root": { sx={{
fontSize: "12px", "& .MuiTypography-root": {
fontWeight: 600, fontSize: "12px",
color: hasUnreadDirects ? "var(--danger)" :"rgba(250, 250, 250, 0.5)" fontWeight: 600,
}, color: hasUnreadDirects
}} primary="Messaging" /> ? "var(--danger)"
: "rgba(250, 250, 250, 0.5)",
},
}}
primary="Messaging"
/>
</MenuItem> </MenuItem>
</Menu> </Menu>
</> </>
); );
}; };

View File

@ -1,67 +1,97 @@
import { Button, ButtonBase, InputAdornment, TextField, TextFieldProps, styled } from "@mui/material"; import {
import { forwardRef, useState } from 'react' ButtonBase,
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff'; InputAdornment,
import VisibilityIcon from '@mui/icons-material/Visibility'; TextField,
export const CustomInput = styled(TextField)({ TextFieldProps,
width: "183px", // Adjust the width as needed styled,
} from "@mui/material";
import { forwardRef, useState } from "react";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import VisibilityIcon from "@mui/icons-material/Visibility";
export const CustomInput = styled(TextField)(({ theme }) => ({
width: "183px",
borderRadius: "5px", borderRadius: "5px",
// backgroundColor: "rgba(30, 30, 32, 1)", backgroundColor: theme.palette.background.paper,
outline: "none", outline: "none",
input: { input: {
fontSize: 10, fontSize: 10,
fontFamily: "Inter", fontFamily: "Inter",
fontWeight: 400, fontWeight: 400,
color: "white", color: theme.palette.text.primary,
"&::placeholder": { "&::placeholder": {
fontSize: 16, fontSize: 16,
color: "rgba(255, 255, 255, 0.2)", color: theme.palette.text.disabled,
}, },
outline: "none", outline: "none",
padding: "10px", padding: "10px",
}, },
"& .MuiOutlinedInput-root": { "& .MuiOutlinedInput-root": {
"& fieldset": { "& fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)', border: `0.5px solid ${theme.palette.divider}`,
}, },
"&:hover fieldset": { "&:hover fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)', border: `0.5px solid ${theme.palette.divider}`,
}, },
"&.Mui-focused fieldset": { "&.Mui-focused fieldset": {
border: '0.5px solid rgba(255, 255, 255, 0.5)', border: `0.5px solid ${theme.palette.divider}`,
}, },
}, },
"& .MuiInput-underline:before": { "& .MuiInput-underline:before": {
borderBottom: "none", borderBottom: "none",
}, },
"& .MuiInput-underline:hover:not(.Mui-disabled):before": { "& .MuiInput-underline:hover:not(.Mui-disabled):before": {
borderBottom: "none", borderBottom: "none",
}, },
"& .MuiInput-underline:after": { "& .MuiInput-underline:after": {
borderBottom: "none", borderBottom: "none",
}, },
}); }));
export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>(
export const PasswordField = forwardRef<HTMLInputElement, TextFieldProps>( ({ ...props }, ref) => { ({ ...props }, ref) => {
const [canViewPassword, setCanViewPassword] = useState(false); const [canViewPassword, setCanViewPassword] = useState(false);
return ( return (
<CustomInput <CustomInput
type={canViewPassword ? 'text' : 'password'} type={canViewPassword ? "text" : "password"}
InputProps={{ InputProps={{
endAdornment: ( endAdornment: (
<InputAdornment position="end" data-testid="toggle-view-password-btn" onClick={() => { <InputAdornment
setCanViewPassword((prevState) => !prevState) position="end"
}}> data-testid="toggle-view-password-btn"
{canViewPassword ? <ButtonBase data-testid="plain-text-indicator" sx={{ minWidth: 0, p: 0 }}><VisibilityOffIcon sx={{ onClick={() => {
color: 'white' setCanViewPassword((prevState) => !prevState);
}}/></ButtonBase> : <ButtonBase data-testid="password-text-indicator" sx={{ minWidth: 0, p: 0 }}><VisibilityIcon sx={{ }}
color: 'white' >
}} /></ButtonBase>} {canViewPassword ? (
</InputAdornment> <ButtonBase
) data-testid="plain-text-indicator"
}} sx={{ minWidth: 0, p: 0 }}
inputRef={ref} >
{...props} <VisibilityOffIcon
/> sx={{
) color: "white",
}); }}
/>
</ButtonBase>
) : (
<ButtonBase
data-testid="password-text-indicator"
sx={{ minWidth: 0, p: 0 }}
>
<VisibilityIcon
sx={{
color: "white",
}}
/>
</ButtonBase>
)}
</InputAdornment>
),
}}
inputRef={ref}
{...props}
/>
);
}
);

View File

@ -1,27 +1,26 @@
.reaction-container { .reaction-container {
position: relative; /* Parent must be positioned relatively */ position: relative; /* Parent must be positioned relatively */
} }
.emoji-picker {
position: absolute; /* Picker positioned absolutely relative to the parent */
right: 0;
z-index: 9000000000; /* Ensure picker appears above other content */
}
.message-container {
overflow: visible; /* Ensure the message container doesn't cut off the picker */
}
.reaction-container { .emoji-picker {
position: relative; position: absolute; /* Picker positioned absolutely relative to the parent */
} right: 0;
z-index: 9000000000; /* Ensure picker appears above other content */
.emoji-picker { }
overflow: hidden;
width: auto
}
.EmojiPickerReact.epr-dark-theme { .message-container {
--epr-emoji-size: 18px; /* Adjust emoji size for dark mode */ overflow: visible; /* Ensure the message container doesn't cut off the picker */
} }
.reaction-container {
position: relative;
}
.emoji-picker {
overflow: hidden;
width: auto;
}
.EmojiPickerReact.epr-dark-theme {
--epr-emoji-size: 18px; /* Adjust emoji size for dark mode */
}

View File

@ -22,20 +22,22 @@ import { LoadingButton } from "@mui/lab";
import { saveToLocalStorage } from "../Apps/AppsNavBar"; import { saveToLocalStorage } from "../Apps/AppsNavBar";
import { decryptData, encryptData } from "../../qortalRequests/get"; import { decryptData, encryptData } from "../../qortalRequests/get";
import { saveFileToDiskGeneric } from "../../utils/generateWallet/generateWallet"; import { saveFileToDiskGeneric } from "../../utils/generateWallet/generateWallet";
import { base64ToUint8Array, uint8ArrayToObject } from "../../backgroundFunctions/encryption"; import {
base64ToUint8Array,
uint8ArrayToObject,
} from "../../backgroundFunctions/encryption";
export const handleImportClick = async () => { export const handleImportClick = async () => {
const fileInput = document.createElement('input'); const fileInput = document.createElement("input");
fileInput.type = 'file'; fileInput.type = "file";
fileInput.accept = '.base64,.txt'; fileInput.accept = ".base64,.txt";
// Create a promise to handle file selection and reading synchronously // Create a promise to handle file selection and reading synchronously
return await new Promise((resolve, reject) => { return await new Promise((resolve, reject) => {
fileInput.onchange = () => { fileInput.onchange = () => {
const file = fileInput.files[0]; const file = fileInput.files[0];
if (!file) { if (!file) {
reject(new Error('No file selected')); reject(new Error("No file selected"));
return; return;
} }
@ -44,7 +46,7 @@ export const handleImportClick = async () => {
resolve(e.target.result); // Resolve with the file content resolve(e.target.result); // Resolve with the file content
}; };
reader.onerror = () => { reader.onerror = () => {
reject(new Error('Error reading file')); reject(new Error("Error reading file"));
}; };
reader.readAsText(file); // Read the file as text (Base64 string) reader.readAsText(file); // Read the file as text (Base64 string)
@ -53,8 +55,7 @@ export const handleImportClick = async () => {
// Trigger the file input dialog // Trigger the file input dialog
fileInput.click(); fileInput.click();
}); });
};
}
export const Save = ({ isDesktop, disableWidth, myName }) => { export const Save = ({ isDesktop, disableWidth, myName }) => {
const [pinnedApps, setPinnedApps] = useRecoilState(sortablePinnedAppsAtom); const [pinnedApps, setPinnedApps] = useRecoilState(sortablePinnedAppsAtom);
@ -65,7 +66,8 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
settingsLocalLastUpdatedAtom settingsLocalLastUpdatedAtom
); );
const setHasSettingsChangedAtom = useSetRecoilState(hasSettingsChangedAtom); const setHasSettingsChangedAtom = useSetRecoilState(hasSettingsChangedAtom);
const [isUsingImportExportSettings, setIsUsingImportExportSettings] = useRecoilState(isUsingImportExportSettingsAtom); const [isUsingImportExportSettings, setIsUsingImportExportSettings] =
useRecoilState(isUsingImportExportSettingsAtom);
const [canSave] = useRecoilState(canSaveSettingToQdnAtom); const [canSave] = useRecoilState(canSaveSettingToQdnAtom);
const [openSnack, setOpenSnack] = useState(false); const [openSnack, setOpenSnack] = useState(false);
@ -104,8 +106,6 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
settingsLocalLastUpdated, settingsLocalLastUpdated,
]); ]);
useEffect(() => { useEffect(() => {
setHasSettingsChangedAtom(hasChanged); setHasSettingsChangedAtom(hasChanged);
}, [hasChanged]); }, [hasChanged]);
@ -176,7 +176,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
message: "Sucessfully published to QDN", message: "Sucessfully published to QDN",
}); });
setOpenSnack(true); setOpenSnack(true);
setAnchorEl(null) setAnchorEl(null);
} }
} }
} catch (error) { } catch (error) {
@ -197,7 +197,7 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
const revertChanges = () => { const revertChanges = () => {
setPinnedApps(oldPinnedApps); setPinnedApps(oldPinnedApps);
saveToLocalStorage("ext_saved_settings", "sortablePinnedApps", null); saveToLocalStorage("ext_saved_settings", "sortablePinnedApps", null);
setAnchorEl(null) setAnchorEl(null);
}; };
return ( return (
@ -207,37 +207,22 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
disabled={ disabled={
// !hasChanged || // !hasChanged ||
// !canSave || // !canSave ||
isLoading isLoading
// settingsQdnLastUpdated === -100 // settingsQdnLastUpdated === -100
} }
> >
{isDesktop ? ( {isDesktop ? (
<IconWrapper <IconWrapper
disableWidth={disableWidth} disableWidth={disableWidth}
color="rgba(250, 250, 250, 0.5)"
label="Save" label="Save"
selected={false} selected={false}
> >
<SaveIcon <SaveIcon
color={ color={hasChanged && !isLoading ? "#5EB049" : undefined}
settingsQdnLastUpdated === -100
? "#8F8F91"
: hasChanged && !isLoading
? "#5EB049"
: "#8F8F91"
}
/> />
</IconWrapper> </IconWrapper>
) : ( ) : (
<SaveIcon <SaveIcon color={hasChanged && !isLoading ? "#5EB049" : undefined} />
color={
settingsQdnLastUpdated === -100
? "#8F8F91"
: hasChanged && !isLoading
? "#5EB049"
: "#8F8F91"
}
/>
)} )}
</ButtonBase> </ButtonBase>
<Popover <Popover
@ -261,15 +246,15 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
> >
{isUsingImportExportSettings && ( {isUsingImportExportSettings && (
<Box <Box
sx={{ sx={{
padding: "15px", padding: "15px",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
gap: 1, gap: 1,
width: '100%' width: "100%",
}} }}
> >
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",
display: "flex", display: "flex",
@ -286,59 +271,45 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
</Typography> </Typography>
<Spacer height="40px" /> <Spacer height="40px" />
<Button <Button
size="small" size="small"
onClick={()=> { onClick={() => {
saveToLocalStorage("ext_saved_settings_import_export", "sortablePinnedApps", null, true); saveToLocalStorage(
setIsUsingImportExportSettings(false) "ext_saved_settings_import_export",
}} "sortablePinnedApps",
variant="contained" null,
sx={{ true
);
setIsUsingImportExportSettings(false);
}}
variant="contained"
sx={{
backgroundColor: "var(--danger)",
color: "black",
fontWeight: "bold",
opacity: 0.7,
"&:hover": {
backgroundColor: "var(--danger)", backgroundColor: "var(--danger)",
color: "black", color: "black",
fontWeight: 'bold', opacity: 1,
opacity: 0.7, },
"&:hover": { }}
backgroundColor: "var(--danger)", >
color: "black", Use QDN saving
opacity: 1, </Button>
}, </Box>
}} </Box>
>
Use QDN saving
</Button>
</Box>
</Box>
)} )}
{!isUsingImportExportSettings && ( {!isUsingImportExportSettings && (
<Box <Box
sx={{ sx={{
padding: "15px", padding: "15px",
display: "flex", display: "flex",
flexDirection: "column", flexDirection: "column",
gap: 1, gap: 1,
width: '100%' width: "100%",
}} }}
> >
{!myName ? ( {!myName ? (
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "14px",
}}
>
You need a registered Qortal name to save your pinned apps to QDN.
</Typography>
</Box>
) : (
<>
{hasChanged && (
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",
@ -352,213 +323,242 @@ export const Save = ({ isDesktop, disableWidth, myName }) => {
fontSize: "14px", fontSize: "14px",
}} }}
> >
You have unsaved changes to your pinned apps. Save them to QDN. You need a registered Qortal name to save your pinned apps to
QDN.
</Typography> </Typography>
<Spacer height="10px" /> </Box>
<LoadingButton ) : (
sx={{ <>
backgroundColor: "var(--green)", {hasChanged && (
color: "black", <Box
opacity: 0.7, sx={{
fontWeight: 'bold', width: "100%",
"&:hover": { display: "flex",
backgroundColor: "var(--green)", flexDirection: "column",
color: "black", alignItems: "center",
opacity: 1, }}
}, >
}}
size="small"
loading={isLoading}
onClick={saveToQdn}
variant="contained"
>
Save to QDN
</LoadingButton>
<Spacer height="20px" />
{!isNaN(settingsQdnLastUpdated) && settingsQdnLastUpdated > 0 && (
<>
<Typography <Typography
sx={{ sx={{
fontSize: "14px", fontSize: "14px",
}} }}
> >
Don't like your current local changes? Would you like to You have unsaved changes to your pinned apps. Save them to
reset to your saved QDN pinned apps? QDN.
</Typography> </Typography>
<Spacer height="10px" /> <Spacer height="10px" />
<LoadingButton <LoadingButton
size="small"
loading={isLoading}
onClick={revertChanges}
variant="contained"
sx={{ sx={{
backgroundColor: "var(--danger)", backgroundColor: "var(--green)",
color: "black", color: "black",
fontWeight: 'bold',
opacity: 0.7, opacity: 0.7,
fontWeight: "bold",
"&:hover": { "&:hover": {
backgroundColor: "var(--danger)", backgroundColor: "var(--green)",
color: "black", color: "black",
opacity: 1, opacity: 1,
}, },
}} }}
size="small"
loading={isLoading}
onClick={saveToQdn}
variant="contained"
> >
Revert to QDN Save to QDN
</LoadingButton> </LoadingButton>
</> <Spacer height="20px" />
{!isNaN(settingsQdnLastUpdated) &&
settingsQdnLastUpdated > 0 && (
<>
<Typography
sx={{
fontSize: "14px",
}}
>
Don't like your current local changes? Would you
like to reset to your saved QDN pinned apps?
</Typography>
<Spacer height="10px" />
<LoadingButton
size="small"
loading={isLoading}
onClick={revertChanges}
variant="contained"
sx={{
backgroundColor: "var(--danger)",
color: "black",
fontWeight: "bold",
opacity: 0.7,
"&:hover": {
backgroundColor: "var(--danger)",
color: "black",
opacity: 1,
},
}}
>
Revert to QDN
</LoadingButton>
</>
)}
{!isNaN(settingsQdnLastUpdated) &&
settingsQdnLastUpdated === 0 && (
<>
<Typography
sx={{
fontSize: "14px",
}}
>
Don't like your current local changes? Would you
like to reset to the default pinned apps?
</Typography>
<Spacer height="10px" />
<LoadingButton
loading={isLoading}
onClick={revertChanges}
variant="contained"
>
Revert to default
</LoadingButton>
</>
)}
</Box>
)} )}
{!isNaN(settingsQdnLastUpdated) && settingsQdnLastUpdated === 0 && ( {!isNaN(settingsQdnLastUpdated) &&
<> settingsQdnLastUpdated === -100 &&
isUsingImportExportSettings !== true && (
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "14px",
}}
>
The app was unable to download your existing QDN-saved
pinned apps. Would you like to overwrite those changes?
</Typography>
<Spacer height="10px" />
<LoadingButton
size="small"
loading={isLoading}
onClick={saveToQdn}
variant="contained"
sx={{
backgroundColor: "var(--danger)",
color: "black",
fontWeight: "bold",
opacity: 0.7,
"&:hover": {
backgroundColor: "var(--danger)",
color: "black",
opacity: 1,
},
}}
>
Overwrite to QDN
</LoadingButton>
</Box>
)}
{!hasChanged && (
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography <Typography
sx={{ sx={{
fontSize: "14px", fontSize: "14px",
}} }}
> >
Don't like your current local changes? Would you like to You currently do not have any changes to your pinned apps
reset to the default pinned apps?
</Typography> </Typography>
<Spacer height="10px" /> </Box>
<LoadingButton
loading={isLoading}
onClick={revertChanges}
variant="contained"
>
Revert to default
</LoadingButton>
</>
)} )}
</Box>
)}
{!isNaN(settingsQdnLastUpdated) && settingsQdnLastUpdated === -100 && isUsingImportExportSettings !== true && (
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "14px",
}}
>
The app was unable to download your existing QDN-saved pinned
apps. Would you like to overwrite those changes?
</Typography>
<Spacer height="10px" />
<LoadingButton
size="small"
loading={isLoading}
onClick={saveToQdn}
variant="contained"
sx={{
backgroundColor: "var(--danger)",
color: "black",
fontWeight: 'bold',
opacity: 0.7,
"&:hover": {
backgroundColor: "var(--danger)",
color: "black",
opacity: 1,
},
}}
>
Overwrite to QDN
</LoadingButton>
</Box>
)}
{!hasChanged && (
<Box
sx={{
width: "100%",
display: "flex",
flexDirection: "column",
alignItems: "center",
}}
>
<Typography
sx={{
fontSize: "14px",
}}
>
You currently do not have any changes to your pinned apps
</Typography>
</Box>
)}
</> </>
)} )}
</Box> </Box>
)} )}
<Box <Box
sx={{
padding: "15px",
display: "flex",
flexDirection: "column",
gap: 1,
width: "100%",
}}
>
<Box
sx={{ sx={{
padding: "15px",
display: "flex", display: "flex",
flexDirection: "column", gap: "10px",
gap: 1, justifyContent: "flex-end",
width: '100%' width: "100%",
}} }}
> >
<Box sx={{ <ButtonBase
display: 'flex', onClick={async () => {
gap: '10px', try {
justifyContent: 'flex-end', const fileContent = await handleImportClick();
width: '100%' const decryptedData = await decryptData({
}}> encryptedData: fileContent,
<ButtonBase onClick={async () => { });
try { const decryptToUnit8ArraySubject =
const fileContent = await handleImportClick(); base64ToUint8Array(decryptedData);
const decryptedData = await decryptData({ const responseData = uint8ArrayToObject(
encryptedData: fileContent, decryptToUnit8ArraySubject
}); );
const decryptToUnit8ArraySubject = if (Array.isArray(responseData)) {
base64ToUint8Array(decryptedData); saveToLocalStorage(
const responseData = uint8ArrayToObject( "ext_saved_settings_import_export",
decryptToUnit8ArraySubject "sortablePinnedApps",
); responseData,
if(Array.isArray(responseData)){ {
saveToLocalStorage("ext_saved_settings_import_export", "sortablePinnedApps", responseData, { isUsingImportExport: true,
isUsingImportExport: true
});
setPinnedApps(responseData)
setOldPinnedApps(responseData)
setIsUsingImportExportSettings(true)
}
} catch (error) {
console.log("error", error);
} }
}}> );
setPinnedApps(responseData);
Import setOldPinnedApps(responseData);
</ButtonBase> setIsUsingImportExportSettings(true);
<ButtonBase onClick={async () => { }
try { } catch (error) {
const data64 = await objectToBase64(pinnedApps); console.log("error", error);
}
const encryptedData = await encryptData({ }}
data64, >
}); Import
const blob = new Blob([encryptedData], {
type: "text/plain",
});
const timestamp = new Date()
.toISOString()
.replace(/:/g, "-"); // Safe timestamp for filenames
const filename = `qortal-new-ui-backup-settings-${timestamp}.txt`;
await saveFileToDiskGeneric(blob, filename)
} catch (error) {
console.log('error', error)
}
}}>
Export
</ButtonBase> </ButtonBase>
</Box> <ButtonBase
</Box> onClick={async () => {
try {
const data64 = await objectToBase64(pinnedApps);
const encryptedData = await encryptData({
data64,
});
const blob = new Blob([encryptedData], {
type: "text/plain",
});
const timestamp = new Date().toISOString().replace(/:/g, "-"); // Safe timestamp for filenames
const filename = `qortal-new-ui-backup-settings-${timestamp}.txt`;
await saveFileToDiskGeneric(blob, filename);
} catch (error) {
console.log("error", error);
}
}}
>
Export
</ButtonBase>
</Box>
</Box>
</Popover> </Popover>
<CustomizedSnackbars <CustomizedSnackbars
duration={3500} duration={3500}

View File

@ -0,0 +1,34 @@
import { createContext, useContext, useState, useMemo } from 'react';
import { createTheme, ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
const darkTheme = createTheme({
palette: {
mode: 'dark',
},
});
const lightTheme = createTheme({
palette: {
mode: 'light',
},
});
const ThemeContext = createContext({ themeMode: 'light', toggleTheme: () => {} });
export const ThemeProvider = ({ children }: { children: React.ReactNode }) => {
const [themeMode, setThemeMode] = useState('light');
const theme = useMemo(() => (themeMode === 'light' ? lightTheme : darkTheme), [themeMode]);
const toggleTheme = () => {
setThemeMode((prevMode) => (prevMode === 'light' ? 'dark' : 'light'));
};
return (
<ThemeContext.Provider value={{ themeMode, toggleTheme }}>
<MuiThemeProvider theme={theme}>{children}</MuiThemeProvider>
</ThemeContext.Provider>
);
};
export const useThemeContext = () => useContext(ThemeContext);

View File

@ -0,0 +1,77 @@
import { useThemeContext } from "./ThemeContext";
import { styled, Switch } from "@mui/material";
const ThemeSwitch = styled(Switch)(({ theme }) => ({
width: 62,
height: 34,
padding: 7,
"& .MuiSwitch-switchBase": {
margin: 1,
padding: 0,
transform: "translateX(6px)",
"&.Mui-checked": {
color: "#fff",
transform: "translateX(22px)",
"& .MuiSwitch-thumb:before": {
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
"#fff"
)}" d="M4.2 2.5l-.7 1.8-1.8.7 1.8.7.7 1.8.6-1.8L6.7 5l-1.9-.7-.6-1.8zm15 8.3a6.7 6.7 0 11-6.6-6.6 5.8 5.8 0 006.6 6.6z"/></svg>')`,
},
"& + .MuiSwitch-track": {
opacity: 1,
backgroundColor: "#aab4be",
...theme.applyStyles("dark", {
backgroundColor: "#8796A5",
}),
},
},
},
"& .MuiSwitch-thumb": {
backgroundColor: "#001e3c",
width: 32,
height: 32,
"&::before": {
content: "''",
position: "absolute",
width: "100%",
height: "100%",
left: 0,
top: 0,
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
backgroundImage: `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="20" width="20" viewBox="0 0 20 20"><path fill="${encodeURIComponent(
"#fff"
)}" d="M9.305 1.667V3.75h1.389V1.667h-1.39zm-4.707 1.95l-.982.982L5.09 6.072l.982-.982-1.473-1.473zm10.802 0L13.927 5.09l.982.982 1.473-1.473-.982-.982zM10 5.139a4.872 4.872 0 00-4.862 4.86A4.872 4.872 0 0010 14.862 4.872 4.872 0 0014.86 10 4.872 4.872 0 0010 5.139zm0 1.389A3.462 3.462 0 0113.471 10a3.462 3.462 0 01-3.473 3.472A3.462 3.462 0 016.527 10 3.462 3.462 0 0110 6.528zM1.665 9.305v1.39h2.083v-1.39H1.666zm14.583 0v1.39h2.084v-1.39h-2.084zM5.09 13.928L3.616 15.4l.982.982 1.473-1.473-.982-.982zm9.82 0l-.982.982 1.473 1.473.982-.982-1.473-1.473zM9.305 16.25v2.083h1.389V16.25h-1.39z"/></svg>')`,
},
...theme.applyStyles("dark", {
backgroundColor: "#003892",
}),
},
"& .MuiSwitch-track": {
opacity: 1,
backgroundColor: "#aab4be",
borderRadius: 20 / 2,
...theme.applyStyles("dark", {
backgroundColor: "#8796A5",
}),
},
}));
const ThemeSelector = ({ style }) => {
const { themeMode, toggleTheme } = useThemeContext();
return (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "center",
gap: "1px",
...style,
}}
>
<ThemeSwitch checked={themeMode === "dark"} onChange={toggleTheme} />
</div>
);
};
export default ThemeSelector;

View File

@ -1,43 +1,40 @@
@font-face { @font-face {
font-family: 'Inter'; font-family: "Inter";
src: url('./styles/fonts/Inter-SemiBold.ttf') format('truetype'); src: url("./styles/fonts/Inter-SemiBold.ttf") format("truetype");
font-weight: 600; font-weight: 600;
} }
@font-face { @font-face {
font-family: 'Inter'; font-family: "Inter";
src: url('./styles/fonts/Inter-ExtraBold.ttf') format('truetype'); src: url("./styles/fonts/Inter-ExtraBold.ttf") format("truetype");
font-weight: 800; font-weight: 800;
} }
@font-face { @font-face {
font-family: 'Inter'; font-family: "Inter";
src: url('./styles/fonts/Inter-Bold.ttf') format('truetype'); src: url("./styles/fonts/Inter-Bold.ttf") format("truetype");
font-weight: 700; font-weight: 700;
} }
@font-face { @font-face {
font-family: 'Inter'; font-family: "Inter";
src: url('./styles/fonts/Inter-Regular.ttf') format('truetype'); src: url("./styles/fonts/Inter-Regular.ttf") format("truetype");
font-weight: 400; font-weight: 400;
} }
:root { :root {
padding: 0px; padding: 0px;
margin: 0px; margin: 0px;
box-sizing: border-box !important; box-sizing: border-box !important;
word-break: break-word; word-break: break-word;
--color-instance : #1E1E20; --color-instance: #1e1e20;
--color-instance-popover-bg: #222222; --color-instance-popover-bg: #222222;
--Mail-Background: rgba(49, 51, 56, 1); --Mail-Background: rgba(49, 51, 56, 1);
--new-message-text: black; --new-message-text: black;
--bg-primary: rgba(31, 32, 35, 1);
--bg-primary : rgba(31, 32, 35, 1);
--bg-2: #27282c; --bg-2: #27282c;
--bg-3: rgba(0, 0, 0, 0.1); --bg-3: rgba(0, 0, 0, 0.1);
--unread: #4297e2; --unread: #4297e2;
--danger: #B14646; --danger: #b14646;
--apps-circle: #1F2023; --apps-circle: #1f2023;
--green: #5EB049; --green: #5eb049;
} }
body { body {
@ -97,10 +94,8 @@ body {
initial-value: transparent; initial-value: transparent;
} }
.scrollable-container { .scrollable-container {
transition: --var1 0.4s; transition: --var1 0.4s;
} }
.scrollable-container:hover { .scrollable-container:hover {
@ -115,11 +110,6 @@ body {
opacity: 0; opacity: 0;
} }
/* Mobile-specific scrollbar styles */ /* Mobile-specific scrollbar styles */
@media only screen and (max-width: 600px) { @media only screen and (max-width: 600px) {
::-webkit-scrollbar { ::-webkit-scrollbar {
@ -137,11 +127,11 @@ body {
background-color: whitesmoke; background-color: whitesmoke;
} }
html, body { html,
overscroll-behavior:none !important; body {
overscroll-behavior: none !important;
} }
.swiper { .swiper {
width: 100%; width: 100%;
} }

View File

@ -1,81 +1,20 @@
import React from 'react' import React from "react";
import ReactDOM from 'react-dom/client' import ReactDOM from "react-dom/client";
import App from './App.tsx' import App from "./App.tsx";
import './index.css' import "./index.css";
import "./messaging/messagesToBackground"; import "./messaging/messagesToBackground";
import { ThemeProvider, createTheme } from '@mui/material/styles'; import { MessageQueueProvider } from "./MessageQueueContext.tsx";
import { CssBaseline } from '@mui/material'; import { RecoilRoot } from "recoil";
import { MessageQueueProvider } from './MessageQueueContext.tsx'; import { ThemeProvider } from "./components/Theme/ThemeContext.tsx";
import { RecoilRoot } from 'recoil';
const theme = createTheme({
palette: {
primary: {
main: '#232428', // Primary color (e.g., used for buttons, headers, etc.)
},
secondary: {
main: '#232428', // Secondary color
},
background: {
default: '#27282c', // Default background color
paper: '#1d1d1d', // Paper component background (for dropdowns, dialogs, etc.)
},
text: {
primary: '#ffffff', // White as the primary text color
secondary: '#b0b0b0', // Light gray for secondary text
disabled: '#808080', // Gray for disabled text
},
action: {
// disabledBackground: 'set color of background here',
disabled: 'rgb(255 255 255 / 70%)'
}
},
typography: {
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', // Font family
h1: {
color: '#ffffff', // White color for h1 elements
},
h2: {
color: '#ffffff', // White color for h2 elements
},
body1: {
color: '#ffffff', // Default body text color
},
body2: {
color: '#b0b0b0', // Lighter text for body2, often used for secondary text
},
},
components: {
MuiOutlinedInput: {
styleOverrides: {
root: {
".MuiOutlinedInput-notchedOutline": {
borderColor: "white", // ⚪ Default outline color
},
},
},
},
MuiSelect: {
styleOverrides: {
icon: {
color: "white", // ✅ Caret (dropdown arrow) color
},
},
},
},
});
export default theme; ReactDOM.createRoot(document.getElementById("root")!).render(
ReactDOM.createRoot(document.getElementById('root')!).render(
<> <>
<ThemeProvider theme={theme}> <ThemeProvider>
<CssBaseline /> <MessageQueueProvider>
<MessageQueueProvider> <RecoilRoot>
<RecoilRoot> <App />
<App /> </RecoilRoot>
</RecoilRoot> </MessageQueueProvider>
</MessageQueueProvider>
</ThemeProvider> </ThemeProvider>
</>, </>
) );

View File

@ -4,6 +4,7 @@
"useDefineForClassFields": true, "useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"], "lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext", "module": "ESNext",
"noImplicitAny": false,
"skipLibCheck": true, "skipLibCheck": true,
/* Bundler mode */ /* Bundler mode */

View File

@ -1,51 +1,55 @@
/// <reference types="vitest" /> /// <reference types="vitest" />
import { defineConfig } from 'vite'; import { defineConfig } from "vite";
import react from '@vitejs/plugin-react'; import react from "@vitejs/plugin-react";
// Import path module for resolving file paths // Import path module for resolving file paths
import fixReactVirtualized from 'esbuild-plugin-react-virtualized' import fixReactVirtualized from "esbuild-plugin-react-virtualized";
import wasm from 'vite-plugin-wasm'; import wasm from "vite-plugin-wasm";
import topLevelAwait from 'vite-plugin-top-level-await'; import topLevelAwait from "vite-plugin-top-level-await";
import { VitePWA } from 'vite-plugin-pwa'; import { VitePWA } from "vite-plugin-pwa";
export default defineConfig({ export default defineConfig({
test: { test: {
environment: 'jsdom', environment: "jsdom",
globals: true, globals: true,
setupFiles: ['./src/test/setup.ts'] setupFiles: ["./src/test/setup.ts"],
}, },
assetsInclude: ['**/*.wasm'], assetsInclude: ["**/*.wasm"],
plugins: [react(), wasm(), topLevelAwait(), VitePWA({ plugins: [
registerType: 'prompt', react(),
manifest: { wasm(),
name: 'Qortal Hub', topLevelAwait(),
short_name: 'Hub', VitePWA({
description: 'Your easy access to the Qortal blockchain', registerType: "prompt",
start_url: '/', manifest: {
display: 'standalone', name: "Qortal Hub",
theme_color: '#ffffff', short_name: "Hub",
background_color: '#ffffff', description: "Your easy access to the Qortal blockchain",
icons: [ start_url: "/",
{ display: "standalone",
src: '/qortal192.png', theme_color: "#ffffff",
sizes: '192x192', background_color: "#ffffff",
type: 'image/png', icons: [
}, {
{ src: "/qortal192.png",
src: '/qortal.png', sizes: "192x192",
sizes: '512x512', type: "image/png",
type: 'image/png', },
}, {
], src: "/qortal.png",
}, sizes: "512x512",
workbox: { type: "image/png",
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit },
disableDevLogs: true, // Suppresses logs in development ],
}, },
})], workbox: {
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB limit
disableDevLogs: true, // Suppresses logs in development
},
}),
],
optimizeDeps: { optimizeDeps: {
esbuildOptions: { esbuildOptions: {
plugins: [fixReactVirtualized], plugins: [fixReactVirtualized],
} },
} },
}); });