Cleaning up some code

This commit is contained in:
2025-06-11 16:07:26 -05:00
parent ee6bede841
commit 185a7ea500
18 changed files with 101 additions and 830 deletions

View File

@ -1,11 +0,0 @@
import { SignUpCard } from './cards/SignUp';
export default function NoSession() {
return (
<div className='w-full mx-auto text-center pt-2 md:pt-10'>
<div className='mx-auto flex flex-col items-center justify-center'>
<SignUpCard />
</div>
</div>
);
}

View File

@ -92,30 +92,28 @@ export const ProfileCard = () => {
}
return (
<div className='max-w-2xl min-w-sm mx-auto p-4'>
<Card className='mb-8'>
<CardHeader className='pb-2'>
<CardTitle className='text-2xl'>Your Profile</CardTitle>
<CardDescription>
Manage your personal information and how it appears to others
</CardDescription>
</CardHeader>
{isLoading && !profile ? (
<div className='flex justify-center py-8'>
<Loader2 className='h-8 w-8 animate-spin text-gray-500' />
</div>
) : (
<div className='space-y-8'>
<AvatarUpload onAvatarUploaded={handleAvatarUploaded} />
<Separator />
<ProfileForm onSubmit={handleProfileSubmit} />
<Separator />
<ResetPasswordForm onSubmit={handleResetPasswordSubmit} />
<Separator />
<SignOut />
</div>
)}
</Card>
</div>
<Card className='max-w-2xl min-w-xs sm:min-w-md mx-auto mb-8'>
<CardHeader className='pb-2'>
<CardTitle className='text-2xl'>Your Profile</CardTitle>
<CardDescription>
Manage your personal information and how it appears to others
</CardDescription>
</CardHeader>
{isLoading && !profile ? (
<div className='flex justify-center py-8'>
<Loader2 className='h-8 w-8 animate-spin text-gray-500' />
</div>
) : (
<div className='space-y-8'>
<AvatarUpload onAvatarUploaded={handleAvatarUploaded} />
<Separator />
<ProfileForm onSubmit={handleProfileSubmit} />
<Separator />
<ResetPasswordForm onSubmit={handleResetPasswordSubmit} />
<Separator />
<SignOut />
</div>
)}
</Card>
);
};

View File

