From 7ebbc5e5e5739f647bf8bd2a6835c4f9569bd7f4 Mon Sep 17 00:00:00 2001 From: Jocelyn Facchini Date: Fri, 20 Jun 2025 15:11:53 +0100 Subject: [PATCH 1/5] Change user data to be a fake API --- README.md | 5 +- src/App.test.tsx | 6 +++ src/api/companyData.ts | 87 +++++++++++++++++++++++++++++++++++ src/{data => api}/userData.ts | 18 +++++++- 4 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 src/api/companyData.ts rename src/{data => api}/userData.ts (90%) diff --git a/README.md b/README.md index 5da9a13..b1dc2c8 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,9 @@ Don't be afraid to ask questions, and do communicate your thinking. ## Goal -Test-drive a component that can take in data, and render it as a table. +Test-drive a component that can take in arbitrary data and render it as a table. Use `./design.png` as a reference. You don't need to worry about styling to begin with. -`./src/data/userData.ts` contains example data that should be rendered. +`./src/api/userData.ts` contains a fake API via the method `getUserData`, you will be able to look at the +shape of the data as described by the interface `UserData`. diff --git a/src/App.test.tsx b/src/App.test.tsx index 42eb75a..9cabcab 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,9 +1,15 @@ import React from 'react'; import { render, screen } from '@testing-library/react'; import App from './App'; +import {getCompanyData} from "./api/companyData"; +import {getUserData} from "./api/userData"; test('renders hello world', () => { render(); const heading = screen.getByRole('heading', { name: /hello world/i }); expect(heading).toBeInTheDocument(); }); + +test('', () => { + getUserData().then(console.log); +}) \ No newline at end of file diff --git a/src/api/companyData.ts b/src/api/companyData.ts new file mode 100644 index 0000000..a951e03 --- /dev/null +++ b/src/api/companyData.ts @@ -0,0 +1,87 @@ +export interface CompanyData { + name: string; + address: string; + phoneNumber: string +} + +const companyData: CompanyData[] = [ + { + name: 'Innovate Solutions Ltd.', + address: '123 Innovation Drive, Tech Park, Reading, RG2 6GF', + phoneNumber: '0118 496 0123', + }, + { + name: 'Apex Industries PLC', + address: '45 Apex Tower, Canary Wharf, London, E14 5NP', + phoneNumber: '020 7946 0456', + }, + { + name: 'QuantumLeap Analytics', + address: '789 Science Park, Cambridge, CB4 0WZ', + phoneNumber: '01223 496 0789', + }, + { + name: 'Starlight Retail Group', + address: '321 High Street, Manchester, M1 1AA', + phoneNumber: '0161 496 0321', + }, + { + name: 'Evergreen Logistics', + address: '56 Logistics Way, Magna Park, Lutterworth, LE17 4XN', + phoneNumber: '01455 496 0567', + }, + { + name: 'Pinnacle Construction', + address: '89 Builders Lane, Birmingham, B2 4DT', + phoneNumber: '0121 496 0890', + }, + { + name: 'Serenity Health & Wellness', + address: '10 Serene Avenue, Bath, BA1 1SU', + phoneNumber: '01225 496 0101', + }, + { + name: 'Fusion Digital Marketing', + address: '24 Digital Road, Shoreditch, London, EC1V 9DD', + phoneNumber: '020 7946 0245', + }, + { + name: 'Silverstream Financials', + address: '1 City Square, Leeds, LS1 2ES', + phoneNumber: '0113 496 0112', + }, + { + name: 'Bluebird Creative Agency', + address: '67 Creative Quarter, Bristol, BS1 6EA', + phoneNumber: '0117 496 0678', + }, + { + name: 'Oakwood Property Management', + address: '90 Property Point, Edinburgh, EH2 4DL', + phoneNumber: '0131 496 0901', + }, + { + name: 'Momentum Manufacturing', + address: '15 Industrial Estate, Coventry, CV1 2WT', + phoneNumber: '024 7649 6015', + }, + { + name: 'Golden Key Hospitality', + address: '7 Hospitality Hub, York, YO1 7JF', + phoneNumber: '01904 496 0077', + }, + { + name: 'Nexus Data Systems', + address: '33 Data Drive, Milton Keynes, MK9 2FN', + phoneNumber: '01908 496 0330', + }, + { + name: 'First-Rate Foods Distribution', + address: '88 Distribution Way, Glasgow, G1 1XQ', + phoneNumber: '0141 496 0888', + }, +]; + +export async function getCompanyData(): Promise { + return companyData; +} \ No newline at end of file diff --git a/src/data/userData.ts b/src/api/userData.ts similarity index 90% rename from src/data/userData.ts rename to src/api/userData.ts index a9ae232..e7a8873 100644 --- a/src/data/userData.ts +++ b/src/api/userData.ts @@ -1,4 +1,4 @@ -interface UserData { +export interface UserData { id: string; firstName: string; lastName: string; @@ -8,7 +8,7 @@ interface UserData { rating: number; } -export const userData: UserData[] = [ +const userData: UserData[] = [ { id: '9da70cb8-4d17-4d79-ae93-8b6c47662c2c', firstName: 'Quinta', @@ -190,3 +190,17 @@ export const userData: UserData[] = [ rating: 1, }, ]; + +function shuffleArray(array: T[]): T[] { + for (let i = array.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [array[i], array[j]] = [array[j], array[i]]; + } + return array; +} + +// MOCK User API, this will simulate returning different results +// as if the data is evolving +export async function getUserData(): Promise { + return shuffleArray(userData); +} From ba52fabd93f2775abec35bc5b62e0792c017d95d Mon Sep 17 00:00:00 2001 From: Jocelyn Facchini Date: Fri, 20 Jun 2025 15:13:43 +0100 Subject: [PATCH 2/5] Add prettier for those not using vscode --- package-lock.json | 16 ++++++++++++++++ package.json | 1 + 2 files changed, 17 insertions(+) diff --git a/package-lock.json b/package-lock.json index 78b5a64..6a934bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ "@types/node": "^16.18.23", "@types/react": "^18.0.33", "@types/react-dom": "^18.0.11", + "prettier": "^3.5.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", @@ -13696,6 +13697,21 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", diff --git a/package.json b/package.json index 29f2b1c..cc8e859 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "@types/node": "^16.18.23", "@types/react": "^18.0.33", "@types/react-dom": "^18.0.11", + "prettier": "^3.5.3", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", From ac254c8a82ca4f564057ad4fecddf7c0f73ab2f8 Mon Sep 17 00:00:00 2001 From: Jocelyn Facchini Date: Fri, 20 Jun 2025 15:14:56 +0100 Subject: [PATCH 3/5] Revert test --- src/App.test.tsx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/App.test.tsx b/src/App.test.tsx index 9cabcab..206c153 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,15 +1,9 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import App from './App'; -import {getCompanyData} from "./api/companyData"; -import {getUserData} from "./api/userData"; +import React from "react"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; -test('renders hello world', () => { +test("renders hello world", () => { render(); - const heading = screen.getByRole('heading', { name: /hello world/i }); + const heading = screen.getByRole("heading", { name: /hello world/i }); expect(heading).toBeInTheDocument(); }); - -test('', () => { - getUserData().then(console.log); -}) \ No newline at end of file From d340350402ff8f597b51ee21279e4a9e88013506 Mon Sep 17 00:00:00 2001 From: Jocelyn Facchini Date: Fri, 20 Jun 2025 15:22:03 +0100 Subject: [PATCH 4/5] Adapt prettier to current style --- package.json | 3 +++ src/App.test.tsx | 10 +++++----- src/index.tsx | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index cc8e859..564eaa2 100644 --- a/package.json +++ b/package.json @@ -40,5 +40,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "prettier": { + "singleQuote": true } } diff --git a/src/App.test.tsx b/src/App.test.tsx index 206c153..42eb75a 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,9 +1,9 @@ -import React from "react"; -import { render, screen } from "@testing-library/react"; -import App from "./App"; +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import App from './App'; -test("renders hello world", () => { +test('renders hello world', () => { render(); - const heading = screen.getByRole("heading", { name: /hello world/i }); + const heading = screen.getByRole('heading', { name: /hello world/i }); expect(heading).toBeInTheDocument(); }); diff --git a/src/index.tsx b/src/index.tsx index 1fd12b7..56a5fca 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,10 +4,10 @@ import './index.css'; import App from './App'; const root = ReactDOM.createRoot( - document.getElementById('root') as HTMLElement + document.getElementById('root') as HTMLElement, ); root.render( - + , ); From 3d77983133af4cc12a732d8772909ecf5abaeddd Mon Sep 17 00:00:00 2001 From: Jocelyn Facchini Date: Fri, 20 Jun 2025 15:23:18 +0100 Subject: [PATCH 5/5] Fix style --- src/api/companyData.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/api/companyData.ts b/src/api/companyData.ts index a951e03..3804c8a 100644 --- a/src/api/companyData.ts +++ b/src/api/companyData.ts @@ -1,7 +1,7 @@ export interface CompanyData { name: string; address: string; - phoneNumber: string + phoneNumber: string; } const companyData: CompanyData[] = [ @@ -84,4 +84,4 @@ const companyData: CompanyData[] = [ export async function getCompanyData(): Promise { return companyData; -} \ No newline at end of file +}