Skip to content

Commit 447332e

Browse files
fix: align toggle switches in repository settings
- Remove fixed label width from Toggle component - Move delete button to left of toggle switches - Add matching border/padding to 'Enable after adding' section to align with repository items - Ensure all toggles have consistent right-side alignment
1 parent 9bbc19a commit 447332e

File tree

2 files changed

+70
-58
lines changed

2 files changed

+70
-58
lines changed

src/app/_components/GeneralSettingsModal.tsx

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,7 @@ export function GeneralSettingsModal({
16301630
https://github.com/owner/repo)
16311631
</p>
16321632
</div>
1633-
<div className="flex items-center justify-between">
1633+
<div className="border-border flex items-center justify-between gap-3 rounded-lg border p-3">
16341634
<div>
16351635
<p className="text-foreground text-sm font-medium">
16361636
Enable after adding
@@ -1644,6 +1644,7 @@ export function GeneralSettingsModal({
16441644
onCheckedChange={setNewRepoEnabled}
16451645
disabled={isAddingRepo}
16461646
label="Enable repository"
1647+
labelPosition="left"
16471648
/>
16481649
</div>
16491650
<Button
@@ -1739,44 +1740,7 @@ export function GeneralSettingsModal({
17391740
{repo.enabled ? "• Enabled" : "• Disabled"}
17401741
</p>
17411742
</div>
1742-
<div className="flex items-center gap-2">
1743-
<Toggle
1744-
checked={repo.enabled}
1745-
onCheckedChange={async (enabled) => {
1746-
setMessage(null);
1747-
try {
1748-
const result =
1749-
await updateRepoMutation.mutateAsync({
1750-
id: repo.id,
1751-
enabled,
1752-
});
1753-
if (result.success) {
1754-
setMessage({
1755-
type: "success",
1756-
text: `Repository ${enabled ? "enabled" : "disabled"} successfully!`,
1757-
});
1758-
await refetchRepositories();
1759-
} else {
1760-
setMessage({
1761-
type: "error",
1762-
text:
1763-
result.error ??
1764-
"Failed to update repository",
1765-
});
1766-
}
1767-
} catch (error) {
1768-
setMessage({
1769-
type: "error",
1770-
text:
1771-
error instanceof Error
1772-
? error.message
1773-
: "Failed to update repository",
1774-
});
1775-
}
1776-
}}
1777-
disabled={updateRepoMutation.isPending}
1778-
label={repo.enabled ? "Disable" : "Enable"}
1779-
/>
1743+
<div className="flex items-center gap-2 flex-shrink-0">
17801744
<Button
17811745
onClick={async () => {
17821746
if (!repo.is_removable) {
@@ -1837,6 +1801,44 @@ export function GeneralSettingsModal({
18371801
>
18381802
<Trash2 className="h-4 w-4" />
18391803
</Button>
1804+
<Toggle
1805+
checked={repo.enabled}
1806+
onCheckedChange={async (enabled) => {
1807+
setMessage(null);
1808+
try {
1809+
const result =
1810+
await updateRepoMutation.mutateAsync({
1811+
id: repo.id,
1812+
enabled,
1813+
});
1814+
if (result.success) {
1815+
setMessage({
1816+
type: "success",
1817+
text: `Repository ${enabled ? "enabled" : "disabled"} successfully!`,
1818+
});
1819+
await refetchRepositories();
1820+
} else {
1821+
setMessage({
1822+
type: "error",
1823+
text:
1824+
result.error ??
1825+
"Failed to update repository",
1826+
});
1827+
}
1828+
} catch (error) {
1829+
setMessage({
1830+
type: "error",
1831+
text:
1832+
error instanceof Error
1833+
? error.message
1834+
: "Failed to update repository",
1835+
});
1836+
}
1837+
}}
1838+
disabled={updateRepoMutation.isPending}
1839+
label={repo.enabled ? "Disable" : "Enable"}
1840+
labelPosition="left"
1841+
/>
18401842
</div>
18411843
</div>
18421844
),

src/app/_components/ui/toggle.tsx

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6,30 +6,40 @@ export interface ToggleProps
66
checked?: boolean;
77
onCheckedChange?: (checked: boolean) => void;
88
label?: string;
9+
labelPosition?: 'left' | 'right';
910
}
1011

1112
const Toggle = React.forwardRef<HTMLInputElement, ToggleProps>(
12-
({ className, checked, onCheckedChange, label, ...props }, ref) => {
13+
({ className, checked, onCheckedChange, label, labelPosition = 'right', ...props }, ref) => {
14+
const toggleSwitch = (
15+
<label className="relative inline-flex items-center cursor-pointer">
16+
<input
17+
type="checkbox"
18+
className="sr-only"
19+
checked={checked}
20+
onChange={(e) => onCheckedChange?.(e.target.checked)}
21+
ref={ref}
22+
{...props}
23+
/>
24+
<div className={cn(
25+
"w-11 h-6 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary/20 rounded-full peer after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 dark:after:border-gray-500 after:border after:rounded-full after:h-5 after:w-5 after:transition-transform after:duration-300 after:ease-in-out after:shadow-md transition-colors duration-300 ease-in-out border-2 border-gray-300 dark:border-gray-600",
26+
checked
27+
? "bg-blue-500 dark:bg-blue-600 after:translate-x-full"
28+
: "bg-gray-300 dark:bg-gray-700",
29+
className
30+
)} />
31+
</label>
32+
);
33+
1334
return (
1435
<div className="flex items-center space-x-3">
15-
<label className="relative inline-flex items-center cursor-pointer">
16-
<input
17-
type="checkbox"
18-
className="sr-only"
19-
checked={checked}
20-
onChange={(e) => onCheckedChange?.(e.target.checked)}
21-
ref={ref}
22-
{...props}
23-
/>
24-
<div className={cn(
25-
"w-11 h-6 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-primary/20 rounded-full peer after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 dark:after:border-gray-500 after:border after:rounded-full after:h-5 after:w-5 after:transition-transform after:duration-300 after:ease-in-out after:shadow-md transition-colors duration-300 ease-in-out border-2 border-gray-300 dark:border-gray-600",
26-
checked
27-
? "bg-blue-500 dark:bg-blue-600 after:translate-x-full"
28-
: "bg-gray-300 dark:bg-gray-700",
29-
className
30-
)} />
31-
</label>
32-
{label && (
36+
{label && labelPosition === 'left' && (
37+
<span className="text-sm font-medium text-foreground">
38+
{label}
39+
</span>
40+
)}
41+
{toggleSwitch}
42+
{label && labelPosition === 'right' && (
3343
<span className="text-sm font-medium text-foreground">
3444
{label}
3545
</span>

0 commit comments

Comments
 (0)