fix: remove medium theme, fix navbar re-render, fix Node.js env loading

- Remove 'medium' theme from dashboard and marketplace; keep only light/dark
- Marketplace: move public pages into (public)/ route group so header/footer
  persist across navigations without re-rendering (eliminates usePathname)
- MarketplaceShell is now a pure context provider; chrome lives in
  (public)/layout.tsx which Next.js holds stable across navigations
- WorkspaceFrame: remove history.replaceState and standalone-route logic
- Docker API: bypass npm run dev to avoid node --env-file in containers
- Add scripts/run-with-env-file.cjs for Node.js < 20.6 compatibility;
  update apps/api/package.json dev script to use it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
root
2026-05-23 02:41:02 -04:00
parent 8f93bb89f6
commit dcd62f35ac
26 changed files with 161 additions and 125 deletions
@@ -5,7 +5,7 @@ import { SHARED_LANGUAGE_COOKIE, SHARED_LANGUAGE_KEY, SHARED_THEME_KEY, readCurr
import { apiFetch } from '@/lib/api'
export type DashboardLanguage = 'en' | 'fr' | 'ar'
export type DashboardTheme = 'light' | 'medium' | 'dark'
export type DashboardTheme = 'light' | 'dark'
type FleetDict = {
statusLabels: Record<'AVAILABLE' | 'RENTED' | 'MAINTENANCE' | 'OUT_OF_SERVICE', string>
@@ -297,7 +297,6 @@ type DashboardDictionary = {
language: string
theme: string
light: string
medium: string
dark: string
fleet: FleetDict
vehicleDetail: VehicleDetailDict
@@ -348,7 +347,6 @@ const dictionaries: Record<DashboardLanguage, DashboardDictionary> = {
language: 'Language',
theme: 'Theme',
light: 'Light',
medium: 'Medium',
dark: 'Dark',
fleet: {
statusLabels: { AVAILABLE: 'Available', RENTED: 'Rented', MAINTENANCE: 'Maintenance', OUT_OF_SERVICE: 'Out of Service' },
@@ -692,7 +690,6 @@ const dictionaries: Record<DashboardLanguage, DashboardDictionary> = {
language: 'Langue',
theme: 'Mode',
light: 'Clair',
medium: 'Moyen',
dark: 'Sombre',
fleet: {
statusLabels: { AVAILABLE: 'Disponible', RENTED: 'Loué', MAINTENANCE: 'Maintenance', OUT_OF_SERVICE: 'Hors service' },
@@ -1036,7 +1033,6 @@ const dictionaries: Record<DashboardLanguage, DashboardDictionary> = {
language: 'اللغة',
theme: 'الوضع',
light: 'فاتح',
medium: 'متوسط',
dark: 'داكن',
fleet: {
statusLabels: { AVAILABLE: 'متاح', RENTED: 'مؤجر', MAINTENANCE: 'صيانة', OUT_OF_SERVICE: 'خارج الخدمة' },
@@ -1421,7 +1417,7 @@ export function DashboardI18nProvider({
useEffect(() => {
const storedTheme = readScopedPreference(SHARED_THEME_KEY, ['dashboard-theme'])
if (storedTheme === 'light' || storedTheme === 'medium' || storedTheme === 'dark') {
if (storedTheme === 'light' || storedTheme === 'dark') {
if (storedTheme !== theme) setThemeState(storedTheme)
return
}
@@ -1474,7 +1470,7 @@ export function DashboardI18nProvider({
writeScopedPreference(SHARED_LANGUAGE_KEY, langToWrite, [DASHBOARD_LANGUAGE_KEY])
}
if (scopedTheme === 'light' || scopedTheme === 'medium' || scopedTheme === 'dark') {
if (scopedTheme === 'light' || scopedTheme === 'dark') {
if (scopedTheme !== theme) setThemeState(scopedTheme)
} else {
writeScopedPreference(SHARED_THEME_KEY, theme, ['dashboard-theme'])
@@ -1557,7 +1553,7 @@ export function DashboardThemeSwitcher() {
<span className="px-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-slate-500 dark:text-slate-400">
{dict.theme}
</span>
{(['light', 'medium', 'dark'] as DashboardTheme[]).map((value) => {
{(['light', 'dark'] as DashboardTheme[]).map((value) => {
const active = value === theme
return (
<button
@@ -1570,7 +1566,7 @@ export function DashboardThemeSwitcher() {
: 'text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-800'
}`}
>
{value === 'light' ? dict.light : value === 'medium' ? dict.medium : dict.dark}
{value === 'light' ? dict.light : dict.dark}
</button>
)
})}