Skip to content
This repository has been archived by the owner on Feb 3, 2025. It is now read-only.

Commit

Permalink
feat: add detail page
Browse files Browse the repository at this point in the history
  • Loading branch information
irfan-maulana-tkp committed Oct 1, 2020
1 parent 97af15e commit cb367a0
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 31 deletions.
70 changes: 70 additions & 0 deletions components/CardDetail.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { getPerfColorClass, getLCPColorClass, getFIDColorClass, getCLSColorClass } from '../utils/getColorClass';

const CardDetail = ({ data, title }): React.ReactElement => {
return (
<div className="mt-4 p-4 bg-white shadow overflow-hidden rounded-lg">
<div className="flex justify-center space-between">
<div className="text-gray-600 my-2 mr-2">
<small className="text-sm font-bold">{title}</small>
<div className={`text-5xl font-bold capitalize ${getPerfColorClass(data.perf)}`}>
{(data.perf * 100).toFixed(0)}
</div>
</div>
</div>

<div className="flex justify-center space-between my-2">
<div className="w-20 my-2 mr-4 text-center">
<small className="text-sm text-blue-400 font-bold">LCP</small>
<div className="text-center">
<span className={`text-3xl text-gray-600 font-bold capitalize ${getLCPColorClass(data.lcp)}`}>
{(data.lcp / 1000).toFixed(2)}
</span>
<small className="text-lg font-bold text-gray-600 ml-1">s</small>
</div>
</div>
<div className="w-20 my-2 mr-4 text-center">
<small className="text-sm text-blue-400 font-bold">FID</small>
<div className="text-center">
<span className={`text-3xl text-gray-600 font-bold capitalize ${getFIDColorClass(data.fid)}`}>
{data.fid.toFixed(0)}
</span>
<small className="text-lg font-bold text-gray-600 ml-1">ms</small>
</div>
</div>
<div className="w-20 my-2 mr-4 text-center">
<small className="text-sm text-blue-400 font-bold">CLS</small>
<div className={`text-3xl text-gray-600 font-bold capitalize ${getCLSColorClass(data.cls)}`}>
{data.cls.toFixed(2)}
</div>
</div>
</div>

<div className="flex justify-center space-between my-2">
<div className="w-20 my-2 mr-4 text-center">
<small className="text-sm text-blue-400 font-bold">TBT</small>
<div className="text-center">
<span className={`text-3xl text-gray-600 font-bold capitalize`}>{(data.tbt / 1000).toFixed(2)}</span>
<small className="text-lg font-bold text-gray-600 ml-1">s</small>
</div>
</div>
<div className="w-20 my-2 mr-4 text-center">
<small className="text-sm text-blue-400 font-bold">FCP</small>
<div className="text-center">
<span className={`text-3xl text-gray-600 font-bold capitalize`}>{(data.fcp / 1000).toFixed(2)}</span>
<small className="text-lg font-bold text-gray-600 ml-1">s</small>
</div>
</div>
<div className="w-20 my-2 mr-4 text-center">
<small className="text-sm text-blue-400 font-bold">TTI</small>
<div className="text-center">
<span className={`text-3xl text-gray-600 font-bold capitalize`}>{(data.tti / 1000).toFixed(2)}</span>
<small className="text-lg font-bold text-gray-600 ml-1">s</small>
</div>
</div>
</div>
</div>
);
};

export default CardDetail;
File renamed without changes.
2 changes: 1 addition & 1 deletion cronjob/lh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default async (name: string, url: string, device: string): Promise<LHResp

const perf = categories?.performance?.score || 0;
const req = totalResources.requestCount || 0;
const size = totalResources.size || 0;
const size = totalResources.size || totalResources.transferSize || 0;

