FEATURE (navbar): Update navbar style

This commit is contained in:
Rostislav Dugin
2026-01-20 08:25:58 +03:00
parent 1afb3aa3ff
commit 0952a15ec5
13 changed files with 118 additions and 94 deletions

View File

@@ -14,7 +14,6 @@
"dayjs": "^1.11.13",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-github-btn": "^1.4.0",
"react-router": "^7.6.0",
"recharts": "^3.2.0",
"tailwindcss": "^4.1.7"
@@ -4272,12 +4271,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/github-buttons": {
"version": "2.29.1",
"resolved": "https://registry.npmjs.org/github-buttons/-/github-buttons-2.29.1.tgz",
"integrity": "sha512-TV3YgAKda5hPz75n7QXmGCsSzgVya1vvmBieebg3EB5ScmashTZ0FldViG1aU2d4V5rcAGrtQ7k5uAaCo0A4PA==",
"license": "BSD-2-Clause"
},
"node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
@@ -6759,18 +6752,6 @@
"react": "^19.1.0"
}
},
"node_modules/react-github-btn": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/react-github-btn/-/react-github-btn-1.4.0.tgz",
"integrity": "sha512-lV4FYClAfjWnBfv0iNlJUGhamDgIq6TayD0kPZED6VzHWdpcHmPfsYOZ/CFwLfPv4Zp+F4m8QKTj0oy2HjiGXg==",
"license": "BSD-2-Clause",
"dependencies": {
"github-buttons": "^2.22.0"
},
"peerDependencies": {
"react": ">=16.3.0"
}
},
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",

View File

@@ -19,7 +19,6 @@
"dayjs": "^1.11.13",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-github-btn": "^1.4.0",
"react-router": "^7.6.0",
"recharts": "^3.2.0",
"tailwindcss": "^4.1.7"

View File

