Skip to content

Commit

Permalink
Some bug fixes, cleanup, UX perspective with glare for statistics.
Browse files Browse the repository at this point in the history
  • Loading branch information
xmliszt committed Feb 22, 2024
1 parent 96bac67 commit 56e74b5
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 27 deletions.
2 changes: 2 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
--input: 20 5.9% 90%;
--ring: 20 14.3% 4.1%;
--radius: 0.75rem;
--glare: 0 0% 0% / 5%;
}

.dark {
Expand All @@ -49,6 +50,7 @@
--border: 12 6.5% 15.1%;
--input: 12 6.5% 15.1%;
--ring: 24 5.7% 82.9%;
--glare: 360 100% 100% / 5%;
}
}

Expand Down
14 changes: 14 additions & 0 deletions app/level/[id]/ai-evaluation-loading-progress-bar.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
'use client';

import { useEffect, useRef, useState } from 'react';
import { useRouter } from 'next/navigation';

import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
} from '@/components/ui/alert-dialog';
import { Progress } from '@/components/ui/progress';
Expand All @@ -24,8 +27,10 @@ const AI_EVALUATION_LOADING_MESSAGES = [
];

export function AiEvaluationLoadingProgressBar(props: AIEvaluationLoadingProgressBarProps) {
const router = useRouter();
const [currentlyDisplayMessage, setCurrentlyDisplayMessage] = useState<string>('');
const intervalRef = useRef<number | null>(null);

useEffect(() => {
// Loop the messages
let index = 0;
Expand All @@ -48,6 +53,15 @@ export function AiEvaluationLoadingProgressBar(props: AIEvaluationLoadingProgres
</div>
</AlertDialogDescription>
<Progress value={(props.current / props.total) * 100} />
<AlertDialogFooter>
<AlertDialogCancel
onClick={() => {
router.push('/levels');
}}
>
Cancel and exit
</AlertDialogCancel>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
Expand Down
46 changes: 32 additions & 14 deletions app/level/[id]/level-page-client-wrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Progress } from '@/components/ui/progress';
import { CONSTANTS } from '@/lib/constants';
import { tryParseErrorAsGoogleAIError } from '@/lib/errors/google-ai-error-parser';
import { HASH } from '@/lib/hash';
import { getPersistence, setPersistence } from '@/lib/persistence/persistence';
import { fetchWord } from '@/lib/services/wordService';
Expand Down Expand Up @@ -254,15 +255,28 @@ export function LevelPageClientWrapper(props: LevelWordsProviderProps) {
setConversation(newConversation);
} catch (error) {
console.error(error);
setConversation([
...inputConversation,
{
role: 'error',
content:
"Oops! I encountered a technical issue and I'm unable to continue the conversation right now. Please try again later!",
timestamp: new Date().toISOString(),
},
]);
try {
const googleError = tryParseErrorAsGoogleAIError(error, 'conversation');
setConversation([
...inputConversation,
{
role: 'error',
content: googleError.message,
timestamp: new Date().toISOString(),
},
]);
} catch (error) {
console.error(error);
setConversation([
...inputConversation,
{
role: 'error',
content:
"Oops! I encountered a technical issue and I'm unable to continue the conversation right now. Please try again later!",
timestamp: new Date().toISOString(),
},
]);
}
} finally {
setIsWaitingForAIResponse(false);
setIsLoading(false);
Expand Down Expand Up @@ -422,9 +436,13 @@ export function LevelPageClientWrapper(props: LevelWordsProviderProps) {
confirmAlert({
title: 'Something went wrong!',
description: 'Something went wrong during our evaluation process. Please try again.',
cancelLabel: 'Try again',
hasConfirmButton: false,
onCancel: startEvaluationAndUpload,
cancelLabel: 'Cancel and exit',
confirmLabel: 'Try again',
hasConfirmButton: true,
onCancel: () => {
router.push('/levels');
},
onConfirm: startEvaluationAndUpload,
});
}
});
Expand Down Expand Up @@ -481,7 +499,7 @@ export function LevelPageClientWrapper(props: LevelWordsProviderProps) {
{isCountingDown ? (
<div
className={cn(
'fixed top-1/2 z-50 w-full animate-bounce text-center',
'fixed top-1/2 z-50 w-full animate-ping text-center',
countdown.time === 0
? 'text-6xl'
: countdown.time === 1
Expand All @@ -496,7 +514,7 @@ export function LevelPageClientWrapper(props: LevelWordsProviderProps) {
{countdown.time === 0 ? 'Start' : countdown.time === -1 ? '' : countdown.time}
</div>
) : isGeneratingVariations ? (
<div className='fixed top-1/2 z-50 w-full animate-bounce text-center text-3xl'>
<div className='fixed top-1/2 z-50 w-full animate-pulse text-center text-3xl'>
{renderWaitingMessageForVariations()}
</div>
) : (
Expand Down
8 changes: 4 additions & 4 deletions app/profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ export default async function ProfilePage() {
<Suspense fallback={<Skeleton className='h-[350px] w-full' numberOfRows={12} />}>
<ProfilePlayedTopicScrollView />
</Suspense>
<Suspense fallback={<Skeleton className='h-[350px] w-full' numberOfRows={12} />}>
<Suspense fallback={<Skeleton className='h-[500px] w-full' numberOfRows={12} />}>
<ProfileStatisticsCardView />
</Suspense>
<ProfilePrivacySettingsCard className='w-full max-w-[500px]' user={user} />
<ProfileSubscriptionCard className='w-full max-w-[500px]' user={user} />
<ProfileDangerZone className='w-full max-w-[500px]' user={user} />
<ProfilePrivacySettingsCard className='w-full' user={user} />
<ProfileSubscriptionCard className='w-full' user={user} />
<ProfileDangerZone className='w-full' user={user} />
<ProfileFeedbackFloatingButton user={user} />
</ProfileScrollControl>
);
Expand Down
2 changes: 1 addition & 1 deletion app/profile/profile-scroll-control.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function ProfileScrollControl(props: ProfileScrollControlProps) {

return (
<main className='flex flex-col items-center gap-16 bg-background px-10 py-8 text-foreground'>
{props.children}
<div className='flex max-w-xl flex-col items-center gap-16'>{props.children}</div>
</main>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,6 @@ export async function ProfileStatisticsCardView() {
})()}
titleFontSize='text-4xl'
/>
<ProfileStatisticsSimpleCardView
key='coming-soon'
title='Stay tuned...'
value='More stats coming soon!'
/>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
'use client';

import { useRef } from 'react';
import Link from 'next/link';

import { Button } from '@/components/ui/button';
Expand All @@ -19,12 +22,35 @@ export function ProfileStatisticsSimpleCardView({
href,
titleFontSize,
}: ProfileStatisticsSimpleCardProps) {
const boundingRef = useRef<DOMRect | null>(null);
return (
<div
className={cn(
'relative flex snap-center flex-col gap-2 rounded-lg border p-4 leading-snug',
'min-h-[150px] w-full min-w-[250px] lg:w-fit lg:min-w-[150px]'
'group relative flex snap-center flex-col gap-2 rounded-lg border p-4 leading-snug',
'min-h-[150px] w-full min-w-[250px] shrink grow lg:w-fit lg:min-w-[150px]',
'transform transition-[transoform_border_box-shadow] duration-300 ease-out hover:scale-105 hover:border-primary hover:shadow-lg'
)}
onMouseEnter={(event) => {
boundingRef.current = event.currentTarget.getBoundingClientRect();
}}
onMouseLeave={(event) => {
boundingRef.current = null;
// Restore rotation
event.currentTarget.style.transform = '';
}}
onMouseMove={(event) => {
if (!boundingRef.current) return;
const x = event.clientX - boundingRef.current.left;
const y = event.clientY - boundingRef.current.top;
const xPercentage = x / boundingRef.current.width;
const yPercentage = y / boundingRef.current.height;
const xRotation = (xPercentage - 0.5) * 20;
const yRotation = (0.5 - yPercentage) * -20;
event.currentTarget.style.transform = `perspective(1000px) rotateX(${yRotation}deg) rotateY(${xRotation}deg)`;
// set glare x, y position
event.currentTarget.style.setProperty('--x', `${xPercentage * 100}%`);
event.currentTarget.style.setProperty('--y', `${yPercentage * 100}%`);
}}
>
<div className='text-xs italic text-muted-foreground'>{title}</div>
<div
Expand All @@ -42,6 +68,7 @@ export function ProfileStatisticsSimpleCardView({
</Button>
</Link>
)}
<div className='pointer-events-none absolute inset-0 group-hover:bg-[radial-gradient(at_var(--x)_var(--y),hsl(var(--glare))_20%,transparent_80%)]'></div>
</div>
);
}
2 changes: 1 addition & 1 deletion components/custom/skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ interface SkeletonProps {
export function Skeleton({
hasHeaderRow = true,
numberOfRows = 3,
className = 'w-full',
className = 'w-full max-w-xl',
}: SkeletonProps) {
const renderRows = () => {
const rows: React.ReactElement[] = [];
Expand Down

0 comments on commit 56e74b5

Please sign in to comment.