const response: LHResponse = {
perf,
Expand Down
2 changes: 1 addition & 1 deletion cronjob/run.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Table from 'cli-table3';

import data from './ecommerce';
import data from '../constants/ecommerce';
import runLH from './lh';
import { updateReport } from './report';
import { EcommerceItem } from '../types';
Expand Down
4 changes: 2 additions & 2 deletions cronjob/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export default function sortAsc(arr: any[], key: string): any[] {
return arr.sort((a, b) => a - b);
}

const _quantile = (sorted: any[], q: number) => {
const _quantile = (sorted: any[], q: number): any => {
const pos = (sorted.length - 1) * q;
const base = Math.floor(pos);
const rest = pos - base;
Expand All @@ -14,7 +14,7 @@ const _quantile = (sorted: any[], q: number) => {
}
};

export function quantile(arr: any[], q: number, key: string) {
export function quantile(arr: any[], q: number, key: string): any {
const sorted = sortAsc(arr, key);
const sortOnlyValue = sorted.map((i) => i[key]);
const res = _quantile(sortOnlyValue, q);
Expand Down
40 changes: 40 additions & 0 deletions pages/[id].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import { GetStaticProps, GetStaticPaths } from 'next';

import Layout from '../components/Layout';
import CardDetail from '../components/CardDetail';

import reports from '../reports/output';
import dataEcommerce from '../constants/ecommerce';
import { EcommerceItem } from '../types';

const DetailPage = ({ data, lastUpdate }): React.ReactElement => {
return (
<Layout>
<h1 className="text-3xl font-bold capitalize">Web Performance: {data.n}</h1>
<small className="text-gray-600 text-lg font-bold">Last update {lastUpdate}</small>

<CardDetail data={data.d} title="Desktop" />
<CardDetail data={data.m} title="Mobile" />
</Layout>
);
};

export const getStaticPaths: GetStaticPaths = async () => {
const paths = dataEcommerce.map((i: EcommerceItem) => `/${i.name.toLowerCase()}`);

return { paths, fallback: false };
};

export const getStaticProps: GetStaticProps = async ({ params }) => {
const id: string = params ? `${params.id}` : '';

const reportDates = Object.keys(reports) || [];
const lastDate = reportDates[reportDates.length - 1] || '';
const lastReport = reports[lastDate] || [];
const data = lastReport.length > 0 ? lastReport.find((item) => item.n.toLowerCase() === id.toLowerCase()) : {};

return { props: { data, lastUpdate: lastDate } };
};

export default DetailPage;
49 changes: 22 additions & 27 deletions pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,9 @@
import React from 'react';
// import Link from 'next/link';
import Link from 'next/link';

import Layout from '../components/Layout';
import reports from '../reports/output';

const getColorClass = (value): string => {
if (value <= 0.49) {
return 'text-red-600';
}
if (value <= 0.89) {
return 'text-orange-500';
}

return 'text-green-500';
};
import { getPerfColorClass } from '../utils/getColorClass';

const Home = (): React.ReactElement => {
const reportDates = Object.keys(reports) || [];
Expand All @@ -25,23 +16,27 @@ const Home = (): React.ReactElement => {
<h3 className="text-gray-900 text-xl font-bold">Last update {lastDate}</h3>

{lastReportSorted.map((item) => (
<div key={item.n} className="mt-4 p-4 bg-white shadow overflow-hidden rounded-lg">
<h3 className="text-3xl font-bold capitalize">{item.n}</h3>
<div className="flex justify-start">
<div className="text-gray-400 my-2 mr-2">
<small className="text-sm font-bold">Desktop</small>
<div className={`text-5xl font-bold capitalize ${getColorClass(item.d.perf)}`}>
{(item.d.perf * 100).toFixed(0)}
</div>
</div>
<div className="text-gray-400 my-2 ml-2">
<small className="text-sm font-bold">Mobile</small>
<div className={`text-5xl font-bold capitalize ${getColorClass(item.m.perf)}`}>
{(item.m.perf * 100).toFixed(0)}
<Link href={`/${item.n.toLowerCase()}`} key={item.n}>
<a href={`/${item.n.toLowerCase()}`}>
<div className="mt-4 p-4 bg-white shadow overflow-hidden rounded-lg">
<h3 className="text-3xl font-bold capitalize">{item.n}</h3>
<div className="flex justify-start">
<div className="text-gray-600 my-2 mr-2">
<small className="text-sm font-bold">Desktop</small>
<div className={`text-5xl font-bold capitalize ${getPerfColorClass(item.d.perf)}`}>
{(item.d.perf * 100).toFixed(0)}
</div>
</div>
<div className="text-gray-600 my-2 ml-2">
<small className="text-sm font-bold">Mobile</small>
<div className={`text-5xl font-bold capitalize ${getPerfColorClass(item.m.perf)}`}>
{(item.m.perf * 100).toFixed(0)}
</div>
</div>
</div>
</div>
</div>
</div>
</a>
</Link>
))}
</Layout>
);
Expand Down
34 changes: 34 additions & 0 deletions utils/getColorClass.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const getPerfColorClass = (value: number): string => {
if (value <= 0.49) {
return 'text-red-600';
}
if (value <= 0.89) {
return 'text-orange-500';
}

return 'text-green-500';
};

export const getWebVitalColorClass = (value: number, good: number, avg: number): string => {
if (value <= good) {
return 'text-green-500';
}

if (value <= avg) {
return 'text-orange-500';
}

return 'text-red-600';
};

export const getLCPColorClass = (value: number): string => {
return getWebVitalColorClass(value, 2500, 4000);
};

export const getFIDColorClass = (value: number): string => {
return getWebVitalColorClass(value, 100, 300);
};

export const getCLSColorClass = (value: number): string => {
return getWebVitalColorClass(value, 0.1, 0.25);
};

1 comment on commit cb367a0

@vercel
Copy link

@vercel vercel bot commented on cb367a0 Oct 1, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.