Skip to content

Commit f535c37

Browse files
authored
Update the Learn codebase (#764)
1 parent 9daf946 commit f535c37

27 files changed

+1054
-6671
lines changed

.nvmrc

-1
This file was deleted.

dashboard/final-example/.eslintrc.json

-3
This file was deleted.

dashboard/final-example/.nvmrc

-1
This file was deleted.

dashboard/final-example/app/dashboard/layout.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import SideNav from '@/app/ui/dashboard/sidenav';
22

3-
export const experimental_ppr = true;
4-
53
export default function Layout({ children }: { children: React.ReactNode }) {
64
return (
75
<div className="flex h-screen flex-col md:flex-row md:overflow-hidden">

dashboard/final-example/app/lib/data.ts

-10
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,8 @@ import {
88
Revenue,
99
} from './definitions';
1010
import { formatCurrency } from './utils';
11-
import { unstable_noStore as noStore } from 'next/cache';
1211

1312
export async function fetchRevenue() {
14-
// Add noStore() here to prevent the response from being cached.
15-
// This is equivalent to in fetch(..., {cache: 'no-store'}).
16-
noStore();
1713
try {
1814
// Artificially delay a response for demo purposes.
1915
// Don't do this in production :)
@@ -33,7 +29,6 @@ export async function fetchRevenue() {
3329
}
3430

3531
export async function fetchLatestInvoices() {
36-
noStore();
3732
try {
3833
const data = await sql<LatestInvoiceRaw>`
3934
SELECT invoices.amount, customers.name, customers.image_url, customers.email, invoices.id
@@ -54,7 +49,6 @@ export async function fetchLatestInvoices() {
5449
}
5550

5651
export async function fetchCardData() {
57-
noStore();
5852
try {
5953
// You can probably combine these into a single SQL query
6054
// However, we are intentionally splitting them to demonstrate
@@ -94,7 +88,6 @@ export async function fetchFilteredInvoices(
9488
query: string,
9589
currentPage: number,
9690
) {
97-
noStore();
9891
const offset = (currentPage - 1) * ITEMS_PER_PAGE;
9992

10093
try {
@@ -127,7 +120,6 @@ export async function fetchFilteredInvoices(
127120
}
128121

129122
export async function fetchInvoicesPages(query: string) {
130-
noStore();
131123
try {
132124
const count = await sql`SELECT COUNT(*)
133125
FROM invoices
@@ -149,7 +141,6 @@ export async function fetchInvoicesPages(query: string) {
149141
}
150142

151143
export async function fetchInvoiceById(id: string) {
152-
noStore();
153144
try {
154145
const data = await sql<InvoiceForm>`
155146
SELECT
@@ -193,7 +184,6 @@ export async function fetchCustomers() {
193184
}
194185

195186
export async function fetchFilteredCustomers(query: string) {
196-
noStore();
197187
try {
198188
const data = await sql<CustomersTableType>`
199189
SELECT

dashboard/starter-example/app/lib/placeholder-data.js renamed to dashboard/final-example/app/lib/placeholder-data.ts

+2-13
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ const customers = [
2828
2929
image_url: '/customers/lee-robinson.png',
3030
},
31-
{
32-
id: '3958dc9e-787f-4377-85e9-fec4b6a6442a',
33-
name: 'Steph Dietz',
34-
35-
image_url: '/customers/steph-dietz.png',
36-
},
3731
{
3832
id: '76d65c26-f784-44a2-ac19-586678f7c2f2',
3933
name: 'Michael Novotny',
@@ -86,7 +80,7 @@ const invoices = [
8680
date: '2023-08-05',
8781
},
8882
{
89-
customer_id: customers[7].id,
83+
customer_id: customers[2].id,
9084
amount: 54246,
9185
status: 'pending',
9286
date: '2023-07-16',
@@ -150,9 +144,4 @@ const revenue = [
150144
{ month: 'Dec', revenue: 4800 },
151145
];
152146

153-
module.exports = {
154-
users,
155-
customers,
156-
invoices,
157-
revenue,
158-
};
147+
export { users, customers, invoices, revenue };
+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import bcrypt from 'bcrypt';
2+
import { db } from '@vercel/postgres';
3+
import { invoices, customers, revenue, users } from '../lib/placeholder-data';
4+
5+
const client = await db.connect();
6+
7+
async function seedUsers() {
8+
await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`;
9+
await client.sql`
10+
CREATE TABLE IF NOT EXISTS users (
11+
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
12+
name VARCHAR(255) NOT NULL,
13+
email TEXT NOT NULL UNIQUE,
14+
password TEXT NOT NULL
15+
);
16+
`;
17+
18+
const insertedUsers = await Promise.all(
19+
users.map(async (user) => {
20+
const hashedPassword = await bcrypt.hash(user.password, 10);
21+
return client.sql`
22+
INSERT INTO users (id, name, email, password)
23+
VALUES (${user.id}, ${user.name}, ${user.email}, ${hashedPassword})
24+
ON CONFLICT (id) DO NOTHING;
25+
`;
26+
}),
27+
);
28+
29+
return insertedUsers;
30+
}
31+
32+
async function seedInvoices() {
33+
await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`;
34+
35+
await client.sql`
36+
CREATE TABLE IF NOT EXISTS invoices (
37+
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
38+
customer_id UUID NOT NULL,
39+
amount INT NOT NULL,
40+
status VARCHAR(255) NOT NULL,
41+
date DATE NOT NULL
42+
);
43+
`;
44+
45+
const insertedInvoices = await Promise.all(
46+
invoices.map(
47+
(invoice) => client.sql`
48+
INSERT INTO invoices (customer_id, amount, status, date)
49+
VALUES (${invoice.customer_id}, ${invoice.amount}, ${invoice.status}, ${invoice.date})
50+
ON CONFLICT (id) DO NOTHING;
51+
`,
52+
),
53+
);
54+
55+
return insertedInvoices;
56+
}
57+
58+
async function seedCustomers() {
59+
await client.sql`CREATE EXTENSION IF NOT EXISTS "uuid-ossp"`;
60+
61+
await client.sql`
62+
CREATE TABLE IF NOT EXISTS customers (
63+
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
64+
name VARCHAR(255) NOT NULL,
65+
email VARCHAR(255) NOT NULL,
66+
image_url VARCHAR(255) NOT NULL
67+
);
68+
`;
69+
70+
const insertedCustomers = await Promise.all(
71+
customers.map(
72+
(customer) => client.sql`
73+
INSERT INTO customers (id, name, email, image_url)
74+
VALUES (${customer.id}, ${customer.name}, ${customer.email}, ${customer.image_url})
75+
ON CONFLICT (id) DO NOTHING;
76+
`,
77+
),
78+
);
79+
80+
return insertedCustomers;
81+
}
82+
83+
async function seedRevenue() {
84+
await client.sql`
85+
CREATE TABLE IF NOT EXISTS revenue (
86+
month VARCHAR(4) NOT NULL UNIQUE,
87+
revenue INT NOT NULL
88+
);
89+
`;
90+
91+
const insertedRevenue = await Promise.all(
92+
revenue.map(
93+
(rev) => client.sql`
94+
INSERT INTO revenue (month, revenue)
95+
VALUES (${rev.month}, ${rev.revenue})
96+
ON CONFLICT (month) DO NOTHING;
97+
`,
98+
),
99+
);
100+
101+
return insertedRevenue;
102+
}
103+
104+
export async function GET() {
105+
try {
106+
await client.sql`BEGIN`;
107+
await seedUsers();
108+
await seedCustomers();
109+
await seedInvoices();
110+
await seedRevenue();
111+
await client.sql`COMMIT`;
112+
113+
return Response.json({ message: 'Database seeded successfully' });
114+
} catch (error) {
115+
await client.sql`ROLLBACK`;
116+
return Response.json({ error }, { status: 500 });
117+
}
118+
}

dashboard/final-example/app/ui/customers/table.tsx

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import Image from 'next/image';
22
import { lusitana } from '@/app/ui/fonts';
33
import Search from '@/app/ui/search';
4-
import {
5-
CustomersTableType,
6-
FormattedCustomersTable,
7-
} from '@/app/lib/definitions';
4+
import { FormattedCustomersTable } from '@/app/lib/definitions';
85

96
export default async function CustomersTable({
107
customers,

dashboard/final-example/app/ui/dashboard/latest-invoices.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import clsx from 'clsx';
33
import Image from 'next/image';
44
import { lusitana } from '@/app/ui/fonts';
55
import { fetchLatestInvoices } from '@/app/lib/data';
6+
67
export default async function LatestInvoices() {
78
const latestInvoices = await fetchLatestInvoices();
89

dashboard/final-example/app/ui/invoices/buttons.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function DeleteInvoice({ id }: { id: string }) {
3030

3131
return (
3232
<form action={deleteInvoiceWithId}>
33-
<button className="rounded-md border p-2 hover:bg-gray-100">
33+
<button type="submit" className="rounded-md border p-2 hover:bg-gray-100">
3434
<span className="sr-only">Delete</span>
3535
<TrashIcon className="w-5" />
3636
</button>
+1-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
/** @type {import('next').NextConfig} */
22

3-
const nextConfig = {
4-
experimental: {
5-
ppr: 'incremental',
6-
},
7-
};
3+
const nextConfig = {};
84

95
export default nextConfig;

dashboard/final-example/package.json

+17-28
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,32 @@
33
"scripts": {
44
"build": "next build",
55
"dev": "next dev",
6-
"lint": "next lint",
7-
"prettier": "prettier --write --ignore-unknown .",
8-
"prettier:check": "prettier --check --ignore-unknown .",
9-
"seed": "node -r dotenv/config ./scripts/seed.js",
106
"start": "next start"
117
},
128
"dependencies": {
13-
"@heroicons/react": "^2.0.18",
9+
"@heroicons/react": "^2.1.4",
1410
"@tailwindcss/forms": "^0.5.7",
15-
"@types/node": "20.5.7",
16-
"@vercel/postgres": "^0.5.0",
17-
"autoprefixer": "10.4.15",
11+
"@vercel/postgres": "^0.8.0",
12+
"autoprefixer": "10.4.19",
1813
"bcrypt": "^5.1.1",
19-
"clsx": "^2.0.0",
20-
"next": "15.0.0-canary.28",
21-
"next-auth": "^5.0.0-beta.4",
22-
"postcss": "8.4.31",
23-
"react": "19.0.0-rc-6230622a1a-20240610",
24-
"react-dom": "19.0.0-rc-6230622a1a-20240610",
25-
"tailwindcss": "3.3.3",
26-
"typescript": "5.2.2",
27-
"use-debounce": "^9.0.4",
28-
"zod": "^3.22.2"
14+
"clsx": "^2.1.1",
15+
"next": "15.0.0-rc.0",
16+
"next-auth": "5.0.0-beta.19",
17+
"postcss": "8.4.38",
18+
"react": "19.0.0-rc-f994737d14-20240522",
19+
"react-dom": "19.0.0-rc-f994737d14-20240522",
20+
"tailwindcss": "3.4.4",
21+
"typescript": "5.5.2",
22+
"use-debounce": "^10.0.1",
23+
"zod": "^3.23.8"
2924
},
3025
"devDependencies": {
31-
"@types/bcrypt": "^5.0.1",
26+
"@types/bcrypt": "^5.0.2",
27+
"@types/node": "20.14.8",
3228
"@types/react": "18.3.3",
33-
"@types/react-dom": "18.3.0",
34-
"@vercel/style-guide": "^5.0.1",
35-
"dotenv": "^16.3.1",
36-
"eslint": "^8.52.0",
37-
"eslint-config-next": "15.0.0-rc.0",
38-
"eslint-config-prettier": "9.0.0",
39-
"prettier": "^3.0.3",
40-
"prettier-plugin-tailwindcss": "0.5.4"
29+
"@types/react-dom": "18.3.0"
4130
},
4231
"engines": {
43-
"node": ">=18.17.0"
32+
"node": ">=20.12.0"
4433
}
4534
}

0 commit comments

Comments
 (0)