Dev 1.3.1 #114

Merged
LukeGus merged 38 commits from dev-1.3.1 into main 2025-08-28 06:00:48 +00:00
4 changed files with 78 additions and 91 deletions
Showing only changes of commit b046aedcee - Show all commits
+11 -23
View File
@@ -90,32 +90,20 @@ function AppContent() {
return ( return (
<div> <div>
{!isAuthenticated && !authLoading && ( {!isAuthenticated && !authLoading && (
<div <div>
className="fixed inset-0 bg-gradient-to-br from-background via-muted/20 to-background z-[9999]"
aria-hidden="true"
>
<div className="absolute inset-0 opacity-20">
<div className="absolute inset-0" style={{ <div className="absolute inset-0" style={{
backgroundImage: `repeating-linear-gradient( backgroundImage: `linear-gradient(
45deg, 135deg,
transparent, transparent 0%,
transparent 20px, transparent 49%,
hsl(var(--primary) / 0.4) 20px, rgba(255, 255, 255, 0.03) 49%,
hsl(var(--primary) / 0.4) 40px rgba(255, 255, 255, 0.03) 51%,
)` transparent 51%,
transparent 100%
)`,
backgroundSize: '80px 80px'
}} /> }} />
</div> </div>
<div className="absolute inset-0 opacity-10">
<div className="absolute inset-0" style={{
backgroundImage: `linear-gradient(hsl(var(--border) / 0.3) 1px, transparent 1px),
linear-gradient(90deg, hsl(var(--border) / 0.3) 1px, transparent 1px)`,
backgroundSize: '40px 40px'
}} />
</div>
<div className="absolute inset-0 bg-gradient-to-t from-background/80 via-transparent to-background/60" />
</div>
)} )}
{!isAuthenticated && !authLoading && ( {!isAuthenticated && !authLoading && (
+28 -22
View File
@@ -72,10 +72,11 @@ export function Homepage({
return ( return (
<div <div
className={`w-full min-h-svh grid place-items-center relative transition-[padding-top] duration-200 ease-linear ${ className={`w-full min-h-svh relative transition-[padding-top] duration-200 ease-linear ${
isTopbarOpen ? 'pt-[66px]' : 'pt-2' isTopbarOpen ? 'pt-[66px]' : 'pt-2'
}`}> }`}>
<div className="flex flex-row items-center justify-center gap-8 relative z-[10000]"> {!loggedIn ? (
<div className="absolute top-[66px] left-0 w-full h-[calc(100%-66px)] flex items-center justify-center">
<HomepageAuth <HomepageAuth
setLoggedIn={setLoggedIn} setLoggedIn={setLoggedIn}
setIsAdmin={setIsAdmin} setIsAdmin={setIsAdmin}
@@ -87,61 +88,66 @@ export function Homepage({
setDbError={setDbError} setDbError={setDbError}
onAuthSuccess={onAuthSuccess} onAuthSuccess={onAuthSuccess}
/> />
</div>
<div className="flex flex-row items-center justify-center gap-8"> ) : (
{loggedIn && ( <div className="absolute top-[66px] left-0 w-full h-[calc(100%-66px)] flex items-center justify-center">
<div className="flex flex-col items-center gap-4 w-[350px]"> <div className="flex flex-row items-center justify-center gap-8 relative z-[10000]">
<div className="flex flex-col items-center gap-6 w-[400px]">
<div <div
className="my-2 text-center bg-muted/50 border-2 border-[#303032] rounded-lg p-4 w-full"> className="text-center bg-[#18181b] border-2 border-[#303032] rounded-lg p-6 w-full shadow-lg">
<h3 className="text-lg font-semibold mb-2">Logged in!</h3> <h3 className="text-xl font-bold mb-3 text-white">Logged in!</h3>
<p className="text-muted-foreground"> <p className="text-gray-300 leading-relaxed">
You are logged in! Use the sidebar to access all available tools. To get started, You are logged in! Use the sidebar to access all available tools. To get started,
create an SSH Host in the SSH Manager tab. Once created, you can connect to that create an SSH Host in the SSH Manager tab. Once created, you can connect to that
host using the other apps in the sidebar. host using the other apps in the sidebar.
</p> </p>
</div> </div>
<div className="flex flex-row items-center gap-2"> <div className="flex flex-row items-center gap-3">
<Button <Button
variant="link" variant="outline"
className="text-sm" size="sm"
className="text-sm border-[#303032] text-gray-300 hover:text-white hover:bg-[#18181b] transition-colors"
onClick={() => window.open('https://github.com/LukeGus/Termix', '_blank')} onClick={() => window.open('https://github.com/LukeGus/Termix', '_blank')}
> >
GitHub GitHub
</Button> </Button>
<div className="w-px h-4 bg-border"></div> <div className="w-px h-4 bg-[#303032]"></div>
<Button <Button
variant="link" variant="outline"
className="text-sm" size="sm"
className="text-sm border-[#303032] text-gray-300 hover:text-white hover:bg-[#18181b] transition-colors"
onClick={() => window.open('https://github.com/LukeGus/Termix/issues/new', '_blank')} onClick={() => window.open('https://github.com/LukeGus/Termix/issues/new', '_blank')}
> >
Feedback Feedback
</Button> </Button>
<div className="w-px h-4 bg-border"></div> <div className="w-px h-4 bg-[#303032]"></div>
<Button <Button
variant="link" variant="outline"
className="text-sm" size="sm"
className="text-sm border-[#303032] text-gray-300 hover:text-white hover:bg-[#18181b] transition-colors"
onClick={() => window.open('https://discord.com/invite/jVQGdvHDrf', '_blank')} onClick={() => window.open('https://discord.com/invite/jVQGdvHDrf', '_blank')}
> >
Discord Discord
</Button> </Button>
<div className="w-px h-4 bg-border"></div> <div className="w-px h-4 bg-[#303032]"></div>
<Button <Button
variant="link" variant="outline"
className="text-sm" size="sm"
className="text-sm border-[#303032] text-gray-300 hover:text-white hover:bg-[#18181b] transition-colors"
onClick={() => window.open('https://github.com/sponsors/LukeGus', '_blank')} onClick={() => window.open('https://github.com/sponsors/LukeGus', '_blank')}
> >
Donate Donate
</Button> </Button>
</div> </div>
</div> </div>
)}
<HomepageUpdateLog <HomepageUpdateLog
loggedIn={loggedIn} loggedIn={loggedIn}
/> />
</div> </div>
</div> </div>
)}
<HomepageAlertManager <HomepageAlertManager
userId={userId} userId={userId}
+1 -1
View File
@@ -346,7 +346,7 @@ export function HomepageAuth({
return ( return (
<div <div
className={`w-[420px] max-w-full p-6 flex flex-col ${className || ''}`} className={`w-[420px] max-w-full p-6 flex flex-col bg-[#18181b] border-2 border-[#303032] rounded-md ${className || ''}`}
{...props} {...props}
> >
{dbError && ( {dbError && (
+20 -27
View File
@@ -89,70 +89,63 @@ export function HomepageUpdateLog({loggedIn}: HomepageUpdateLogProps) {
}; };
return ( return (
<div className="w-[400px] h-[600px] flex flex-col border-2 border-border rounded-lg bg-card p-4"> <div className="w-[400px] h-[600px] flex flex-col border-2 border-[#303032] rounded-lg bg-[#18181b] p-4 shadow-lg">
<div> <div>
<h3 className="text-lg font-semibold mb-3">Updates & Releases</h3> <h3 className="text-lg font-bold mb-3 text-white">Updates & Releases</h3>
<Separator className="p-0.25 mt-3 mb-3"/> <Separator className="p-0.25 mt-3 mb-3 bg-[#303032]"/>
{versionInfo && versionInfo.status === 'requires_update' && ( {versionInfo && versionInfo.status === 'requires_update' && (
<Alert> <Alert className="bg-[#0e0e10] border-[#303032] text-white">
<AlertTitle>Update Available</AlertTitle> <AlertTitle className="text-white">Update Available</AlertTitle>
<AlertDescription> <AlertDescription className="text-gray-300">
A new version ({versionInfo.version}) is available. A new version ({versionInfo.version}) is available.
<Button
variant="link"
className="p-0 h-auto underline ml-1"
onClick={() => window.open("https://docs.termix.site/docs", '_blank')}
>
Update now
</Button>
</AlertDescription> </AlertDescription>
</Alert> </Alert>
)} )}
</div> </div>
{versionInfo && versionInfo.status === 'requires_update' && ( {versionInfo && versionInfo.status === 'requires_update' && (
<Separator className="p-0.25 mt-3 mb-3"/> <Separator className="p-0.25 mt-3 mb-3 bg-[#303032]"/>
)} )}
<div className="flex-1 overflow-y-auto space-y-3"> <div className="flex-1 overflow-y-auto space-y-3 pr-2">
{loading && ( {loading && (
<div className="flex items-center justify-center h-32"> <div className="flex items-center justify-center h-32">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary"></div> <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-500"></div>
</div> </div>
)} )}
{error && ( {error && (
<Alert variant="destructive"> <Alert variant="destructive" className="bg-red-900/20 border-red-500 text-red-300">
<AlertTitle>Error</AlertTitle> <AlertTitle className="text-red-300">Error</AlertTitle>
<AlertDescription>{error}</AlertDescription> <AlertDescription className="text-red-300">{error}</AlertDescription>
</Alert> </Alert>
)} )}
{releases?.items.map((release) => ( {releases?.items.map((release) => (
<div <div
key={release.id} key={release.id}
className="border border-border rounded-lg p-3 hover:bg-accent transition-colors cursor-pointer" className="border border-[#303032] rounded-lg p-3 hover:bg-[#0e0e10] transition-colors cursor-pointer bg-[#0e0e10]/50"
onClick={() => window.open(release.link, '_blank')} onClick={() => window.open(release.link, '_blank')}
> >
<div className="flex items-start justify-between mb-2"> <div className="flex items-start justify-between mb-2">
<h4 className="font-medium text-sm leading-tight flex-1"> <h4 className="font-semibold text-sm leading-tight flex-1 text-white">
{release.title} {release.title}
</h4> </h4>
{release.isPrerelease && ( {release.isPrerelease && (
<span <span
className="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded ml-2 flex-shrink-0"> className="text-xs bg-yellow-600 text-yellow-100 px-2 py-1 rounded ml-2 flex-shrink-0 font-medium">
Pre-release Pre-release
</span> </span>
)} )}
</div> </div>
<p className="text-xs text-muted-foreground mb-2 leading-relaxed"> <p className="text-xs text-gray-300 mb-2 leading-relaxed">
{formatDescription(release.description)} {formatDescription(release.description)}
</p> </p>
<div className="flex items-center text-xs text-muted-foreground"> <div className="flex items-center text-xs text-gray-400">
<span>{new Date(release.pubDate).toLocaleDateString()}</span> <span>{new Date(release.pubDate).toLocaleDateString()}</span>
{release.assets.length > 0 && ( {release.assets.length > 0 && (
<> <>
@@ -165,9 +158,9 @@ export function HomepageUpdateLog({loggedIn}: HomepageUpdateLogProps) {
))} ))}
{releases && releases.items.length === 0 && !loading && ( {releases && releases.items.length === 0 && !loading && (
<Alert> <Alert className="bg-[#0e0e10] border-[#303032] text-gray-300">
<AlertTitle>No Releases</AlertTitle> <AlertTitle className="text-gray-300">No Releases</AlertTitle>
<AlertDescription> <AlertDescription className="text-gray-400">
No releases found. No releases found.
</AlertDescription> </AlertDescription>
</Alert> </Alert>