Skip to content

Commit

Permalink
feat: ✨ added skeleton when results page loading (#41)
Browse files Browse the repository at this point in the history
  • Loading branch information
WasiqB authored Oct 6, 2024
1 parent bf572e2 commit 206581f
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 47 deletions.
56 changes: 56 additions & 0 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Code Style and Structure:

- Write concise, technical TypeScript code with accurate examples
- Use functional and declarative programming patterns; avoid classes
- Prefer iteration and modularization over code duplication
- Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
- Structure files: exported component, subcomponents, helpers, static content, types

Naming Conventions:

- Use lowercase with dashes for directories (e.g., components/auth-wizard)
- Favor named exports for components

TypeScript Usage:

- Use TypeScript for all code; prefer interfaces over types
- Avoid enums; use maps instead
- Use functional components with TypeScript interfaces

Syntax and Formatting:

- Use the "function" keyword for pure functions
- Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements
- Use declarative JSX

Error Handling and Validation:

- Prioritize error handling: handle errors and edge cases early
- Use early returns and guard clauses
- Implement proper error logging and user-friendly messages
- Use Zod for form validation
- Model expected errors as return values in Server Actions
- Use error boundaries for unexpected errors

UI and Styling:

- Use Shadcn UI, Daisy UI, Magic UI, Radix, and Tailwind Aria for components and styling
- Implement responsive design with Tailwind CSS; use a mobile-first approach

Performance Optimization:

- Minimize 'use client', 'useEffect', and 'setState'; favor React Server Components (RSC)
- Wrap client components in Suspense with fallback
- Use dynamic loading for non-critical components
- Optimize images: use WebP format, include size data, implement lazy loading

Key Conventions:

- Use 'nuqs' for URL search parameter state management
- Optimize Web Vitals (LCP, CLS, FID)
- Limit 'use client':
- Favor server components and Next.js SSR
- Use only for Web API access in small components
- Avoid for data fetching or state management

Follow Next.js docs for Data Fetching, Rendering, and Routing
118 changes: 71 additions & 47 deletions app/(app)/results/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use client';

import * as React from 'react';
import { useState, useEffect } from 'react';
import { FormattedData } from '@/types/types';
import {
Expand All @@ -15,12 +16,14 @@ import {
CardHeader,
CardTitle,
} from '@/components/ui/card';
import { Skeleton } from '@/components/ui/skeleton';
import { ChartConfig } from '@/components/ui/chart';
import DoughNutComponent from '@/components/charts/dough-nut-chart';
import { TestResultData, getFormattedData } from '@/components/data-table/data';
import { columns } from '@/components/data-table/columns';
import { PieComponent } from '@/components/charts/pie-chart';
import { NavBar } from '@/components/home/nav-bar';
import { cn } from '@/lib/utils';

const chartConfig: ChartConfig = {
total: {
Expand Down Expand Up @@ -50,6 +53,7 @@ const ResultsPage = (): JSX.Element => {
const [columnVisibility, setColumnVisibility] = useState<VisibilityState>({});
const [result, setResult] = useState<TestResultData[]>([]);
const [formattedData, setFormattedData] = useState<FormattedData>();
const [isLoading, setIsLoading] = useState(true);

useEffect(() => {
const resultData = localStorage.getItem('json-data') as string;
Expand All @@ -58,6 +62,7 @@ const ResultsPage = (): JSX.Element => {
setResult(testResult);
setFormattedData(getFormattedData(testResult));
}
setIsLoading(false);
}, []);

const {
Expand All @@ -72,7 +77,11 @@ const ResultsPage = (): JSX.Element => {

return (
<div className='flex min-h-screen flex-col'>
<NavBar suffix={`for ${date}`} cta='Generate new Report' showFeedback />
<NavBar
suffix={`for ${isLoading ? '...' : date}`}
cta='Generate new Report'
showFeedback
/>
<main className='flex-grow pt-16'>
<section className='container mx-auto space-y-6 p-4'>
<div className='grid grid-cols-1 gap-6'>
Expand All @@ -85,53 +94,68 @@ const ResultsPage = (): JSX.Element => {
</CardHeader>
<CardContent>
<div className='grid grid-cols-2 gap-4 md:grid-cols-4'>
<Card className='rounded-lg bg-blue-200 p-4'>
<CardDescription>Total Tests</CardDescription>
<CardTitle className='text-blue-700'>
{totalTests}
</CardTitle>
</Card>
<Card className='rounded-lg bg-green-200 p-4'>
<CardDescription>Passed</CardDescription>
<CardTitle className='text-green-700'>{passed}</CardTitle>
</Card>
<Card className='rounded-lg bg-red-200 p-4'>
<CardDescription>Failed</CardDescription>
<CardTitle className='text-red-700'>{failed}</CardTitle>
</Card>
<Card className='rounded-lg bg-yellow-200 p-4'>
<CardDescription>Skipped</CardDescription>
<CardTitle className='text-yellow-700'>{skipped}</CardTitle>
</Card>
{['Total Tests', 'Passed', 'Failed', 'Skipped'].map(
(label, index) => (
<Card
key={label}
className={cn(
'rounded-lg p-4',
`${['bg-blue-200', 'bg-green-200', 'bg-red-200', 'bg-yellow-200'][index]}`
)}
>
<CardDescription>{label}</CardDescription>
{isLoading ? (
<Skeleton className='h-8 w-20' />
) : (
<CardTitle
className={`text-${['blue', 'green', 'red', 'yellow'][index]}-700`}
>
{[totalTests, passed, failed, skipped][index]}
</CardTitle>
)}
</Card>
)
)}
</div>
</CardContent>
</Card>
</div>
<div className='grid grid-cols-1 gap-6 md:grid-cols-2'>
<DoughNutComponent
title='Test Summary Counts'
description='Status based distribution of Test results'
config={chartConfig}
data={chartCountData || []}
totalValue={totalTests || 0}
valueLabel='Test cases'
/>
<PieComponent
title='Test Summary %'
description='Status based % distribution of Test results'
config={chartConfig}
data={chartPieData || []}
/>
{isLoading ? (
<>
<Skeleton className='h-[300px] w-full' />
<Skeleton className='h-[300px] w-full' />
</>
) : (
<>
<DoughNutComponent
title='Test Summary Counts'
description='Status based distribution of Test results'
config={chartConfig}
data={chartCountData || []}
totalValue={totalTests || 0}
valueLabel='Test cases'
/>
<PieComponent
title='Test Summary %'
description='Status based % distribution of Test results'
config={chartConfig}
data={chartPieData || []}
/>
</>
)}
</div>
{result ? (
<Card>
<CardHeader>
<CardTitle className='text-xl'>Test Details</CardTitle>
<CardDescription>
List of all the executed test cases
</CardDescription>
</CardHeader>
<CardContent>
<Card>
<CardHeader>
<CardTitle className='text-xl'>Test Details</CardTitle>
<CardDescription>
List of all the executed test cases
</CardDescription>
</CardHeader>
<CardContent>
{isLoading ? (
<Skeleton className='h-[400px] w-full' />
) : result ? (
<DataTable
columns={columns}
data={result}
Expand All @@ -143,11 +167,11 @@ const ResultsPage = (): JSX.Element => {
setColumnVisibility={setColumnVisibility}
setSorting={setSorting}
/>
</CardContent>
</Card>
) : (
<p className='text-center'>No data available</p>
)}
) : (
<p className='text-center'>No data available</p>
)}
</CardContent>
</Card>
</section>
</main>
</div>
Expand Down

0 comments on commit 206581f

Please sign in to comment.