diff --git a/.cspell.json b/.cspell.json index a15c231d6..ac84ff63f 100644 --- a/.cspell.json +++ b/.cspell.json @@ -375,7 +375,17 @@ "asar", "icns", "nsis", - "WARNING️" + "WARNING️", + "Periode", + "maximizable", + "mainconfig", + "electronmon", + "languagedetector", + "teamsupercell", + "pmmmwh", + "compat", + "webm", + "webp" ], "useGitignore": true, "ignorePaths": [ @@ -424,5 +434,8 @@ "apps/desktop/i18n/**", "apps/**/*.{svg,css,scss}", ".scripts/icon-utils/icons/**", + "apps/server-web/src/locales/**/*.json", + "apps/server-web/src/resources/*", + "apps/server-web/assets/*" ] } diff --git a/.github/workflows/desktop-server-api.apps.yml b/.github/workflows/desktop-server-api.apps.yml index afe85a1d9..f90c82507 100644 --- a/.github/workflows/desktop-server-api.apps.yml +++ b/.github/workflows/desktop-server-api.apps.yml @@ -369,7 +369,7 @@ jobs: PROCESSOR_REVISION: '' PSModuleAnalysisCachePath: '' PSModulePath: '' - Path: 'C:\hostedtoolcache\windows\node\20.11.1\x64;C:\Program Files\Git\bin;C:\npm\prefix;C:\hostedtoolcache\windows\Python\3.9.13\x64\Scripts;C:\hostedtoolcache\windows\Python\3.9.13\x64;C:\Program Files\OpenSSL\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Program Files\CMake\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Program Files\GitHub CLI\;c:\tools\php;C:\Program Files (x86)\sbt\bin;C:\Program Files\Amazon\AWSCLIV2\;C:\Users\runneradmin\.dotnet\tools;C:\Users\runneradmin\.cargo\bin;C:\Users\runneradmin\AppData\Local\Microsoft\WindowsApps' + Path: 'C:\hostedtoolcache\windows\node\20.11.1\x64;C:\Program Files\Git\bin;C:\npm\prefix;C:\hostedtoolcache\windows\Python\3.9.13\x64\Scripts;C:\hostedtoolcache\windows\Python\3.9.13\x64;C:\Program Files\OpenSSL\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Program Files\CMake\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\Git\usr\bin;C:\Program Files\Amazon\AWSCLIV2\' DOTNET_MULTILEVEL_LOOKUP: '' DOTNET_NOLOGO: '' DOTNET_SKIP_FIRST_TIME_EXPERIENCE: '' @@ -405,4 +405,3 @@ jobs: # APPDATA: '' # COMMONPROGRAMFILES: '' # CommonProgramFiles(x86) - # CommonProgramW6432 diff --git a/.github/workflows/desktop-server-web.apps.yml b/.github/workflows/desktop-server-web.apps.yml index 2fcc04f92..9523f72f8 100644 --- a/.github/workflows/desktop-server-web.apps.yml +++ b/.github/workflows/desktop-server-web.apps.yml @@ -360,7 +360,7 @@ jobs: PROCESSOR_REVISION: '' PSModuleAnalysisCachePath: '' PSModulePath: '' - Path: 'C:\hostedtoolcache\windows\node\20.11.1\x64;C:\Program Files\Git\bin;C:\npm\prefix;C:\hostedtoolcache\windows\Python\3.9.13\x64\Scripts;C:\hostedtoolcache\windows\Python\3.9.13\x64;C:\Program Files\OpenSSL\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Program Files\CMake\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Program Files\GitHub CLI\;c:\tools\php;C:\Program Files (x86)\sbt\bin;C:\Program Files\Amazon\AWSCLIV2\;C:\Users\runneradmin\.dotnet\tools;C:\Users\runneradmin\.cargo\bin;C:\Users\runneradmin\AppData\Local\Microsoft\WindowsApps' + Path: 'C:\hostedtoolcache\windows\node\20.11.1\x64;C:\Program Files\Git\bin;C:\npm\prefix;C:\hostedtoolcache\windows\Python\3.9.13\x64\Scripts;C:\hostedtoolcache\windows\Python\3.9.13\x64;C:\Program Files\OpenSSL\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Program Files\CMake\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\Git\usr\bin;C:\Program Files\Amazon\AWSCLIV2\' DOTNET_MULTILEVEL_LOOKUP: '' DOTNET_NOLOGO: '' DOTNET_SKIP_FIRST_TIME_EXPERIENCE: '' @@ -396,4 +396,3 @@ jobs: # APPDATA: '' # COMMONPROGRAMFILES: '' # CommonProgramFiles(x86) - # CommonProgramW6432 diff --git a/.github/workflows/desktop.apps.yml b/.github/workflows/desktop.apps.yml index 618ef3814..c0ff59ba8 100644 --- a/.github/workflows/desktop.apps.yml +++ b/.github/workflows/desktop.apps.yml @@ -369,7 +369,7 @@ jobs: PROCESSOR_REVISION: '' PSModuleAnalysisCachePath: '' PSModulePath: '' - Path: 'C:\hostedtoolcache\windows\node\20.11.1\x64;C:\Program Files\Git\bin;C:\npm\prefix;C:\hostedtoolcache\windows\Python\3.9.13\x64\Scripts;C:\hostedtoolcache\windows\Python\3.9.13\x64;C:\Program Files\OpenSSL\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Program Files\CMake\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Program Files\GitHub CLI\;c:\tools\php;C:\Program Files (x86)\sbt\bin;C:\Program Files\Amazon\AWSCLIV2\;C:\Users\runneradmin\.dotnet\tools;C:\Users\runneradmin\.cargo\bin;C:\Users\runneradmin\AppData\Local\Microsoft\WindowsApps' + Path: 'C:\hostedtoolcache\windows\node\20.11.1\x64;C:\Program Files\Git\bin;C:\npm\prefix;C:\hostedtoolcache\windows\Python\3.9.13\x64\Scripts;C:\hostedtoolcache\windows\Python\3.9.13\x64;C:\Program Files\OpenSSL\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\PowerShell\7\;C:\Program Files\CMake\bin;C:\Program Files\nodejs\;C:\Program Files\Git\cmd;C:\Program Files\Git\usr\bin;C:\Program Files\Amazon\AWSCLIV2\' DOTNET_MULTILEVEL_LOOKUP: '' DOTNET_NOLOGO: '' DOTNET_SKIP_FIRST_TIME_EXPERIENCE: '' @@ -405,4 +405,3 @@ jobs: # APPDATA: '' # COMMONPROGRAMFILES: '' # CommonProgramFiles(x86) - # CommonProgramW6432 diff --git a/apps/extensions/yarn.lock b/apps/extensions/yarn.lock index fd1d0ef18..aab83a967 100644 --- a/apps/extensions/yarn.lock +++ b/apps/extensions/yarn.lock @@ -4633,9 +4633,9 @@ reusify@^1.0.4: integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rollup@^3.2.5: - version "3.5.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.5.0.tgz#dfe5cba22c2c074691b4c25b9b8e9cfd90ac712b" - integrity sha512-TYu2L+TGhmNsXCtByont89u+ATQLcDy6A+++PwLXYunRtOm7XnaD+65s1pvewaOxMYR0eOkMXn9/i0saBxxpnQ== + version "3.29.5" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.5.tgz#8a2e477a758b520fb78daf04bca4c522c1da8a54" + integrity sha512-GVsDdsbJzzy4S/v3dqWPJ7EfvZJfCHiDqe80IyrF59LYuP+e6U1LJoUqeuqRbwAWoMNoXivMNeNAOf5E22VA1w== optionalDependencies: fsevents "~2.3.2" diff --git a/apps/server-web/postcss.config.js b/apps/server-web/postcss.config.js index 3ea9307f4..436740524 100644 --- a/apps/server-web/postcss.config.js +++ b/apps/server-web/postcss.config.js @@ -1,3 +1,10 @@ +const path = require('path'); + module.exports = { - plugins: [require('tailwindcss'), require('autoprefixer')], + plugins: { + tailwindcss: { + config: path.join(__dirname, 'tailwind.config.js') + }, + autoprefixer: {} + } }; diff --git a/apps/server-web/src/locales/i18n/bg/translation.json b/apps/server-web/src/locales/i18n/bg/translation.json index 22c0e2529..e0b133967 100644 --- a/apps/server-web/src/locales/i18n/bg/translation.json +++ b/apps/server-web/src/locales/i18n/bg/translation.json @@ -50,7 +50,7 @@ }, "AUTO_UPDATE_TITLE": "Автоматична проверка на актуализацията", "AUTO_UPDATE_SUBTITLE": "Активирайте автоматичната проверка на актуализацията, за да стартирате заявка за проверка дали е налична нова версия и да уведомите", - "AUTO_UPDATE_TOGLE": "Автоматична актуализация", + "AUTO_UPDATE_TOGGLE": "Автоматична актуализация", "CHECK_UPDATE_TITLE": "Проверете и актуализирайте версията на приложението си", "CHECK_UPDATE_SUBTITLE": "Налична е нова актуализация! Моля, щракнете върху бутона Изтегляне сега по-долу.", "LANGUAGES": "Езици" diff --git a/apps/server-web/src/locales/i18n/en/translation.json b/apps/server-web/src/locales/i18n/en/translation.json index 1d506ae0e..763e3924c 100644 --- a/apps/server-web/src/locales/i18n/en/translation.json +++ b/apps/server-web/src/locales/i18n/en/translation.json @@ -50,7 +50,7 @@ }, "AUTO_UPDATE_TITLE": "Automatic Update Check", "AUTO_UPDATE_SUBTITLE": "Enable automatice update check, in order to run a request to check if new version is available and notify", - "AUTO_UPDATE_TOGLE": "Automatic Update", + "AUTO_UPDATE_TOGGLE": "Automatic Update", "CHECK_UPDATE_TITLE": "Check & Update your app version", "CHECK_UPDATE_SUBTITLE": "New Update is available! Please click button Download Now below.", "LANGUAGES": "Languages" diff --git a/apps/server-web/src/main/helpers/constant.ts b/apps/server-web/src/main/helpers/constant.ts index 89889dd37..b6bc8e792 100644 --- a/apps/server-web/src/main/helpers/constant.ts +++ b/apps/server-web/src/main/helpers/constant.ts @@ -15,7 +15,8 @@ export const EventLists = { CHANGE_LANGUAGE: 'CHANGE_LANGUAGE', OPEN_WEB: 'OPEN_WEB', SERVER_WINDOW: 'SERVER_WINDOW', - RESTART_SERVER: 'RESTART_SERVER' + RESTART_SERVER: 'RESTART_SERVER', + CHANGE_THEME: 'CHANGE_THEME', } export const SettingPageTypeMessage = { @@ -35,7 +36,8 @@ export const SettingPageTypeMessage = { updateSetting: 'update-setting', updateSettingResponse: 'update-setting-response', updateCancel: 'update-cancel', - restartServer: 'restart-server' + restartServer: 'restart-server', + themeChange: 'theme-change' } export const ServerPageTypeMessage = { diff --git a/apps/server-web/src/main/helpers/interfaces/i-constant.ts b/apps/server-web/src/main/helpers/interfaces/i-constant.ts index 64cdc0211..421769ce3 100644 --- a/apps/server-web/src/main/helpers/interfaces/i-constant.ts +++ b/apps/server-web/src/main/helpers/interfaces/i-constant.ts @@ -1 +1 @@ -export type Channels = 'setting-page' | 'ipc-renderer' | 'language-set' | 'updater-page' | 'server-page'; +export type Channels = 'setting-page' | 'ipc-renderer' | 'language-set' | 'updater-page' | 'server-page' | 'theme-change' | 'current-theme'; diff --git a/apps/server-web/src/main/helpers/interfaces/i-server.ts b/apps/server-web/src/main/helpers/interfaces/i-server.ts index adb236d32..469c87b9d 100644 --- a/apps/server-web/src/main/helpers/interfaces/i-server.ts +++ b/apps/server-web/src/main/helpers/interfaces/i-server.ts @@ -2,6 +2,7 @@ interface GeneralConfig { lang?: string autoUpdate?: boolean updateCheckPeriode?: string + theme?: string [key: string]: any } diff --git a/apps/server-web/src/main/helpers/services/libs/desktop-store.ts b/apps/server-web/src/main/helpers/services/libs/desktop-store.ts index 18c14ba73..860ee190e 100644 --- a/apps/server-web/src/main/helpers/services/libs/desktop-store.ts +++ b/apps/server-web/src/main/helpers/services/libs/desktop-store.ts @@ -29,7 +29,7 @@ export const LocalStore = { const config: WebServer = { server: { PORT: 3002, - GAUZY_API_SERVER_URL: 'htpp://localhost:3000', + GAUZY_API_SERVER_URL: 'http://localhost:3000', NEXT_PUBLIC_GAUZY_API_SERVER_URL: 'http://localhost:3000' }, general: { diff --git a/apps/server-web/src/main/helpers/services/libs/server-task.ts b/apps/server-web/src/main/helpers/services/libs/server-task.ts index be4eae744..15cfedc77 100644 --- a/apps/server-web/src/main/helpers/services/libs/server-task.ts +++ b/apps/server-web/src/main/helpers/services/libs/server-task.ts @@ -19,7 +19,7 @@ export abstract class ServerTask { protected isRunning: boolean; protected signal: AbortSignal; private criticalMessageError = ['[CRITICAL::ERROR]', 'EADDRINUSE']; - public eventEmmitter: EventEmitter; + public eventEmitter: EventEmitter; protected constructor( processPath: string, @@ -28,7 +28,7 @@ export abstract class ServerTask { successMessage: string, errorMessage: string, signal: AbortSignal, - eventEmmitter: EventEmitter + eventEmitter: EventEmitter ) { this.processPath = processPath; this.args = args; @@ -39,7 +39,7 @@ export abstract class ServerTask { this.pid = `${this.args.serviceName}Pid`; this.signal = signal; this.isRunning = false; - this.eventEmmitter = eventEmmitter; + this.eventEmitter = eventEmitter; this.loggerObserver = new Observer((msg: string) => { console.log('Sending log_state:', msg); @@ -99,8 +99,8 @@ export abstract class ServerTask { service.on('disconnect', () => { console.log(LOG_TYPES.SERVER_LOG, 'Webserver disconnected'); - if (this.eventEmmitter) { - this.eventEmmitter.emit(EventLists.webServerStopped); + if (this.eventEmitter) { + this.eventEmitter.emit(EventLists.webServerStopped); } }) @@ -108,8 +108,8 @@ export abstract class ServerTask { console.log('child process error', err); }) - if (this.eventEmmitter) { - this.eventEmmitter.emit(EventLists.webServerStarted); + if (this.eventEmitter) { + this.eventEmitter.emit(EventLists.webServerStarted); } this.config.setting = { server: { ...this.config.setting.server, [this.pid]: service.pid } }; } catch (error) { diff --git a/apps/server-web/src/main/main.ts b/apps/server-web/src/main/main.ts index 636b57d51..33ad2a1c0 100644 --- a/apps/server-web/src/main/main.ts +++ b/apps/server-web/src/main/main.ts @@ -364,6 +364,16 @@ const onInitApplication = () => { }) }) + eventEmitter.on(EventLists.CHANGE_THEME, (data) => { + LocalStore.updateConfigSetting({ + general: { + theme: data + } + }) + logWindow?.webContents.send('themeSignal', { type: SettingPageTypeMessage.themeChange, data }); + settingWindow?.webContents.send('themeSignal', { type: SettingPageTypeMessage.themeChange, data }); + }) + eventEmitter.on(EventLists.gotoAbout, async () => { if (!settingWindow) { await createWindow('SETTING_WINDOW'); @@ -467,6 +477,9 @@ ipcMain.on(IPC_TYPES.SETTING_PAGE, async (event, arg) => { case SettingPageTypeMessage.restartServer: eventEmitter.emit(EventLists.RESTART_SERVER) break; + case SettingPageTypeMessage.themeChange: + eventEmitter.emit(EventLists.CHANGE_THEME, arg.data) + break; default: break; } @@ -505,6 +518,11 @@ ipcMain.on(IPC_TYPES.SERVER_PAGE, (_, arg) => { } }) +ipcMain.handle('current-theme', async () => { + const setting: WebServer = LocalStore.getStore('config'); + return setting.general?.theme;; +}) + const createIntervalAutoUpdate = () => { if (intervalUpdate) { clearInterval(intervalUpdate) @@ -513,10 +531,10 @@ const createIntervalAutoUpdate = () => { if (setting.general?.autoUpdate && setting.general.updateCheckPeriode) { const checkIntervalSecond = parseInt(setting.general.updateCheckPeriode); if (!Number.isNaN(checkIntervalSecond)) { - const intevalMS = checkIntervalSecond * 60 * 1000; + const intervalMS = checkIntervalSecond * 60 * 1000; intervalUpdate = setInterval(() => { updater.checkUpdateNotify(); - }, intevalMS) + }, intervalMS) } } } diff --git a/apps/server-web/src/main/main_.ts b/apps/server-web/src/main/main_.ts index 05b44eb4f..10c8220ed 100644 --- a/apps/server-web/src/main/main_.ts +++ b/apps/server-web/src/main/main_.ts @@ -102,8 +102,8 @@ const createWindow = async () => { menuBuilder.buildMenu(); // Open urls in the user's browser - mainWindow.webContents.setWindowOpenHandler((edata) => { - shell.openExternal(edata.url); + mainWindow.webContents.setWindowOpenHandler((eData) => { + shell.openExternal(eData.url); return { action: 'deny' }; }); diff --git a/apps/server-web/src/main/preload.ts b/apps/server-web/src/main/preload.ts index a7989b0cb..833df4dbe 100644 --- a/apps/server-web/src/main/preload.ts +++ b/apps/server-web/src/main/preload.ts @@ -23,6 +23,9 @@ const electronHandler = { once(channel: Channels, func: (...args: unknown[]) => void) { ipcRenderer.once(channel, (_event, ...args) => func(...args)); }, + invoke(channel: Channels, ...args: unknown[]) { + return ipcRenderer.invoke(channel, ...args); + }, removeEventListener(channel: Channels) { ipcRenderer.removeAllListeners(channel) } @@ -33,8 +36,14 @@ contextBridge.exposeInMainWorld('electron', electronHandler); contextBridge.exposeInMainWorld('languageChange', { language: (callback: any) => ipcRenderer.on('languageSignal', (_event, value) => callback(value)) }) +contextBridge.exposeInMainWorld('themeChange', { + theme: (callback: any) => ipcRenderer.on('themeSignal', (_event, value) => callback(value)) +}) export type ElectronHandler = typeof electronHandler; export type languageChange = { language: (callback: any) => void } +export type themeChange = { + theme: (callback: any) => void +} diff --git a/apps/server-web/src/renderer/App.css b/apps/server-web/src/renderer/App.css index 654b5a5e5..f6d269756 100644 --- a/apps/server-web/src/renderer/App.css +++ b/apps/server-web/src/renderer/App.css @@ -1,7 +1,339 @@ +@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700;800&family=Poppins:ital,wght@0,300;0,500;0,700;0,800;1,400;1,600&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,700;1,100;1,200;1,300;1,400;1,700&display=swap'); + @tailwind base; @tailwind components; @tailwind utilities; +:root { + --tw-color-dark--theme: #1e2025; + --tooltipBackground: #000; +} + +body { + @apply bg-[#F2F2F2] dark:bg-[#1e2025]; + /* Background changes */ + @apply text-black dark:text-white; + /* Text changes */ +} + +html.dark { + --tooltipBackground: #000; +} + +.font-poppins { + font-family: 'Poppins' !important; +} + +@layer base { + html { + font-family: 'Poppins', sans-serif; + } + + body { + font-style: normal; + font-weight: 300; + font-size: 16px; + line-height: 160%; + overflow: hidden; + @apply text-default dark:text-white; + } + + .x-container { + @apply 3xl:max-w-[1540px] 2xl:max-w-[1320px] xl:max-w-[1140px]; + } + + :root { + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + + --primary: 222.2 47.4% 11.2%; + --primary-foreground: 210 40% 98%; + + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + + --ring: 215 20.2% 65.1%; + + --radius: 0.5rem; + } + + .dark { + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + + --primary: 210 40% 98%; + --primary-foreground: 222.2 47.4% 11.2%; + + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 85.7% 97.3%; + + --ring: 217.2 32.6% 17.5%; + } +} + +@layer components { + + /* Colors custom */ + .bg-gray-lighter { + @apply bg-[#F2F2F2] dark:bg-dark--theme-light; + } + + /* --------------------- Container ------------------------------------ */ + .x-container { + --tblr-gutter-x: 1.5rem; + --tblr-gutter-y: 0; + width: 100%; + padding-right: calc(var(--tblr-gutter-x) * 0.5); + padding-left: calc(var(--tblr-gutter-x) * 0.5); + margin-right: auto; + margin-left: auto; + } + + /* ----------------Fade IN and Fade out */ + + .fade-out { + opacity: 0; + width: 0; + height: 0; + transition: + width 0.5s 0.5s, + height 0.5s 0.5s, + opacity 0.5s; + } + + .fade-in { + opacity: 1; + width: 100%; + height: 100%; + transition: + width 0.2s, + height 0.2s, + opacity 0.2s 0.2s; + } + + /* ------------------- Input ----------------------- */ + .input-border { + @apply border-[#00000021] dark:border-[#3b3c44] border-solid border; + @apply dark:bg-[#1B1D22]; + } + + /* Shadow */ + .nav-items--shadow { + box-shadow: 0px 14px 24px -10px rgba(0, 0, 0, 0.04); + } + + .main--card-border { + @apply border dark:border-[#28292F]; + } + + + .scrollbar-hide::-webkit-scrollbar { + display: none; + } + + .scrollbar-hide { + -ms-overflow-style: none; + /* IE and Edge */ + scrollbar-width: none; + /* Firefox */ + } + + .custom-scrollbar::-webkit-scrollbar { + display: block; + width: 8px; + height: 5px; + @apply dark:bg-[#7b7b7c] bg-gray-400; + } + + .custom-scrollbar:hover::-webkit-scrollbar { + padding: 1px; + } + + .custom-scrollbar::-webkit-scrollbar-thumb { + @apply dark:bg-[#484848] bg-gray-300; + } + + /* Details Aside Bar */ + + .details-label { + @apply not-italic font-medium text-[0.625rem] leading-[140%] tracking-[-0.02em] text-[#A5A2B2] 2xl:text-xs; + } +} + +/* input */ +.search-border { + height: 33px; +} + +.search-border .input-border { + border-width: 0px !important; + height: 40px; +} + +.search-border .input-border input { + height: 40px; +} + +.search-border .input-border input::placeholder { + color: #7e7991; + font-size: 15px !important; + /* font-weight: 500; */ + letter-spacing: 0.8px; +} + +#file-upload input[type='file'] { + display: none; +} + +@font-face { + font-family: 'Plus-Jakarta-Sans-VariableFont_wght'; + src: url('./styles/fonts/PlusJakartaSans-VariableFont_wght.ttf'); +} + +@font-face { + font-family: 'Plus-Jakarta-Sans-Regular'; + src: url('./styles/fonts/PlusJakartaSans-Regular.ttf'); +} + +@font-face { + font-family: 'Plus-Jakarta-Sans-Bold'; + src: url('./styles/fonts/PlusJakartaSans-Bold.ttf'); +} + +@font-face { + font-family: 'Plus-Jakarta-Sans-Light'; + src: url('./styles/fonts/PlusJakartaSans-Light.ttf'); +} + +@font-face { + font-family: 'Plus-Jakarta-Sans-Medium'; + src: url('./styles/fonts/PlusJakartaSans-Medium.ttf'); +} + +@font-face { + font-family: 'Plus-Jakarta-Sans-SemiBold'; + src: url('./styles/fonts/PlusJakartaSans-SemiBold.ttf'); +} + +.search-class { + height: 100%; + width: 100%; + display: flex; + align-items: center; + background: #fcfcfc; + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; +} + +.theme-popup-scrollbar ::-webkit-scrollbar { + display: none; +} + +/* React Date picker */ + +.prose { + max-width: unset !important; +} + + +@keyframes zoom-in-out { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(1.2); + } + + 100% { + transform: scale(1); + } +} + +/* @keyframes pulse { + 0%, + 100% { + opacity: 1; + } + 50% { + opacity: 1; + transform: scale(1.2); + } +} */ + +.progress-ring__circle { + stroke-dasharray: 400, 400; + transition: stroke-dashoffset 0.35s; + transform: rotate(-90deg); + transform-origin: 50% 50%; +} + +@layer utilities { + @layer responsive { + .no-scrollbar::-webkit-scrollbar { + display: block; + } + + .no-scrollbar:hover::-webkit-scrollbar { + display: block; + width: 8px; + height: 5px; + @apply dark:bg-[#606062] bg-gray-300; + } + + .no-scrollbar::-webkit-scrollbar-thumb { + @apply dark:bg-dark--theme-light bg-gray-400; + } + + .no-scrollbar { + -ms-overflow-style: none; + scrollbar-width: none; + } + + .no-scrollbar:hover { + -ms-overflow-style: auto; + scrollbar-width: auto; + } + } +} + + .dropdown:focus-within .dropdown-menu { opacity: 1; transform: translate(0) scale(1); diff --git a/apps/server-web/src/renderer/App.tsx b/apps/server-web/src/renderer/App.tsx index 1718ea52c..3ad4a3986 100644 --- a/apps/server-web/src/renderer/App.tsx +++ b/apps/server-web/src/renderer/App.tsx @@ -4,21 +4,39 @@ import './App.css'; import { Setting } from './pages/Setting'; import i18next from 'i18next'; import { ServerPage } from './pages/Server'; +import { ThemeProvider, useTheme } from './ThemeContext'; export default function App() { const [language, setLanguage] = useState('en'); + const { theme } = useTheme(); + + const setTheme = async (htmlElement: HTMLElement) => { + const currentTheme = await window.electron.ipcRenderer.invoke('current-theme'); + htmlElement.classList.remove('dark', 'light'); + htmlElement.classList.toggle(currentTheme || theme); + } + useEffect(() => { + const htmlElement = document.documentElement; + setTheme(htmlElement); window.languageChange.language((value: any) => { setLanguage(value); }); + window.themeChange.theme((value: any) => { + console.log(value); + htmlElement.classList.remove('dark', 'light'); + htmlElement.classList.toggle(value.data); + }) i18next.changeLanguage(language); }, [language]); return ( - - - } /> - } /> - - + + + + } /> + } /> + + + ); } diff --git a/apps/server-web/src/renderer/ThemeContext.tsx b/apps/server-web/src/renderer/ThemeContext.tsx new file mode 100644 index 000000000..2978201e9 --- /dev/null +++ b/apps/server-web/src/renderer/ThemeContext.tsx @@ -0,0 +1,27 @@ +import React, { createContext, useState, useContext } from 'react'; + +const ThemeContext = createContext({ + theme: 'dark', + toggleTheme: (value: string) => { }, +}); +type ThemeContextType = { + children: React.ReactNode; +} +export const ThemeProvider = ({ children }: ThemeContextType) => { + const [theme, setTheme] = useState('light'); + + const toggleTheme = (value: string) => { + window.electron.ipcRenderer.sendMessage('setting-page', { data: value, type: 'theme-change' }); + setTheme(value); + }; + + return ( + + {children} + + ); +}; + +export const useTheme = () => { + return useContext(ThemeContext); +}; diff --git a/apps/server-web/src/renderer/components/About.tsx b/apps/server-web/src/renderer/components/About.tsx index d95bb3f44..2e8807d71 100644 --- a/apps/server-web/src/renderer/components/About.tsx +++ b/apps/server-web/src/renderer/components/About.tsx @@ -3,12 +3,12 @@ import { IAbout } from '../libs/interfaces'; export const AboutComponent = (props: IAbout) => { return ( -
-
+
+
-

