mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-08 20:46:44 +03:00
More responsive layout updates to Config Page
This commit is contained in:
@@ -563,7 +563,7 @@ export function ConfigTabs() {
|
|||||||
) : (
|
) : (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Header section */}
|
{/* Header section */}
|
||||||
<div className="flex flex-row justify-between items-start">
|
<div className="flex flex-col md:flex-row justify-between gap-y-4 items-start">
|
||||||
<div className="flex flex-col gap-y-1.5">
|
<div className="flex flex-col gap-y-1.5">
|
||||||
<h1 className="text-2xl font-semibold leading-none tracking-tight">
|
<h1 className="text-2xl font-semibold leading-none tracking-tight">
|
||||||
Configuration Settings
|
Configuration Settings
|
||||||
|
|||||||
@@ -88,15 +88,17 @@ export function GitHubConfigForm({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="w-full h-full flex flex-col">
|
<Card className="w-full h-full flex flex-col">
|
||||||
<CardHeader className="flex flex-row items-center justify-between gap-4">
|
<CardHeader className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||||||
<CardTitle className="text-lg font-semibold">
|
<CardTitle className="text-lg font-semibold">
|
||||||
GitHub Configuration
|
GitHub Configuration
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
{/* Desktop: Show button in header */}
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="default"
|
||||||
onClick={testConnection}
|
onClick={testConnection}
|
||||||
disabled={isLoading || !config.token}
|
disabled={isLoading || !config.token}
|
||||||
|
className="hidden sm:inline-flex"
|
||||||
>
|
>
|
||||||
{isLoading ? "Testing..." : "Test Connection"}
|
{isLoading ? "Testing..." : "Test Connection"}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -200,6 +202,17 @@ export function GitHubConfigForm({
|
|||||||
if (onAdvancedOptionsAutoSave) onAdvancedOptionsAutoSave(newOptions);
|
if (onAdvancedOptionsAutoSave) onAdvancedOptionsAutoSave(newOptions);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Mobile: Show button at bottom */}
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="default"
|
||||||
|
onClick={testConnection}
|
||||||
|
disabled={isLoading || !config.token}
|
||||||
|
className="sm:hidden w-full"
|
||||||
|
>
|
||||||
|
{isLoading ? "Testing..." : "Test Connection"}
|
||||||
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export function GitHubMirrorSettings({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<div className="flex items-start space-x-3">
|
<div className="flex items-start space-x-3">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="starred-repos"
|
id="starred-repos"
|
||||||
@@ -145,10 +145,10 @@ export function GitHubMirrorSettings({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Starred repos content selection - inline to prevent layout shift */}
|
{/* Starred repos content selection - responsive layout */}
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
"flex items-center justify-end transition-opacity duration-200",
|
"flex items-center justify-end transition-opacity duration-200 mt-3 md:mt-0",
|
||||||
githubConfig.mirrorStarred ? "opacity-100" : "opacity-0 pointer-events-none"
|
githubConfig.mirrorStarred ? "opacity-100" : "opacity-0 hidden pointer-events-none"
|
||||||
)}>
|
)}>
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
@@ -156,7 +156,7 @@ export function GitHubMirrorSettings({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={!githubConfig.mirrorStarred}
|
disabled={!githubConfig.mirrorStarred}
|
||||||
className="h-8 text-xs font-normal min-w-[140px] justify-between"
|
className="h-8 text-xs font-normal min-w-[140px] md:min-w-[140px] justify-between"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{advancedOptions.skipStarredIssues ? (
|
{advancedOptions.skipStarredIssues ? (
|
||||||
@@ -325,7 +325,7 @@ export function GitHubMirrorSettings({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||||
<div className="flex items-start space-x-3">
|
<div className="flex items-start space-x-3">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
id="mirror-metadata"
|
id="mirror-metadata"
|
||||||
@@ -346,10 +346,10 @@ export function GitHubMirrorSettings({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Metadata multi-select - inline to prevent layout shift */}
|
{/* Metadata multi-select - responsive layout */}
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
"flex items-center justify-end transition-opacity duration-200",
|
"flex items-center justify-end transition-opacity duration-200 mt-3 md:mt-0",
|
||||||
mirrorOptions.mirrorMetadata ? "opacity-100" : "opacity-0 pointer-events-none"
|
mirrorOptions.mirrorMetadata ? "opacity-100" : "opacity-0 hidden pointer-events-none"
|
||||||
)}>
|
)}>
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
@@ -357,7 +357,7 @@ export function GitHubMirrorSettings({
|
|||||||
variant="outline"
|
variant="outline"
|
||||||
size="sm"
|
size="sm"
|
||||||
disabled={!mirrorOptions.mirrorMetadata}
|
disabled={!mirrorOptions.mirrorMetadata}
|
||||||
className="h-8 text-xs font-normal min-w-[140px] justify-between"
|
className="h-8 text-xs font-normal min-w-[140px] md:min-w-[140px] justify-between"
|
||||||
>
|
>
|
||||||
<span>
|
<span>
|
||||||
{(() => {
|
{(() => {
|
||||||
|
|||||||
@@ -136,15 +136,17 @@ export function GiteaConfigForm({ config, setConfig, onAutoSave, isAutoSaving, g
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card className="w-full h-full flex flex-col">
|
<Card className="w-full h-full flex flex-col">
|
||||||
<CardHeader className="flex flex-row items-center justify-between gap-4">
|
<CardHeader className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
|
||||||
<CardTitle className="text-lg font-semibold">
|
<CardTitle className="text-lg font-semibold">
|
||||||
Gitea Configuration
|
Gitea Configuration
|
||||||
</CardTitle>
|
</CardTitle>
|
||||||
|
{/* Desktop: Show button in header */}
|
||||||
<Button
|
<Button
|
||||||
type="button"
|
type="button"
|
||||||
variant="outline"
|
variant="default"
|
||||||
onClick={testConnection}
|
onClick={testConnection}
|
||||||
disabled={isLoading || !config.url || !config.token}
|
disabled={isLoading || !config.url || !config.token}
|
||||||
|
className="hidden sm:inline-flex"
|
||||||
>
|
>
|
||||||
{isLoading ? "Testing..." : "Test Connection"}
|
{isLoading ? "Testing..." : "Test Connection"}
|
||||||
</Button>
|
</Button>
|
||||||
@@ -252,6 +254,17 @@ export function GiteaConfigForm({ config, setConfig, onAutoSave, isAutoSaving, g
|
|||||||
if (onAutoSave) onAutoSave(newConfig);
|
if (onAutoSave) onAutoSave(newConfig);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
{/* Mobile: Show button at bottom */}
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="default"
|
||||||
|
onClick={testConnection}
|
||||||
|
disabled={isLoading || !config.url || !config.token}
|
||||||
|
className="sm:hidden w-full"
|
||||||
|
>
|
||||||
|
{isLoading ? "Testing..." : "Test Connection"}
|
||||||
|
</Button>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ export const OrganizationConfiguration: React.FC<OrganizationConfigurationProps>
|
|||||||
<Icon className="h-3.5 w-3.5" />
|
<Icon className="h-3.5 w-3.5" />
|
||||||
<span>{option.label}</span>
|
<span>{option.label}</span>
|
||||||
</div>
|
</div>
|
||||||
<Info className="h-3 w-3 text-muted-foreground opacity-50 group-hover:opacity-100 transition-opacity" />
|
<Info className="h-3 w-3 text-muted-foreground opacity-50 group-hover:opacity-100 transition-opacity hidden sm:inline-block" />
|
||||||
</button>
|
</button>
|
||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipContent>
|
<TooltipContent>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ const strategyConfig = {
|
|||||||
preserve: {
|
preserve: {
|
||||||
title: "Preserve Structure",
|
title: "Preserve Structure",
|
||||||
icon: FolderTree,
|
icon: FolderTree,
|
||||||
description: "Keep the exact same organization structure as GitHub",
|
description: "Keep the exact same org structure as GitHub",
|
||||||
color: "text-blue-600 dark:text-blue-400",
|
color: "text-blue-600 dark:text-blue-400",
|
||||||
bgColor: "bg-blue-50 dark:bg-blue-950/20",
|
bgColor: "bg-blue-50 dark:bg-blue-950/20",
|
||||||
borderColor: "border-blue-200 dark:border-blue-900",
|
borderColor: "border-blue-200 dark:border-blue-900",
|
||||||
@@ -60,7 +60,7 @@ const strategyConfig = {
|
|||||||
"mixed": {
|
"mixed": {
|
||||||
title: "Mixed Mode",
|
title: "Mixed Mode",
|
||||||
icon: GitBranch,
|
icon: GitBranch,
|
||||||
description: "user repos in single org, org repos preserve structure",
|
description: "Personal repos in single org, org repos preserve structure",
|
||||||
color: "text-orange-600 dark:text-orange-400",
|
color: "text-orange-600 dark:text-orange-400",
|
||||||
bgColor: "bg-orange-50 dark:bg-orange-950/20",
|
bgColor: "bg-orange-50 dark:bg-orange-950/20",
|
||||||
borderColor: "border-orange-200 dark:border-orange-900",
|
borderColor: "border-orange-200 dark:border-orange-900",
|
||||||
@@ -281,7 +281,7 @@ export const OrganizationStrategy: React.FC<OrganizationStrategyProps> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="flex items-start justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-start sm:justify-between gap-4">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<h4 className="text-sm font-medium mb-3 flex items-center gap-2">
|
<h4 className="text-sm font-medium mb-3 flex items-center gap-2">
|
||||||
<Building className="h-4 w-4" />
|
<Building className="h-4 w-4" />
|
||||||
@@ -371,15 +371,16 @@ export const OrganizationStrategy: React.FC<OrganizationStrategyProps> = ({
|
|||||||
!isSelected && "border-muted"
|
!isSelected && "border-muted"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="p-3">
|
<div className="p-3 sm:p-4">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-start gap-3">
|
||||||
<RadioGroupItem
|
<RadioGroupItem
|
||||||
value={key}
|
value={key}
|
||||||
id={key}
|
id={key}
|
||||||
|
className="mt-1"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className={cn(
|
<div className={cn(
|
||||||
"rounded-lg p-2",
|
"rounded-lg p-2 flex-shrink-0",
|
||||||
isSelected ? config.bgColor : "bg-muted dark:bg-muted/50"
|
isSelected ? config.bgColor : "bg-muted dark:bg-muted/50"
|
||||||
)}>
|
)}>
|
||||||
<Icon className={cn(
|
<Icon className={cn(
|
||||||
@@ -388,38 +389,40 @@ export const OrganizationStrategy: React.FC<OrganizationStrategyProps> = ({
|
|||||||
)} />
|
)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex-1">
|
<div className="flex-1 min-w-0">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-start justify-between gap-2">
|
||||||
<h4 className="font-medium text-sm">{config.title}</h4>
|
<div className="flex-1">
|
||||||
</div>
|
<h4 className="font-medium text-sm">{config.title}</h4>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5">
|
<p className="text-xs text-muted-foreground mt-1 leading-relaxed">
|
||||||
{config.description}
|
{config.description}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
|
||||||
|
|
||||||
<HoverCard openDelay={200}>
|
|
||||||
<HoverCardTrigger asChild>
|
|
||||||
<span
|
|
||||||
className="inline-flex p-1.5 hover:bg-muted rounded-md transition-colors cursor-help"
|
|
||||||
onClick={(e) => e.stopPropagation()}
|
|
||||||
>
|
|
||||||
<Info className="h-4 w-4 text-muted-foreground" />
|
|
||||||
</span>
|
|
||||||
</HoverCardTrigger>
|
|
||||||
<HoverCardContent side="left" align="center" className="w-[500px]">
|
|
||||||
<div className="space-y-3">
|
|
||||||
<h4 className="font-medium text-sm">Repository Mapping Preview</h4>
|
|
||||||
<MappingPreview
|
|
||||||
strategy={key}
|
|
||||||
config={config}
|
|
||||||
destinationOrg={destinationOrg}
|
|
||||||
starredReposOrg={starredReposOrg}
|
|
||||||
githubUsername={githubUsername}
|
|
||||||
giteaUsername={giteaUsername}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</HoverCardContent>
|
|
||||||
</HoverCard>
|
<HoverCard openDelay={200}>
|
||||||
|
<HoverCardTrigger asChild>
|
||||||
|
<span
|
||||||
|
className="inline-flex p-1 sm:p-1.5 hover:bg-muted rounded-md transition-colors cursor-help flex-shrink-0 ml-2"
|
||||||
|
onClick={(e) => e.stopPropagation()}
|
||||||
|
>
|
||||||
|
<Info className="h-3.5 w-3.5 sm:h-4 sm:w-4 text-muted-foreground" />
|
||||||
|
</span>
|
||||||
|
</HoverCardTrigger>
|
||||||
|
<HoverCardContent side="left" align="center" className="w-[500px]">
|
||||||
|
<div className="space-y-3">
|
||||||
|
<h4 className="font-medium text-sm">Repository Mapping Preview</h4>
|
||||||
|
<MappingPreview
|
||||||
|
strategy={key}
|
||||||
|
config={config}
|
||||||
|
destinationOrg={destinationOrg}
|
||||||
|
starredReposOrg={starredReposOrg}
|
||||||
|
githubUsername={githubUsername}
|
||||||
|
giteaUsername={giteaUsername}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</HoverCardContent>
|
||||||
|
</HoverCard>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Card>
|
</Card>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export function Sidebar({ className, onNavigate, isOpen, onClose }: SidebarProps
|
|||||||
{/* Mobile Backdrop */}
|
{/* Mobile Backdrop */}
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<div
|
<div
|
||||||
className="fixed inset-0 bg-background/80 backdrop-blur-sm z-40 lg:hidden"
|
className="fixed inset-0 backdrop-blur-sm z-40 lg:hidden"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -72,13 +72,13 @@ export function Sidebar({ className, onNavigate, isOpen, onClose }: SidebarProps
|
|||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
<aside
|
<aside
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed lg:static inset-y-0 left-0 z-50 w-64 bg-background border-r flex flex-col h-full transition-transform duration-200 ease-in-out lg:translate-x-0",
|
"fixed lg:static inset-y-0 left-0 z-50 w-64 bg-background border-r flex flex-col h-full lg:h-[calc(100vh-4.5rem)] transition-transform duration-200 ease-in-out lg:translate-x-0",
|
||||||
isOpen ? "translate-x-0" : "-translate-x-full",
|
isOpen ? "translate-x-0" : "-translate-x-full",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex flex-col h-full pt-4">
|
<div className="flex flex-col h-full">
|
||||||
<nav className="flex flex-col gap-y-1 lg:gap-y-1 pl-2 pr-3">
|
<nav className="flex flex-col gap-y-1 lg:gap-y-1 pl-2 pr-3 pt-4 flex-shrink-0">
|
||||||
{links.map((link, index) => {
|
{links.map((link, index) => {
|
||||||
const isActive = currentPath === link.href;
|
const isActive = currentPath === link.href;
|
||||||
const Icon = link.icon;
|
const Icon = link.icon;
|
||||||
@@ -101,7 +101,9 @@ export function Sidebar({ className, onNavigate, isOpen, onClose }: SidebarProps
|
|||||||
})}
|
})}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div className="mt-auto px-4 py-4">
|
<div className="flex-1 min-h-0" />
|
||||||
|
|
||||||
|
<div className="px-4 py-4 flex-shrink-0">
|
||||||
<div className="rounded-md bg-muted p-3 lg:p-3">
|
<div className="rounded-md bg-muted p-3 lg:p-3">
|
||||||
<h4 className="text-sm font-medium mb-2">Need Help?</h4>
|
<h4 className="text-sm font-medium mb-2">Need Help?</h4>
|
||||||
<p className="text-xs text-muted-foreground mb-3 lg:mb-2">
|
<p className="text-xs text-muted-foreground mb-3 lg:mb-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user