@ -86,7 +86,7 @@ export const SignInCard = () => {
<CardDescription className='text-foreground'>
Don&apos;t have an account?{' '}
<Link className='font-medium underline' href='/sign-up'>
Sign up
Sign Up
</Link>
</CardDescription>
</CardHeader>
@ -153,7 +153,7 @@ export const SignInCard = () => {
pendingText='Signing In...'
className='text-[1.0rem] cursor-pointer'
>
Sign in
Sign In
</SubmitButton>
</form>
</Form>

View File

@ -105,7 +105,7 @@ export const SignUpCard = () => {
<CardDescription className='text-foreground'>
Already have an account?{' '}
<Link className='text-primary font-medium underline' href='/sign-in'>
Sign in
Sign In
</Link>
</CardDescription>
</CardHeader>

View File

@ -1,4 +1,3 @@
export * from './NoSession';
export * from './buttons/SignInSignUp';
export * from './buttons/SignInWithApple';
export * from './buttons/SignInWithMicrosoft';

View File

@ -15,24 +15,25 @@ const Footer = () => {
flex items-center gap-2 transition-all duration-200'
>
<Image src='/icons/gitea.svg' alt='Gitea' width={20} height={20} />
<span>View Source Code on Gitea</span>
<span className='text-white'>View Source Code on Gitea</span>
</Link>
</div>
<div className='flex-1 flex justify-center'>
<div className='text-xs text-center space-y-1'>
<p>
<strong>Tech Tracker</strong> - Built for City of Gulfport IT Department
</p>
<div className='text-sm text-center space-y-1'>
<div className='flex my-auto'>
<Image
src='/favicon.png'
width={18}
height={15}
className='mr-1 mt-0.5'
alt='Tech Tracker Logo'
/>
<p>
<strong>Tech Tracker</strong> - City of Gulfport IT Department
</p>
</div>
<p className='text-muted-foreground'>
Open Source MIT Licensed Self-Hosted
<a
href='https://supabase.com'
target='_blank'
className='hover:underline ml-1'
rel='noreferrer'
>
Powered by Supabase
</a>
Open Source MIT Licensed Self-Hosted
</p>
</div>
</div>

View File

@ -12,14 +12,15 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui';
import { useAuth } from '@/components/context';
import { useAuth, useTVMode } from '@/components/context';
import { useRouter } from 'next/navigation';
import { signOut } from '@/lib/actions';
import { User } from 'lucide-react';
const AvatarDropdown = () => {
const { profile, avatarUrl, isLoading, refreshUserData } = useAuth();
const { profile, avatarUrl, refreshUserData } = useAuth();
const router = useRouter();
const { toggleTVMode, tvMode } = useTVMode();
const handleSignOut = async () => {
const result = await signOut();
@ -41,7 +42,7 @@ const AvatarDropdown = () => {
return (
<DropdownMenu>
<DropdownMenuTrigger>
<Avatar className='cursor-pointer'>
<Avatar className='cursor-pointer scale-125'>
{avatarUrl ? (
<AvatarImage
src={avatarUrl}
@ -50,19 +51,28 @@ const AvatarDropdown = () => {
height={64}
/>
) : (
<AvatarFallback className='text-sm'>
<AvatarFallback className='text-md'>
{profile?.full_name ? (
getInitials(profile.full_name)
) : (
<User size={32} />
<User size={64} />
)}
</AvatarFallback>
)}
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>{profile?.full_name}</DropdownMenuLabel>
<DropdownMenuLabel className='font-bold'>{profile?.full_name}</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem asChild>
<button
onClick={toggleTVMode}
className='w-full justify-center cursor-pointer'
>
{tvMode ? 'Normal Mode' : 'TV Mode'}
</button>
</DropdownMenuItem>
<DropdownMenuSeparator className='h-[2px]' />
<DropdownMenuItem asChild>
<Link
href='/profile'

View File

@ -1,17 +0,0 @@
'use client';
import AvatarDropdown from './AvatarDropdown';
import { SignInSignUp } from '@/components/default/auth';
import { useAuth } from '@/components/context';
const NavigationAuth = () => {
const { isAuthenticated } = useAuth();
return isAuthenticated ? (
<div className='flex items-center gap-4'>
<AvatarDropdown />
</div>
) : (
<SignInSignUp />
);
};
export default NavigationAuth;

View File

@ -2,23 +2,27 @@
import Image from 'next/image';
import Link from 'next/link';
import NavigationAuth from './auth';
import { ThemeToggle, TVToggle, useTVMode } from '@/components/context';
import { ThemeToggle, useTVMode } from '@/components/context';
import { useAuth } from '@/components/context';
import AvatarDropdown from './AvatarDropdown';
const Header = () => {
const { tvMode } = useTVMode();
const { isAuthenticated } = useAuth();
return tvMode ? (
<div className='absolute top-4 right-2'>
<div className='flex flex-row my-auto items-center pt-2 pr-0 md:pt-4'>
<TVToggle />
<div className='w-full py-2 pt-6 md:py-5'>
<div className='absolute top-8 right-24'>
<div className='flex flex-row my-auto items-center pt-2 pr-0 md:pt-4'>
{isAuthenticated && <AvatarDropdown />}
</div>
</div>
</div>
) : (
<header className='w-full py-2 pt-6 md:py-5'>
<div className='absolute top-4 right-6'>
<div className='absolute top-8 right-16'>
<div className='flex flex-row my-auto items-center pt-2 pr-0 md:pt-4 md:pr-8'>
<TVToggle />
<ThemeToggle className='mx-2' />
<ThemeToggle className='mr-4' />
{isAuthenticated && <AvatarDropdown />}
</div>
</div>
<Link
@ -36,7 +40,7 @@ const Header = () => {
/>
<h1
className='title-text text-sm md:text-4xl lg:text-8xl
bg-gradient-to-r from-[#bec8e6] via-[#F0EEE4] to-[#FFF8E7]
bg-gradient-to-r from-[#281A65] via-[#363354] to-accent-foreground dark:from-[#bec8e6] dark:via-[#F0EEE4] dark:to-[#FFF8E7]
font-bold pl-2 md:pl-12 text-transparent bg-clip-text'
>
Tech Tracker

View File

@ -1,126 +0,0 @@
'use client';
import * as Sentry from '@sentry/nextjs';
import { useState, useEffect } from 'react';
import {
Button,
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
Separator,
} from '@/components/ui';
import Link from 'next/link';
import { CheckCircle, MessageCircleWarning } from 'lucide-react';
class SentryExampleFrontendError extends Error {
constructor(message: string | undefined) {
super(message);
this.name = 'SentryExampleFrontendError';
}
}
export const TestSentryCard = () => {
const [hasSentError, setHasSentError] = useState(false);
const [isConnected, setIsConnected] = useState(true);
useEffect(() => {
const checkConnectivity = async () => {
console.log('Checking Sentry SDK connectivity...');
const result = await Sentry.diagnoseSdkConnectivity();
setIsConnected(result !== 'sentry-unreachable');
};
checkConnectivity().catch((error) => {
console.error('Error trying to connect to Sentry: ', error);
});
}, []);
const createError = async () => {
await Sentry.startSpan(
{
name: 'Example Frontend Span',
op: 'test',
},
async () => {
const res = await fetch('/api/sentry/example');
if (!res.ok) {
setHasSentError(true);
throw new SentryExampleFrontendError(
'This error is raised in our TestSentry component on the main page.',
);
}
},
);
};
return (
<Card>
<CardHeader>
<div className='flex flex-row my-auto space-x-4'>
<svg
height='40'
width='40'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M21.85 2.995a3.698 3.698 0 0 1 1.353 1.354l16.303 28.278a3.703 3.703 0 0 1-1.354 5.053 3.694 3.694 0 0 1-1.848.496h-3.828a31.149 31.149 0 0 0 0-3.09h3.815a.61.61 0 0 0 .537-.917L20.523 5.893a.61.61 0 0 0-1.057 0l-3.739 6.494a28.948 28.948 0 0 1 9.63 10.453 28.988 28.988 0 0 1 3.499 13.78v1.542h-9.852v-1.544a19.106 19.106 0 0 0-2.182-8.85 19.08 19.08 0 0 0-6.032-6.829l-1.85 3.208a15.377 15.377 0 0 1 6.382 12.484v1.542H3.696A3.694 3.694 0 0 1 0 34.473c0-.648.17-1.286.494-1.849l2.33-4.074a8.562 8.562 0 0 1 2.689 1.536L3.158 34.17a.611.611 0 0 0 .538.917h8.448a12.481 12.481 0 0 0-6.037-9.09l-1.344-.772 4.908-8.545 1.344.77a22.16 22.16 0 0 1 7.705 7.444 22.193 22.193 0 0 1 3.316 10.193h3.699a25.892 25.892 0 0 0-3.811-12.033 25.856 25.856 0 0 0-9.046-8.796l-1.344-.772 5.269-9.136a3.698 3.698 0 0 1 3.2-1.849c.648 0 1.285.17 1.847.495Z'
fill='currentcolor'
/>
</svg>
<CardTitle className='text-3xl my-auto'>Test Sentry</CardTitle>
</div>
<CardDescription className='text-[1.0rem]'>
Click the button below & view the sample error on{' '}
<Link
href={`${process.env.NEXT_PUBLIC_SENTRY_URL}`}
className='text-accent-foreground underline hover:text-primary'
>
the Sentry website
</Link>
. Navigate to the {"'"}Issues{"'"} page & you should see the sample
error!
</CardDescription>
</CardHeader>
<CardContent>
<div className='flex flex-row gap-4 my-auto'>
<Button
type='button'
onClick={createError}
className='cursor-pointer text-md my-auto py-6'
>
<span>Throw Sample Error</span>
</Button>
{hasSentError ? (
<div className='rounded-md bg-green-500/80 dark:bg-green-500/50 py-2 px-4 flex flex-row gap-2 my-auto'>
<CheckCircle size={30} className='my-auto' />
<p className='text-lg'>Sample error was sent to Sentry!</p>
</div>
) : !isConnected ? (
<div className='rounded-md bg-red-600/50 dark:bg-red-500/50 py-2 px-4 flex flex-row gap-2 my-auto'>
<MessageCircleWarning size={40} className='my-auto' />
<p>
Wait! The Sentry SDK is not able to reach Sentry right now -
this may be due to an adblocker. For more information, see{' '}
<Link
href='https://docs.sentry.io/platforms/javascript/guides/nextjs/troubleshooting/#the-sdk-is-not-sending-any-data'
className='text-accent-foreground underline hover:text-primary'
>
the troubleshooting guide.
</Link>
</p>
</div>
) : (
<div className='success_placeholder' />
)}
</div>
<Separator className='my-4 bg-accent' />
<p className='description'>
Warning! Sometimes Adblockers will prevent errors from being sent to
Sentry.
</p>
</CardContent>
</Card>
);
};

View File

@ -1 +0,0 @@
export { TestSentryCard } from './TestSentry';