@@ -91,7 +91,7 @@ export function SettingsComponent({ contentHeight }: Props) {
console.log(`isCloud = ${IS_CLOUD}`);
return (
<div className="flex grow sm:pl-5">
<div className="flex grow">
<div className="w-full">
<div
ref={scrollContainerRef}

View File

@@ -1,6 +1,5 @@
import GitHubButton from 'react-github-btn';
import { ThemeToggleComponent } from '../../../widgets/main/ThemeToggleComponent';
import { StarButtonComponent } from '../../../shared/ui/StarButtonComponent';
import { ThemeToggleComponent } from '../../../shared/ui/ThemeToggleComponent';
export function AuthNavbarComponent() {
return (
@@ -32,19 +31,11 @@ export function AuthNavbarComponent() {
Community
</a>
<div className="mt-[7px]">
<GitHubButton
href="https://github.com/databasus/databasus"
data-icon="octicon-star"
data-size="large"
data-show-count="true"
aria-label="Star Databasus on GitHub"
>
&nbsp;Star on GitHub
</GitHubButton>
</div>
<div className="flex items-center gap-2">
<StarButtonComponent />
<ThemeToggleComponent />
<ThemeToggleComponent />
</div>
</div>
</div>
);

View File

@@ -197,7 +197,7 @@ export function ProfileComponent({ contentHeight }: Props) {
};
return (
<div className="flex grow sm:pl-5">
<div className="flex grow">
<div className="w-full">
<div
className="grow overflow-y-auto rounded bg-white p-5 shadow dark:bg-gray-800"

View File

@@ -366,7 +366,7 @@ export function UsersComponent({ contentHeight }: Props) {
};
return (
<div className="flex grow sm:pl-5">
<div className="flex grow">
<div className="w-full">
<div
ref={scrollContainerRef}

View File

@@ -165,7 +165,7 @@ export function WorkspaceSettingsComponent({ workspaceResponse, user, contentHei
};
return (
<div className="flex grow sm:pl-2">
<div className="flex grow">
<div className="w-full">
<div
ref={scrollContainerRef}

View File

@@ -0,0 +1,61 @@
import { useEffect, useState } from 'react';
const StarIcon = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" />
</svg>
);
export function StarButtonComponent() {
const [starCount, setStarCount] = useState<number | null>(null);
const [isLoading, setIsLoading] = useState(true);
const fetchStarCount = async () => {
try {
const response = await fetch('https://api.github.com/repos/databasus/databasus');
if (response.ok) {
const data = (await response.json()) as { stargazers_count: number };
setStarCount(data.stargazers_count);
}
} catch (error) {
console.error('Failed to fetch GitHub star count:', error);
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchStarCount();
}, []);
return (
<a
href="https://github.com/databasus/databasus"
target="_blank"
rel="noopener noreferrer"
className="flex cursor-pointer items-center rounded-md border !border-gray-200 !bg-white text-sm !text-gray-700 transition-colors hover:!bg-gray-50 dark:!border-gray-600 dark:!bg-gray-700 dark:!text-gray-200 dark:hover:!bg-gray-600"
aria-label="Star databasus/databasus on GitHub"
>
<div className="flex items-center gap-2 border-r border-gray-200 px-2.5 py-1 !text-black dark:border-gray-600 dark:!text-white">
<StarIcon />
<span>Star on GitHub</span>
</div>
{!isLoading && starCount !== null && (
<span className="px-2.5 py-1 !text-black dark:!text-white">
{starCount.toLocaleString()}
</span>
)}
</a>
);
}

View File

@@ -1,7 +1,7 @@
import { Dropdown } from 'antd';
import type { MenuProps } from 'antd';
import { type ThemeMode, useTheme } from '../../shared/theme';
import { type ThemeMode, useTheme } from '../theme';
const SunIcon = () => (
<svg

View File

@@ -1 +1,3 @@
export { ConfirmationComponent } from './ConfirmationComponent';
export { StarButtonComponent } from './StarButtonComponent';
export { ThemeToggleComponent } from './ThemeToggleComponent';

View File

@@ -1,7 +1,6 @@
import { LoadingOutlined, MenuOutlined } from '@ant-design/icons';
import { App, Button, Spin, Tooltip } from 'antd';
import { useEffect, useState } from 'react';
import GitHubButton from 'react-github-btn';
import { APP_VERSION } from '../../constants';
import { type DiskUsage, diskApi } from '../../entity/disk';
@@ -24,14 +23,13 @@ import {
WorkspaceSettingsComponent,
} from '../../features/workspaces';
import { useIsMobile, useScreenHeight } from '../../shared/hooks';
import { useTheme } from '../../shared/theme';
import { StarButtonComponent } from '../../shared/ui/StarButtonComponent';
import { ThemeToggleComponent } from '../../shared/ui/ThemeToggleComponent';
import { SidebarComponent } from './SidebarComponent';
import { ThemeToggleComponent } from './ThemeToggleComponent';
import { WorkspaceSelectionComponent } from './WorkspaceSelectionComponent';
export const MainScreenComponent = () => {
const { message } = App.useApp();
const { resolvedTheme } = useTheme();
const screenHeight = useScreenHeight();
const isMobile = useIsMobile();
const contentHeight = screenHeight - (isMobile ? 70 : 95);
@@ -115,6 +113,9 @@ export const MainScreenComponent = () => {
const isUsedMoreThan95Percent =
diskUsage && diskUsage.usedSpaceBytes / diskUsage.totalSpaceBytes > 0.95;
const isUsedMoreThan85Percent =
diskUsage && diskUsage.usedSpaceBytes / diskUsage.totalSpaceBytes > 0.85;
const isCanManageDBs = selectedWorkspace?.userRole !== WorkspaceRole.VIEWER;
const tabs = [
@@ -199,7 +200,7 @@ export const MainScreenComponent = () => {
</a>
</div>
<div className="ml-2 flex-1 pr-2 md:ml-5 md:flex-initial md:pr-0">
<div className="ml-2 flex-1 pr-2 md:ml-4 md:flex-initial md:pr-0">
{!isLoading && (
<WorkspaceSelectionComponent
workspaces={workspaces}
@@ -220,14 +221,6 @@ export const MainScreenComponent = () => {
Docs
</a>
<a
className="!text-black hover:opacity-80 dark:!text-gray-200"
href="https://databasus.com/contribute"
target="_blank"
rel="noreferrer"
>
Contribute
</a>
<a
className="!text-black hover:opacity-80 dark:!text-gray-200"
href="https://t.me/databasus_community"
@@ -237,20 +230,7 @@ export const MainScreenComponent = () => {
Community
</a>
<div className="mt-1">
<GitHubButton
href="https://github.com/databasus/databasus"
data-color-scheme={resolvedTheme}
data-icon="octicon-star"
data-size="large"
data-show-count="true"
aria-label="Star databasus/databasus on GitHub"
>
&nbsp;Star Databasus on GitHub
</GitHubButton>
</div>
{diskUsage && (
{isUsedMoreThan85Percent && (
<Tooltip title="To make backups locally and restore them, you need to have enough space on your disk. For restore, you need to have same amount of space that the backup size.">
<div
className={`cursor-pointer text-center text-xs ${isUsedMoreThan95Percent ? 'text-red-500' : 'text-gray-500 dark:text-gray-400'}`}
@@ -264,7 +244,11 @@ export const MainScreenComponent = () => {
</Tooltip>
)}
<ThemeToggleComponent />
<div className="flex items-center gap-2">
<StarButtonComponent />
<ThemeToggleComponent />
</div>
</div>
<div className="ml-auto flex items-center gap-2 md:hidden">
@@ -276,6 +260,7 @@ export const MainScreenComponent = () => {
/>
</div>
</div>
{isLoading ? (
<div className="flex items-center justify-center py-2" style={{ height: contentHeight }}>
<Spin indicator={<LoadingOutlined spin />} size="large" />
@@ -292,13 +277,23 @@ export const MainScreenComponent = () => {
contentHeight={contentHeight}
/>
{selectedTab === 'profile' && <ProfileComponent contentHeight={contentHeight} />}
{selectedTab === 'databasus-settings' && (
<SettingsComponent contentHeight={contentHeight} />
{selectedTab === 'profile' && (
<div className="flex-1 md:pl-4">
<ProfileComponent contentHeight={contentHeight} />
</div>
)}
{selectedTab === 'users' && <UsersComponent contentHeight={contentHeight} />}
{selectedTab === 'databasus-settings' && (
<div className="flex-1 md:pl-4">
<SettingsComponent contentHeight={contentHeight} />
</div>
)}
{selectedTab === 'users' && (
<div className="flex-1 md:pl-4">
<UsersComponent contentHeight={contentHeight} />
</div>
)}
{(selectedTab === 'databases' ||
selectedTab === 'storages' ||
@@ -323,7 +318,7 @@ export const MainScreenComponent = () => {
</div>
) : (
<>
<div className="flex-1 md:pl-3">
<div className="flex-1 md:pl-1">
{selectedTab === 'notifiers' && selectedWorkspace && (
<NotifiersComponent
contentHeight={contentHeight}
@@ -348,14 +343,17 @@ export const MainScreenComponent = () => {
key={`databases-${selectedWorkspace.id}`}
/>
)}
{selectedTab === 'settings' && selectedWorkspace && user && (
<WorkspaceSettingsComponent
workspaceResponse={selectedWorkspace}
contentHeight={contentHeight}
user={user}
key={`settings-${selectedWorkspace.id}`}
/>
)}
<div className="flex-1 md:pl-3">
{selectedTab === 'settings' && selectedWorkspace && user && (
<WorkspaceSettingsComponent
workspaceResponse={selectedWorkspace}
contentHeight={contentHeight}
user={user}
key={`settings-${selectedWorkspace.id}`}
/>
)}
</div>
</div>
</>
)}

View File

@@ -1,13 +1,13 @@
import { CloseOutlined } from '@ant-design/icons';
import { Drawer, Tooltip } from 'antd';
import { useEffect } from 'react';
import GitHubButton from 'react-github-btn';
import { type DiskUsage } from '../../entity/disk';
import { type UserProfile, UserRole } from '../../entity/users';
import { useIsMobile } from '../../shared/hooks';
import { useTheme } from '../../shared/theme';
import { ThemeToggleComponent } from './ThemeToggleComponent';
import { StarButtonComponent } from '../../shared/ui/StarButtonComponent';
import { ThemeToggleComponent } from '../../shared/ui/ThemeToggleComponent';
interface TabItem {
text: string;
@@ -213,15 +213,7 @@ export const SidebarComponent = ({
</a>
<div className="pt-2">
<GitHubButton
href="https://github.com/databasus/databasus"
data-icon="octicon-star"
data-size="large"
data-show-count="true"
aria-label="Star databasus/databasus on GitHub"
>
Star on GitHub
</GitHubButton>
<StarButtonComponent text="Star on GitHub" size="large" showCount />
</div>
</div>
</div>

View File

@@ -62,7 +62,7 @@ export const WorkspaceSelectionComponent = ({
return (
<div
className="my-1 flex-1 select-none md:ml-2 md:w-[250px] md:max-w-[250px]"
className="my-1 flex-1 select-none md:ml-2 md:w-[250px] md:max-w-[242px]"
ref={dropdownRef}
>
<div className="mb-1 hidden text-xs text-gray-400 md:block" style={{ lineHeight: 0.7 }}>