-
+
Enter the URL of the map region file you wish to download. The URL must be publicly
reachable and end with .pmtiles. A preflight check will be run to verify the file's
availability, type, and approximate size.
@@ -76,11 +76,11 @@ const DownloadURLModal: React.FC = ({
value={url}
onChange={(e) => setUrl(e.target.value)}
/>
-
+
{messages.map((message, idx) => (
{message}
diff --git a/admin/inertia/components/Footer.tsx b/admin/inertia/components/Footer.tsx
index 78765f7..8c991db 100644
--- a/admin/inertia/components/Footer.tsx
+++ b/admin/inertia/components/Footer.tsx
@@ -1,14 +1,16 @@
import { usePage } from '@inertiajs/react'
import { UsePageProps } from '../../types/system'
+import ThemeToggle from '~/components/ThemeToggle'
export default function Footer() {
const { appVersion } = usePage().props as unknown as UsePageProps
return (
-
-
-
+
)
diff --git a/admin/inertia/components/HorizontalBarChart.tsx b/admin/inertia/components/HorizontalBarChart.tsx
index 7c90a36..b9375fb 100644
--- a/admin/inertia/components/HorizontalBarChart.tsx
+++ b/admin/inertia/components/HorizontalBarChart.tsx
@@ -94,7 +94,7 @@ export default function HorizontalBarChart({
className={classNames(
'absolute top-1/2 -translate-y-1/2 font-bold text-sm',
item.value > 15
- ? 'left-3 text-desert-white drop-shadow-md'
+ ? 'left-3 text-white drop-shadow-md'
: 'right-3 text-desert-green'
)}
>
diff --git a/admin/inertia/components/InstallActivityFeed.tsx b/admin/inertia/components/InstallActivityFeed.tsx
index 135eb54..b14381f 100644
--- a/admin/inertia/components/InstallActivityFeed.tsx
+++ b/admin/inertia/components/InstallActivityFeed.tsx
@@ -31,8 +31,8 @@ export type InstallActivityFeedProps = {
const InstallActivityFeed: React.FC = ({ activity, className, withHeader = false }) => {
return (
-
- {withHeader &&
Installation Activity }
+
+ {withHeader &&
Installation Activity }
{activity.map((activityItem, activityItemIdx) => (
@@ -42,7 +42,7 @@ const InstallActivityFeed: React.FC = ({ activity, cla
'absolute left-0 top-0 flex w-6 justify-center'
)}
>
-
+
<>
@@ -51,16 +51,16 @@ const InstallActivityFeed: React.FC
= ({ activity, cla
) : activityItem.type === 'update-rollback' ? (
) : (
-
+
)}
-
- {activityItem.service_name} -{' '}
+
+ {activityItem.service_name} -{' '}
{activityItem.type.charAt(0).toUpperCase() + activityItem.type.slice(1)}
{activityItem.timestamp}
diff --git a/admin/inertia/components/LoadingSpinner.tsx b/admin/inertia/components/LoadingSpinner.tsx
index 0569cf2..2d81a85 100644
--- a/admin/inertia/components/LoadingSpinner.tsx
+++ b/admin/inertia/components/LoadingSpinner.tsx
@@ -17,10 +17,10 @@ const LoadingSpinner: React.FC
= ({
return (
{!iconOnly && (
-
+
{text || 'Loading...'}
)}
diff --git a/admin/inertia/components/ProgressBar.tsx b/admin/inertia/components/ProgressBar.tsx
index b247d4f..e6733de 100644
--- a/admin/inertia/components/ProgressBar.tsx
+++ b/admin/inertia/components/ProgressBar.tsx
@@ -9,14 +9,14 @@ const ProgressBar = ({ progress, speed }: { progress: number; speed?: string })
return (
-
+
{speed && (
-
+
Est. Speed: {speed}
)}
diff --git a/admin/inertia/components/StorageProjectionBar.tsx b/admin/inertia/components/StorageProjectionBar.tsx
index 36bb214..953992d 100644
--- a/admin/inertia/components/StorageProjectionBar.tsx
+++ b/admin/inertia/components/StorageProjectionBar.tsx
@@ -81,7 +81,7 @@ export default function StorageProjectionBar({
className={classNames(
'absolute top-1/2 -translate-y-1/2 font-bold text-sm',
projectedTotalPercent > 15
- ? 'left-3 text-desert-white drop-shadow-md'
+ ? 'left-3 text-white drop-shadow-md'
: 'right-3 text-desert-green'
)}
>
diff --git a/admin/inertia/components/StyledButton.tsx b/admin/inertia/components/StyledButton.tsx
index 5cc0387..27dfc2e 100644
--- a/admin/inertia/components/StyledButton.tsx
+++ b/admin/inertia/components/StyledButton.tsx
@@ -56,9 +56,9 @@ const StyledButton: React.FC
= ({
switch (variant) {
case 'primary':
return clsx(
- 'bg-desert-green text-desert-white',
- 'hover:bg-desert-green-dark hover:shadow-lg',
- 'active:bg-desert-green-darker',
+ 'bg-desert-green text-white',
+ 'hover:bg-btn-green-hover hover:shadow-lg',
+ 'active:bg-btn-green-active',
'disabled:bg-desert-green-light disabled:text-desert-stone-light',
baseTransition,
baseHover
@@ -66,7 +66,7 @@ const StyledButton: React.FC = ({
case 'secondary':
return clsx(
- 'bg-desert-tan text-desert-white',
+ 'bg-desert-tan text-white',
'hover:bg-desert-tan-dark hover:shadow-lg',
'active:bg-desert-tan-dark',
'disabled:bg-desert-tan-lighter disabled:text-desert-stone-light',
@@ -76,7 +76,7 @@ const StyledButton: React.FC = ({
case 'danger':
return clsx(
- 'bg-desert-red text-desert-white',
+ 'bg-desert-red text-white',
'hover:bg-desert-red-dark hover:shadow-lg',
'active:bg-desert-red-dark',
'disabled:bg-desert-red-lighter disabled:text-desert-stone-light',
@@ -86,7 +86,7 @@ const StyledButton: React.FC = ({
case 'action':
return clsx(
- 'bg-desert-orange text-desert-white',
+ 'bg-desert-orange text-white',
'hover:bg-desert-orange-light hover:shadow-lg',
'active:bg-desert-orange-dark',
'disabled:bg-desert-orange-lighter disabled:text-desert-stone-light',
@@ -96,7 +96,7 @@ const StyledButton: React.FC = ({
case 'success':
return clsx(
- 'bg-desert-olive text-desert-white',
+ 'bg-desert-olive text-white',
'hover:bg-desert-olive-dark hover:shadow-lg',
'active:bg-desert-olive-dark',
'disabled:bg-desert-olive-lighter disabled:text-desert-stone-light',
@@ -116,8 +116,8 @@ const StyledButton: React.FC = ({
case 'outline':
return clsx(
'bg-transparent border-2 border-desert-green text-desert-green',
- 'hover:bg-desert-green hover:text-desert-white hover:border-desert-green-dark',
- 'active:bg-desert-green-dark active:border-desert-green-darker',
+ 'hover:bg-desert-green hover:text-white hover:border-btn-green-hover',
+ 'active:bg-btn-green-hover active:border-btn-green-active',
'disabled:border-desert-green-lighter disabled:text-desert-stone-light',
baseTransition,
baseHover
diff --git a/admin/inertia/components/StyledModal.tsx b/admin/inertia/components/StyledModal.tsx
index fed08c1..0e0d784 100644
--- a/admin/inertia/components/StyledModal.tsx
+++ b/admin/inertia/components/StyledModal.tsx
@@ -48,7 +48,7 @@ const StyledModal: React.FC = ({
>
= ({
{icon &&
{icon}
}
-
+
{title}
{children}
diff --git a/admin/inertia/components/StyledSidebar.tsx b/admin/inertia/components/StyledSidebar.tsx
index 149ef56..ee056dc 100644
--- a/admin/inertia/components/StyledSidebar.tsx
+++ b/admin/inertia/components/StyledSidebar.tsx
@@ -5,6 +5,7 @@ import { IconArrowLeft } from '@tabler/icons-react'
import { usePage } from '@inertiajs/react'
import { UsePageProps } from '../../types/system'
import { IconMenu2, IconX } from '@tabler/icons-react'
+import ThemeToggle from '~/components/ThemeToggle'
type SidebarItem = {
name: string
@@ -37,7 +38,7 @@ const StyledSidebar: React.FC = ({ title, items }) => {
className={classNames(
item.current
? 'bg-desert-green text-white'
- : 'text-black hover:bg-desert-green-light hover:text-white',
+ : 'text-text-primary hover:bg-desert-green-light hover:text-white',
'group flex gap-x-3 rounded-md p-2 text-sm/6 font-semibold'
)}
>
@@ -53,7 +54,7 @@ const StyledSidebar: React.FC = ({ title, items }) => {
-
{title}
+
{title}
@@ -75,8 +76,9 @@ const StyledSidebar: React.FC = ({ title, items }) => {
-
+
Project N.O.M.A.D. Command Center v{appVersion}
+
)
diff --git a/admin/inertia/components/StyledTable.tsx b/admin/inertia/components/StyledTable.tsx
index 4dd3572..4cd7d5c 100644
--- a/admin/inertia/components/StyledTable.tsx
+++ b/admin/inertia/components/StyledTable.tsx
@@ -74,19 +74,19 @@ function StyledTable
({
return (
-
+
{expandable && (
@@ -95,7 +95,7 @@ function StyledTable({
@@ -121,8 +121,8 @@ function StyledTable({
'translateY' in record ? 'translateY(' + record.transformY + 'px)' : undefined,
}}
className={classNames(
- rowLines ? 'border-b border-gray-200' : '',
- onRowClick ? `cursor-pointer hover:bg-gray-100 ` : ''
+ rowLines ? 'border-b border-border-subtle' : '',
+ onRowClick ? `cursor-pointer hover:bg-surface-secondary ` : ''
)}
>
{expandable && (
@@ -134,7 +134,7 @@ function StyledTable({
onClick={(e) => toggleRowExpansion(record, recordIdx, e)}
>
({
))}
{expandable && isExpanded && (
-
+
{expandable.expandedRowRender(record, recordIdx)}
@@ -183,7 +183,7 @@ function StyledTable({
})}
{!loading && data.length === 0 && (
-
+
{noDataText}
diff --git a/admin/inertia/components/ThemeToggle.tsx b/admin/inertia/components/ThemeToggle.tsx
new file mode 100644
index 0000000..abd9109
--- /dev/null
+++ b/admin/inertia/components/ThemeToggle.tsx
@@ -0,0 +1,24 @@
+import { IconSun, IconMoon } from '@tabler/icons-react'
+import { useThemeContext } from '~/providers/ThemeProvider'
+
+interface ThemeToggleProps {
+ compact?: boolean
+}
+
+export default function ThemeToggle({ compact = false }: ThemeToggleProps) {
+ const { theme, toggleTheme } = useThemeContext()
+ const isDark = theme === 'dark'
+
+ return (
+
+ {isDark ? : }
+ {!compact && {isDark ? 'Day Ops' : 'Night Ops'} }
+
+ )
+}
diff --git a/admin/inertia/components/TierSelectionModal.tsx b/admin/inertia/components/TierSelectionModal.tsx
index a98cf67..ed44eee 100644
--- a/admin/inertia/components/TierSelectionModal.tsx
+++ b/admin/inertia/components/TierSelectionModal.tsx
@@ -88,7 +88,7 @@ const TierSelectionModal: React.FC = ({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
-
+
{/* Header */}
@@ -101,7 +101,7 @@ const TierSelectionModal: React.FC
= ({
{category.name}
- {category.description}
+ {category.description}
= ({
{/* Content */}
-
+
Select a tier based on your storage capacity and needs. Higher tiers include all content from lower tiers.
@@ -138,30 +138,30 @@ const TierSelectionModal: React.FC
= ({
'border-2 rounded-lg p-5 cursor-pointer transition-all',
isSelected
? 'border-desert-green bg-desert-green/5 shadow-md'
- : 'border-gray-200 hover:border-desert-green/50 hover:shadow-sm'
+ : 'border-border-subtle hover:border-desert-green/50 hover:shadow-sm'
)}
>
-
+
{tier.name}
{includedTierName && (
-
+
(includes {includedTierName})
)}
-
{tier.description}
+
{tier.description}
{/* Resources preview - only show this tier's own resources */}
-
-
+
+
{includedTierName ? (
<>
{ownResourceCount} additional {ownResourceCount === 1 ? 'resource' : 'resources'}
- (plus everything in {includedTierName})
+ (plus everything in {includedTierName})
>
) : (
<>{ownResourceCount} {ownResourceCount === 1 ? 'resource' : 'resources'} included>
@@ -172,8 +172,8 @@ const TierSelectionModal: React.FC = ({
- {resource.title}
-
+ {resource.title}
+
({formatBytes(resource.size_mb * 1024 * 1024, 0)})
@@ -184,14 +184,14 @@ const TierSelectionModal: React.FC
= ({
-
+
{formatBytes(totalSize, 1)}
{isSelected && }
@@ -203,7 +203,7 @@ const TierSelectionModal: React.FC
= ({
{/* Info note */}
-
+
You can change your selection at any time. Click Submit to confirm your choice.
@@ -212,7 +212,7 @@ const TierSelectionModal: React.FC = ({
{/* Footer */}
-
+
= ({
'px-4 py-2 rounded-md font-medium transition-colors',
localSelectedSlug
? 'bg-desert-green text-white hover:bg-desert-green/90'
- : 'bg-gray-300 text-gray-500 cursor-not-allowed'
+ : 'bg-border-default text-text-muted cursor-not-allowed'
)}
>
Submit
diff --git a/admin/inertia/components/UpdateServiceModal.tsx b/admin/inertia/components/UpdateServiceModal.tsx
index d897a56..e0e1b55 100644
--- a/admin/inertia/components/UpdateServiceModal.tsx
+++ b/admin/inertia/components/UpdateServiceModal.tsx
@@ -60,12 +60,12 @@ export default function UpdateServiceModal({
icon={ }
>
-
+
Update {record.friendly_name || record.service_name} from{' '}
- {currentTag} to{' '}
- {selectedVersion}?
+ {currentTag} to{' '}
+ {selectedVersion}?
-
+
Your data and configuration will be preserved during the update.
{versions.find((v) => v.tag === selectedVersion)?.releaseUrl && (
<>
@@ -95,14 +95,14 @@ export default function UpdateServiceModal({
<>
{loadingVersions ? (
-
Loading versions...
+
Loading versions...
) : versions.length === 0 ? (
-
No other versions available
+
No other versions available
) : (
versions.map((v) => (
setSelectedVersion(v.tag)}
className="text-desert-green focus:ring-desert-green"
/>
- {v.tag}
+ {v.tag}
{v.isLatest && (
Latest
@@ -133,7 +133,7 @@ export default function UpdateServiceModal({
))
)}
-
+
It's not recommended to upgrade to a new major version (e.g. 1.8.2 → 2.0.0) unless you have verified compatibility with your current configuration. Always review the release notes and test in a staging environment if possible.
>
diff --git a/admin/inertia/components/WikipediaSelector.tsx b/admin/inertia/components/WikipediaSelector.tsx
index e5367f1..8e29dd6 100644
--- a/admin/inertia/components/WikipediaSelector.tsx
+++ b/admin/inertia/components/WikipediaSelector.tsx
@@ -37,11 +37,11 @@ const WikipediaSelector: React.FC
= ({
{/* Header with Wikipedia branding */}
-
+
-
Wikipedia
-
Select your preferred Wikipedia package
+
Wikipedia
+
Select your preferred Wikipedia package
@@ -78,7 +78,7 @@ const WikipediaSelector: React.FC = ({
? 'border-desert-green bg-desert-green/10'
: isSelected
? 'border-lime-500 bg-lime-50'
- : 'border-gray-200 bg-white hover:border-gray-300'
+ : 'border-border-subtle bg-surface-primary hover:border-border-default'
)}
>
{/* Status badges */}
@@ -104,8 +104,8 @@ const WikipediaSelector: React.FC = ({
{/* Option content */}
-
{option.name}
-
{option.description}
+
{option.name}
+
{option.description}
{/* Radio indicator */}
= ({
? isInstalled
? 'border-desert-green bg-desert-green'
: 'border-lime-500 bg-lime-500'
- : 'border-gray-300'
+ : 'border-border-default'
)}
>
{isSelected &&
}
@@ -123,7 +123,7 @@ const WikipediaSelector: React.FC
= ({
{option.size_mb === 0 ? 'No download' : formatBytes(option.size_mb * 1024 * 1024, 1)}
diff --git a/admin/inertia/components/chat/ChatInterface.tsx b/admin/inertia/components/chat/ChatInterface.tsx
index 75d4168..ffdd017 100644
--- a/admin/inertia/components/chat/ChatInterface.tsx
+++ b/admin/inertia/components/chat/ChatInterface.tsx
@@ -85,19 +85,19 @@ export default function ChatInterface({
}
return (
-
+
{messages.length === 0 ? (
-
Start a conversation
-
+
Start a conversation
+
Interact with your installed language models directly in the Command Center.
{chatSuggestionsEnabled && chatSuggestions && chatSuggestions.length > 0 && !chatSuggestionsLoading && (
-
Suggestions:
+
Suggestions:
{chatSuggestions.map((suggestion, index) => (
{suggestion}
@@ -120,7 +120,7 @@ export default function ChatInterface({
{/* Display bouncing dots while loading suggestions */}
{chatSuggestionsEnabled && chatSuggestionsLoading &&
}
{!chatSuggestionsEnabled && (
-
+
Need some inspiration? Enable chat suggestions in settings to get started with example prompts.
)}
@@ -144,7 +144,7 @@ export default function ChatInterface({
{isLoading && (
-
@@ -154,7 +154,7 @@ export default function ChatInterface({
>
)}
-