+

V {props.version}

diff --git a/apps/server-web/src/renderer/components/Popup.tsx b/apps/server-web/src/renderer/components/Popup.tsx index 0fdbb9629..b07f4b8e9 100644 --- a/apps/server-web/src/renderer/components/Popup.tsx +++ b/apps/server-web/src/renderer/components/Popup.tsx @@ -19,7 +19,7 @@ export function Popup(props: IPopupComponent) { ​
- -
- -
-
*/} +
+
+ ({ + value: i.code, + label: `LANGUAGES.${i.code}`, + }))} + title={t('FORM.LABELS.LANGUAGES')} + defaultValue={language.code} + onValueChange={(lang) => { + onLangChange({ code: lang }); + }} + disabled={false} + value={language.code} + /> +
+ +
+ +
{children}
diff --git a/apps/server-web/src/renderer/components/Toast.tsx b/apps/server-web/src/renderer/components/Toast.tsx index 11081c7b0..17d96d196 100644 --- a/apps/server-web/src/renderer/components/Toast.tsx +++ b/apps/server-web/src/renderer/components/Toast.tsx @@ -24,7 +24,7 @@ export const ToastComponent = ({ return ( @@ -41,7 +41,7 @@ export const ToastComponent = ({ > diff --git a/apps/server-web/src/renderer/components/Toggler.tsx b/apps/server-web/src/renderer/components/Toggler.tsx new file mode 100644 index 000000000..ae36f7652 --- /dev/null +++ b/apps/server-web/src/renderer/components/Toggler.tsx @@ -0,0 +1,82 @@ +import { useTheme } from '../ThemeContext'; +import clsxm from 'clsx'; +import React, { PropsWithChildren } from 'react'; +import { IClassName } from '../libs/interfaces'; +import { + MoonLightFillIcon as MoonDarkIcon, + MoonLightOutline as MoonIcon, + SunFillIcon as SunIcon, + SunOutline as SunDarkIcon +} from './svgs'; + +type Props = { + className?: string; + onClickOne?: () => void; + onClickTwo?: () => void; + themeTogger?: boolean; + firstBtnClassName?: string; + secondBtnClassName?: string; +} & PropsWithChildren; + +export function Toggler({ + children, + className, + onClickOne, + onClickTwo, + firstBtnClassName, + secondBtnClassName +}: Props) { + const childrenArr = React.Children.toArray(children); + + return ( +
+ + + +
+ ); +} + +export function ThemeToggler({ className }: IClassName) { + const { toggleTheme } = useTheme(); + + return ( + toggleTheme('light')} + onClickTwo={() => toggleTheme('dark')} + > + <> + + + + <> + + + + + ); +} diff --git a/apps/server-web/src/renderer/components/Updater.tsx b/apps/server-web/src/renderer/components/Updater.tsx index ada3401ff..d75435cce 100644 --- a/apps/server-web/src/renderer/components/Updater.tsx +++ b/apps/server-web/src/renderer/components/Updater.tsx @@ -112,7 +112,7 @@ export const UpdaterComponent = (props: IUpdaterComponent) => { {t('FORM.LABELS.AUTO_UPDATE_SUBTITLE')}
-
+
@@ -139,7 +139,7 @@ export const UpdaterComponent = (props: IUpdaterComponent) => { htmlFor="airplane-mode" style={{ paddingLeft: 15 }} > - {t('FORM.LABELS.AUTO_UPDATE_TOGLE')} + {t('FORM.LABELS.AUTO_UPDATE_TOGGLE')}
@@ -172,7 +172,7 @@ export const UpdaterComponent = (props: IUpdaterComponent) => {
-
+
@@ -203,18 +203,18 @@ export const UpdaterComponent = (props: IUpdaterComponent) => {
{updateLogs.length > 0 && - updateLogs.map((ulog, i) => ( + updateLogs.map((uLog, i) => (
- {ulog} + {uLog}
))}
diff --git a/apps/server-web/src/renderer/components/svgs/EverTeamsLogo.tsx b/apps/server-web/src/renderer/components/svgs/EverTeamsLogo.tsx index 239325f44..2a123bf40 100644 --- a/apps/server-web/src/renderer/components/svgs/EverTeamsLogo.tsx +++ b/apps/server-web/src/renderer/components/svgs/EverTeamsLogo.tsx @@ -1,6 +1,6 @@ import Logo from '../../../resources/icons/platform-logo.png'; export const EverTeamsLogo = () => { return ( - EverTeams Logo + EverTeams Logo ); }; diff --git a/apps/server-web/src/renderer/components/svgs/index.ts b/apps/server-web/src/renderer/components/svgs/index.ts index 8d18f2e43..bf45f1f8d 100644 --- a/apps/server-web/src/renderer/components/svgs/index.ts +++ b/apps/server-web/src/renderer/components/svgs/index.ts @@ -1 +1,6 @@ export * from './EverTeamsLogo'; + +export { default as MoonLightFillIcon } from './theme/MoonLightFill'; +export { default as MoonLightOutline } from './theme/MoonLightOutline'; +export { default as SunFillIcon } from './theme/SunFill'; +export { default as SunOutline } from './theme/SunOutline'; diff --git a/apps/server-web/src/renderer/components/svgs/theme/MoonLightFill.tsx b/apps/server-web/src/renderer/components/svgs/theme/MoonLightFill.tsx new file mode 100644 index 000000000..e4ab0ef91 --- /dev/null +++ b/apps/server-web/src/renderer/components/svgs/theme/MoonLightFill.tsx @@ -0,0 +1,18 @@ +import React from 'react'; + +const MoonLightFill = ({ className }: { className?: string }) => ( + + + +); + +export default MoonLightFill; diff --git a/apps/server-web/src/renderer/components/svgs/theme/MoonLightOutline.tsx b/apps/server-web/src/renderer/components/svgs/theme/MoonLightOutline.tsx new file mode 100644 index 000000000..bdfb3f1b2 --- /dev/null +++ b/apps/server-web/src/renderer/components/svgs/theme/MoonLightOutline.tsx @@ -0,0 +1,27 @@ +import React from 'react'; + +interface MoonLightOutlineProps { + className?: string; +} + +const MoonLightOutline: React.FC = ({ className }) => ( + + + + +); + +export default MoonLightOutline; diff --git a/apps/server-web/src/renderer/components/svgs/theme/SunFill.tsx b/apps/server-web/src/renderer/components/svgs/theme/SunFill.tsx new file mode 100644 index 000000000..cfba0189f --- /dev/null +++ b/apps/server-web/src/renderer/components/svgs/theme/SunFill.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +interface SunFillIconProps { + className?: string; +} + +const SunFillIcon: React.FC = ({ className }) => ( + + + + + +); + +export default SunFillIcon; diff --git a/apps/server-web/src/renderer/components/svgs/theme/SunOutline.tsx b/apps/server-web/src/renderer/components/svgs/theme/SunOutline.tsx new file mode 100644 index 000000000..1b73fd665 --- /dev/null +++ b/apps/server-web/src/renderer/components/svgs/theme/SunOutline.tsx @@ -0,0 +1,28 @@ +import React from 'react'; + +interface SunOutlineProps { + className?: string; +} + +const SunOutline: React.FC = ({ className }) => ( + + + + +); + +export default SunOutline; diff --git a/apps/server-web/src/renderer/libs/interfaces/i-components.ts b/apps/server-web/src/renderer/libs/interfaces/i-components.ts index 770bbb72a..6efef4c02 100644 --- a/apps/server-web/src/renderer/libs/interfaces/i-components.ts +++ b/apps/server-web/src/renderer/libs/interfaces/i-components.ts @@ -55,6 +55,12 @@ type ISidebarComponent = { lang: string; }; +export type IClassName = { + className?: string; + fullWidth?: boolean; + type?: 'VERTICAL' | 'HORIZONTAL'; +} & T; + export { IToastComponent, IProgressComponent, diff --git a/apps/server-web/src/renderer/libs/utils/clsxm.ts b/apps/server-web/src/renderer/libs/utils/clsxm.ts new file mode 100644 index 000000000..d1de3c6bd --- /dev/null +++ b/apps/server-web/src/renderer/libs/utils/clsxm.ts @@ -0,0 +1,7 @@ +import clsx, { ClassValue } from 'clsx'; +import { twMerge } from 'tailwind-merge'; + +/** Merge classes with tailwind-merge with clsx full feature */ +export function clsxm(...classes: ClassValue[]) { + return twMerge(clsx(...classes)); +} diff --git a/apps/server-web/src/renderer/pages/Server.tsx b/apps/server-web/src/renderer/pages/Server.tsx index ca5e83d43..ab018e213 100644 --- a/apps/server-web/src/renderer/pages/Server.tsx +++ b/apps/server-web/src/renderer/pages/Server.tsx @@ -42,20 +42,20 @@ export function ServerPage() { }; return ( -
-
+
+
-
+
@@ -77,7 +77,7 @@ export function ServerPage() {