Skip to content

Commit 831260e

Browse files
committed
Many styling fixes + settings page
* Fixed sidebar settings button not changing tab * Fixed issue with password item name size squishing favicon preview * Fixed issue with password scroll-area only having a height relative to the amount of items contained. * Fixed issue of password scroll-area overflowing * Fixed issue of password data length expanding password details window * Started settings page * Removed unnecessary imports.
1 parent e6f3db6 commit 831260e

File tree

9 files changed

+544
-10676
lines changed

9 files changed

+544
-10676
lines changed

package-lock.json

Lines changed: 0 additions & 10326 deletions
This file was deleted.

src/app/layout.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import type { Metadata } from "next";
1+
import {TooltipProvider} from "@/components/ui/tooltip";
2+
import {ClerkProvider} from "@clerk/nextjs";
3+
import type {Metadata} from "next";
4+
import {Toaster} from "react-hot-toast";
25
import "./globals.css";
3-
import { ClerkProvider } from "@clerk/nextjs";
4-
import { Toaster } from "react-hot-toast";
5-
import { TooltipProvider } from "@/components/ui/tooltip";
66

77
export const metadata: Metadata = {
88
title: "LockScript - Vault",

src/components/ui/switch.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"use client"
2+
3+
import * as React from "react"
4+
import * as SwitchPrimitives from "@radix-ui/react-switch"
5+
6+
import { cn } from "@/lib/utils"
7+
8+
const Switch = React.forwardRef<
9+
React.ElementRef<typeof SwitchPrimitives.Root>,
10+
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
11+
>(({ className, ...props }, ref) => (
12+
<SwitchPrimitives.Root
13+
className={cn(
14+
"peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",
15+
className
16+
)}
17+
{...props}
18+
ref={ref}
19+
>
20+
<SwitchPrimitives.Thumb
21+
className={cn(
22+
"pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0"
23+
)}
24+
/>
25+
</SwitchPrimitives.Root>
26+
))
27+
Switch.displayName = SwitchPrimitives.Root.displayName
28+
29+
export { Switch }

src/components/vault/empty-state.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import {CreditCard,Lock,Pin,StickyNote} from "lucide-react"
2-
import type React from "react"
1+
import { CreditCard, Lock, Pin, StickyNote } from "lucide-react";
32

43
interface EmptyStateProps {
5-
activeTab: string
4+
activeTab: string;
65
}
76

87
export const EmptyState: React.FC<EmptyStateProps> = ({ activeTab }) => {
@@ -11,20 +10,23 @@ export const EmptyState: React.FC<EmptyStateProps> = ({ activeTab }) => {
1110
notes: StickyNote,
1211
pins: Pin,
1312
cards: CreditCard,
14-
}
13+
};
1514

16-
const Icon = icons[activeTab as keyof typeof icons] || Lock
15+
const Icon = icons[activeTab as keyof typeof icons] || Lock;
1716

1817
return (
1918
<div className="flex h-full flex-col items-center justify-center space-y-4 text-center">
2019
<div className="rounded-xl bg-gray-100 p-4">
2120
<Icon className="h-8 w-8 text-gray-400" />
2221
</div>
2322
<div>
24-
<h3 className="text-lg font-medium text-gray-900">No {activeTab} Selected</h3>
25-
<p className="text-sm text-gray-500">Select an entry to view its details</p>
23+
<h3 className="text-lg font-medium text-gray-900">
24+
No {activeTab} Selected
25+
</h3>
26+
<p className="text-sm text-gray-500">
27+
Select an entry to view its details
28+
</p>
2629
</div>
2730
</div>
28-
)
29-
}
30-
31+
);
32+
};
Lines changed: 85 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
"use client";
2+
13
import { Button } from "@/components/ui/button";
24
import {
35
DropdownMenu,
46
DropdownMenuContent,
57
DropdownMenuItem,
68
DropdownMenuTrigger,
79
} from "@/components/ui/dropdown-menu";
10+
import { cn } from "@/lib/utils";
811
import {
912
Eye,
1013
EyeOff,
@@ -45,15 +48,17 @@ export const PasswordDetails: React.FC<PasswordDetailsProps> = ({
4548
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
4649

4750
return (
48-
<div className="space-y-6">
51+
<div className="space-y-6 mx-auto">
4952
<div className="flex items-center justify-between">
50-
<h2 className="text-2xl font-bold text-gray-800">{entry.name}</h2>
53+
<h2 className="text-2xl font-bold text-gray-800 dark:text-gray-200 truncate flex-1 mr-2">
54+
{entry.name}
55+
</h2>
5156
<DropdownMenu>
5257
<DropdownMenuTrigger asChild>
5358
<Button
5459
variant="ghost"
5560
size="icon"
56-
className="bg-rose-50 hover:hover:bg-rose-100"
61+
className="bg-rose-50 hover:hover:bg-rose-100 dark:bg-rose-900 dark:hover:bg-rose-800"
5762
>
5863
<MoreVertical className="h-4 w-4" />
5964
</Button>
@@ -72,91 +77,72 @@ export const PasswordDetails: React.FC<PasswordDetailsProps> = ({
7277
</div>
7378

7479
<div>
75-
<div className="flex items-center justify-between rounded-t-xl border border-gray-200 bg-gray-50/50 p-4">
76-
<Tooltip>
77-
<TooltipContent>Copy</TooltipContent>
78-
<TooltipTrigger
79-
onClick={() => {
80-
navigator.clipboard.writeText(entry.website);
81-
toast.success("Copied website succesfully");
82-
}}
83-
>
84-
<div className="flex items-center space-x-2">
85-
<Globe className="h-4 w-4" />
86-
<span className="text-gray-900">{entry.website}</span>
87-
</div>
88-
</TooltipTrigger>
89-
</Tooltip>
90-
80+
<DetailItem
81+
icon={<Globe className="h-4 w-4 flex-shrink-0" />}
82+
value={entry.website}
83+
onCopy={() => {
84+
navigator.clipboard.writeText(entry.website);
85+
toast.success("Copied website successfully");
86+
}}
87+
className="rounded-tl-xl rounded-tr-xl"
88+
>
9189
<a href={entry.website} target="_blank" rel="noopener noreferrer">
9290
<Button variant="ghost" size="icon" className="p-0">
9391
<SquareArrowOutUpRight className="h-4 w-4" />
9492
</Button>
9593
</a>
96-
</div>
97-
98-
<div className="flex items-center justify-between border border-gray-200 bg-gray-50/50 px-4 py-6">
99-
<Tooltip>
100-
<TooltipContent>Copy</TooltipContent>
101-
<TooltipTrigger
102-
onClick={() => {
103-
navigator.clipboard.writeText(entry.username);
104-
toast.success("Copied username succesfully");
105-
}}
106-
>
107-
<div className="flex items-center space-x-2">
108-
<User className="h-4 w-4" />
109-
<span className="text-gray-900">{entry.username}</span>
110-
</div>
111-
</TooltipTrigger>
112-
</Tooltip>
113-
</div>
94+
</DetailItem>
11495

115-
<div className="flex items-center justify-between rounded-b-xl border border-gray-200 bg-gray-50/50 p-4">
116-
<Tooltip>
117-
<TooltipContent>Copy</TooltipContent>
118-
<TooltipTrigger
119-
onClick={() => {
120-
navigator.clipboard.writeText(entry.password);
121-
toast.success("Copied password succesfully");
122-
}}
123-
>
124-
<div className="flex items-center space-x-2">
125-
<Lock className="h-4 w-4" />
126-
<span>
127-
{isPasswordVisible
128-
? entry.password
129-
: "•".repeat(entry.password.length)}
130-
</span>
131-
</div>
132-
</TooltipTrigger>
133-
</Tooltip>
96+
<DetailItem
97+
icon={<User className="h-4 w-4 flex-shrink-0" />}
98+
value={entry.username}
99+
onCopy={() => {
100+
navigator.clipboard.writeText(entry.username);
101+
toast.success("Copied username successfully");
102+
}}
103+
className="py-6"
104+
/>
134105

106+
<DetailItem
107+
icon={<Lock className="h-4 w-4 flex-shrink-0" />}
108+
value={
109+
isPasswordVisible
110+
? entry.password
111+
: "•".repeat(entry.password.length)
112+
}
113+
onCopy={() => {
114+
navigator.clipboard.writeText(entry.password);
115+
toast.success("Copied password successfully");
116+
}}
117+
className="rounded-br-xl rounded-bl-xl"
118+
>
135119
<Button
136120
variant="ghost"
137121
onClick={() => setIsPasswordVisible(!isPasswordVisible)}
138122
className="p-0"
139-
size={"icon"}
123+
size="icon"
140124
>
141125
{isPasswordVisible ? (
142126
<EyeOff className="h-4 w-4" />
143127
) : (
144128
<Eye className="h-4 w-4" />
145129
)}
146130
</Button>
147-
</div>
131+
</DetailItem>
148132
</div>
149133

150134
<div className="space-y-2">
151-
<h3 className="text-lg font-medium text-gray-500">History</h3>{" "}
152-
<div className="space-y-3 rounded-xl border border-gray-200 bg-gray-50/50 p-4">
135+
<h3 className="text-lg font-medium text-gray-500 dark:text-gray-400">
136+
History
137+
</h3>
138+
<div className="space-y-3 rounded-xl border border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50 p-4">
153139
{["Created", "Last modified", "Last access"].map((label) => (
154140
<div
155141
key={label}
156142
className="flex items-center justify-between text-xs"
157143
>
158-
<span className="text-gray-500">{label}</span>
159-
<span className="font-medium text-gray-900">
144+
<span className="text-gray-500 dark:text-gray-400">{label}</span>
145+
<span className="font-medium text-gray-900 dark:text-gray-100">
160146
{label === "Last access"
161147
? new Date(entry.lastAccess).toLocaleString()
162148
: label === "Last modified"
@@ -172,3 +158,40 @@ export const PasswordDetails: React.FC<PasswordDetailsProps> = ({
172158
</div>
173159
);
174160
};
161+
162+
interface DetailItemProps {
163+
icon: React.ReactNode;
164+
value: string;
165+
onCopy: () => void;
166+
children?: React.ReactNode;
167+
className?: string;
168+
}
169+
170+
const DetailItem: React.FC<DetailItemProps> = ({
171+
icon,
172+
value,
173+
onCopy,
174+
children,
175+
className,
176+
}) => (
177+
<div
178+
className={cn(
179+
"flex items-center justify-between border border-gray-200 dark:border-gray-700 bg-gray-50/50 dark:bg-gray-800/50 p-4",
180+
className
181+
)}
182+
>
183+
<Tooltip>
184+
<TooltipContent>Copy</TooltipContent>
185+
<TooltipTrigger
186+
onClick={onCopy}
187+
className="flex items-center space-x-2 max-w-[calc(100%-2rem)] overflow-hidden"
188+
>
189+
{icon}
190+
<span className="text-gray-900 dark:text-gray-100 truncate">
191+
{value}
192+
</span>
193+
</TooltipTrigger>
194+
</Tooltip>
195+
{children}
196+
</div>
197+
);

src/components/vault/settings.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"use client";
2+
3+
export function Settings() {
4+
return (
5+
<div className="w-full max-w-3xl mx-auto p-8">
6+
<h2 className="text-3xl font-bold mb-6">Settings</h2>
7+
</div>
8+
);
9+
}

src/components/vault/sidebar.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import {Button} from "@/components/ui/button";
2-
import {cn} from "@/lib/utils";
3-
import {UserButton} from "@clerk/nextjs";
4-
import {CreditCard,Key,Pin,Settings,StickyNote,X} from 'lucide-react';
1+
import { Button } from "@/components/ui/button";
2+
import { cn } from "@/lib/utils";
3+
import { UserButton } from "@clerk/nextjs";
4+
import { CreditCard, Key, Pin, Settings, StickyNote, X } from "lucide-react";
55

66
interface SidebarProps {
77
activeTab: string;
@@ -62,6 +62,10 @@ export const Sidebar: React.FC<SidebarProps> = ({
6262
"w-full justify-start gap-3 rounded-xl px-4 py-3 transition-all hover:bg-rose-100 hover:text-rose-700",
6363
activeTab === "settings" && "bg-rose-50 text-rose-700"
6464
)}
65+
onClick={() => {
66+
setActiveTab("settings");
67+
setIsSidebarOpen(false);
68+
}}
6569
>
6670
<Settings className="h-5 w-5" />
6771
Settings

0 commit comments

Comments
 (0)