mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2025-12-09 21:16:48 +03:00
Added eye/eye-off icon toggle for password field
This commit is contained in:
@@ -11,11 +11,12 @@ import { authClient } from '@/lib/auth-client';
|
|||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { toast, Toaster } from 'sonner';
|
import { toast, Toaster } from 'sonner';
|
||||||
import { showErrorToast } from '@/lib/utils';
|
import { showErrorToast } from '@/lib/utils';
|
||||||
import { Loader2, Mail, Globe } from 'lucide-react';
|
import { Loader2, Mail, Globe, Eye, EyeOff } from 'lucide-react';
|
||||||
|
|
||||||
|
|
||||||
export function LoginForm() {
|
export function LoginForm() {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
const [ssoEmail, setSsoEmail] = useState('');
|
const [ssoEmail, setSsoEmail] = useState('');
|
||||||
const { login } = useAuth();
|
const { login } = useAuth();
|
||||||
const { authMethods, isLoading: isLoadingMethods } = useAuthMethods();
|
const { authMethods, isLoading: isLoadingMethods } = useAuthMethods();
|
||||||
@@ -139,15 +140,29 @@ export function LoginForm() {
|
|||||||
<label htmlFor="password" className="block text-sm font-medium mb-1">
|
<label htmlFor="password" className="block text-sm font-medium mb-1">
|
||||||
Password
|
Password
|
||||||
</label>
|
</label>
|
||||||
<input
|
<div className="relative">
|
||||||
id="password"
|
<input
|
||||||
name="password"
|
id="password"
|
||||||
type="password"
|
name="password"
|
||||||
required
|
type={showPassword ? "text" : "password"}
|
||||||
className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
required
|
||||||
placeholder="Enter your password"
|
className="w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||||
disabled={isLoading}
|
placeholder="Enter your password"
|
||||||
/>
|
disabled={isLoading}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="absolute inset-y-0 right-0 flex items-center pr-3"
|
||||||
|
onClick={() => setShowPassword(!showPassword)}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
{showPassword ? (
|
||||||
|
<EyeOff className="h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" />
|
||||||
|
) : (
|
||||||
|
<Eye className="h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -6,9 +6,12 @@ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle }
|
|||||||
import { toast, Toaster } from 'sonner';
|
import { toast, Toaster } from 'sonner';
|
||||||
import { showErrorToast } from '@/lib/utils';
|
import { showErrorToast } from '@/lib/utils';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
|
import { Eye, EyeOff } from 'lucide-react';
|
||||||
|
|
||||||
export function SignupForm() {
|
export function SignupForm() {
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||||
const { register } = useAuth();
|
const { register } = useAuth();
|
||||||
|
|
||||||
async function handleSignup(e: React.FormEvent<HTMLFormElement>) {
|
async function handleSignup(e: React.FormEvent<HTMLFormElement>) {
|
||||||
@@ -86,29 +89,57 @@ export function SignupForm() {
|
|||||||
<label htmlFor="password" className="block text-sm font-medium mb-1">
|
<label htmlFor="password" className="block text-sm font-medium mb-1">
|
||||||
Password
|
Password
|
||||||
</label>
|
</label>
|
||||||
<input
|
<div className="relative">
|
||||||
id="password"
|
<input
|
||||||
name="password"
|
id="password"
|
||||||
type="password"
|
name="password"
|
||||||
required
|
type={showPassword ? "text" : "password"}
|
||||||
className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
required
|
||||||
placeholder="Create a password"
|
className="w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||||
disabled={isLoading}
|
placeholder="Create a password"
|
||||||
/>
|
disabled={isLoading}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="absolute inset-y-0 right-0 flex items-center pr-3"
|
||||||
|
onClick={() => setShowPassword(!showPassword)}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
{showPassword ? (
|
||||||
|
<EyeOff className="h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" />
|
||||||
|
) : (
|
||||||
|
<Eye className="h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label htmlFor="confirmPassword" className="block text-sm font-medium mb-1">
|
<label htmlFor="confirmPassword" className="block text-sm font-medium mb-1">
|
||||||
Confirm Password
|
Confirm Password
|
||||||
</label>
|
</label>
|
||||||
<input
|
<div className="relative">
|
||||||
id="confirmPassword"
|
<input
|
||||||
name="confirmPassword"
|
id="confirmPassword"
|
||||||
type="password"
|
name="confirmPassword"
|
||||||
required
|
type={showConfirmPassword ? "text" : "password"}
|
||||||
className="w-full rounded-md border border-input bg-background px-3 py-2 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
required
|
||||||
placeholder="Confirm your password"
|
className="w-full rounded-md border border-input bg-background px-3 py-2 pr-10 text-sm shadow-sm transition-colors placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
|
||||||
disabled={isLoading}
|
placeholder="Confirm your password"
|
||||||
/>
|
disabled={isLoading}
|
||||||
|
/>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="absolute inset-y-0 right-0 flex items-center pr-3"
|
||||||
|
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
||||||
|
tabIndex={-1}
|
||||||
|
>
|
||||||
|
{showConfirmPassword ? (
|
||||||
|
<EyeOff className="h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" />
|
||||||
|
) : (
|
||||||
|
<Eye className="h-4 w-4 text-muted-foreground hover:text-foreground transition-colors" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
|||||||
import type { MirrorJob } from "@/lib/db/schema";
|
import type { MirrorJob } from "@/lib/db/schema";
|
||||||
import { formatDate, getStatusColor } from "@/lib/utils";
|
import { formatDate, getStatusColor } from "@/lib/utils";
|
||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
|
import { Activity, Clock } from "lucide-react";
|
||||||
|
|
||||||
interface RecentActivityProps {
|
interface RecentActivityProps {
|
||||||
activities: MirrorJob[];
|
activities: MirrorJob[];
|
||||||
@@ -17,11 +18,25 @@ export function RecentActivity({ activities }: RecentActivityProps) {
|
|||||||
</Button>
|
</Button>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<div className="flex flex-col divide-y divide-border">
|
{activities.length === 0 ? (
|
||||||
{activities.length === 0 ? (
|
<div className="flex flex-col items-center justify-center py-6 text-center">
|
||||||
<p className="text-sm text-muted-foreground">No recent activity</p>
|
<Clock className="h-10 w-10 text-muted-foreground mb-4" />
|
||||||
) : (
|
<h3 className="text-lg font-medium">No recent activity</h3>
|
||||||
activities.map((activity, index) => (
|
<p className="text-sm text-muted-foreground mt-1 mb-4">
|
||||||
|
Activity will appear here when you start mirroring repositories.
|
||||||
|
</p>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button variant="outline" size="sm" asChild>
|
||||||
|
<a href="/activity">
|
||||||
|
<Activity className="h-3.5 w-3.5 mr-1.5" />
|
||||||
|
View History
|
||||||
|
</a>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="flex flex-col divide-y divide-border">
|
||||||
|
{activities.map((activity, index) => (
|
||||||
<div key={index} className="flex items-center gap-x-3 py-3.5">
|
<div key={index} className="flex items-center gap-x-3 py-3.5">
|
||||||
<div className="relative flex-shrink-0">
|
<div className="relative flex-shrink-0">
|
||||||
<div
|
<div
|
||||||
@@ -39,9 +54,9 @@ export function RecentActivity({ activities }: RecentActivityProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))}
|
||||||
)}
|
</div>
|
||||||
</div>
|
)}
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user