Skip to content

Commit c0c931d

Browse files
committed
added second exercise
1 parent 168b7c3 commit c0c931d

File tree

124 files changed

+11191
-4809
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

124 files changed

+11191
-4809
lines changed

.vscode/extensions.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"recommendations": [
3-
"dbaeumer.vscode-eslint",
4-
"esbenp.prettier-vscode",
5-
"neotan.vscode-auto-restart-typescript-eslint-servers",
6-
]
2+
"recommendations": [
3+
"dbaeumer.vscode-eslint",
4+
"esbenp.prettier-vscode",
5+
"neotan.vscode-auto-restart-typescript-eslint-servers"
6+
]
77
}

.vscode/settings.json

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
{
2-
"typescript.preferences.autoImportFileExcludePatterns": [
3-
"@remix-run/server-runtime",
4-
"@remix-run/router",
5-
"react-router-dom",
6-
"react-router"
7-
],
8-
"workbench.editorAssociations": {
9-
"*.db": "sqlite-viewer.view"
10-
},
11-
"cSpell.words": [
12-
"Kakariki",
13-
"Kiira"
14-
]
2+
"typescript.preferences.autoImportFileExcludePatterns": [
3+
"@remix-run/server-runtime",
4+
"@remix-run/router",
5+
"react-router-dom",
6+
"react-router"
7+
],
8+
"workbench.editorAssociations": {
9+
"*.db": "sqlite-viewer.view"
10+
},
11+
"cSpell.words": ["Kakariki", "Kiira"]
1512
}

epicshop/fix.js

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,29 @@ const VERBOSE = false
1212
const logVerbose = (...args) => (VERBOSE ? console.log(...args) : undefined)
1313

1414
const workshopRoot = here('..')
15-
const examples = (await readDir(here('../examples'))).map(dir =>
15+
const examples = (await readDir(here('../examples'))).map((dir) =>
1616
here(`../examples/${dir}`),
1717
)
1818
const exercises = (await readDir(here('../exercises')))
19-
.map(name => here(`../exercises/${name}`))
20-
.filter(filepath => fs.statSync(filepath).isDirectory())
19+
.map((name) => here(`../exercises/${name}`))
20+
.filter((filepath) => fs.statSync(filepath).isDirectory())
2121
const exerciseApps = (
2222
await Promise.all(
23-
exercises.flatMap(async exercise => {
23+
exercises.flatMap(async (exercise) => {
2424
return (await readDir(exercise))
25-
.filter(dir => {
25+
.filter((dir) => {
2626
return /(problem|solution)/.test(dir)
2727
})
28-
.map(dir => path.join(exercise, dir))
28+
.map((dir) => path.join(exercise, dir))
2929
}),
3030
)
3131
).flat()
32-
const exampleApps = (await readDir(here('../examples'))).map(dir =>
32+
const exampleApps = (await readDir(here('../examples'))).map((dir) =>
3333
here(`../examples/${dir}`),
3434
)
3535
const apps = [...exampleApps, ...exerciseApps]
3636

37-
const appsWithPkgJson = [...examples, ...apps].filter(app => {
37+
const appsWithPkgJson = [...examples, ...apps].filter((app) => {
3838
const pkgjsonPath = path.join(app, 'package.json')
3939
return exists(pkgjsonPath)
4040
})
@@ -70,7 +70,7 @@ async function updateTsconfig() {
7070
const tsconfig = {
7171
files: [],
7272
exclude: ['node_modules'],
73-
references: appsWithPkgJson.map(a => ({
73+
references: appsWithPkgJson.map((a) => ({
7474
path: relativeToWorkshopRoot(a).replace(/\\/g, '/'),
7575
})),
7676
}

eslint.config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@ import defaultConfig from '@epic-web/config/eslint'
22

33
/** @type {import("eslint").Linter.Config} */
44
export default [
5-
...defaultConfig,
5+
...defaultConfig.map((config) => ({
6+
...config,
7+
ignores: [...(config.ignores ?? []), '**/.react-router/**/*'],
8+
})),
9+
610
{
711
rules: {
812
// we leave unused vars around for the exercises
Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
# Registering Routes in React Router
2-
3-
Welcome to your first exercise! In this exercise,
2+
3+
Welcome to your first exercise! In this exercise,
44
you will learn how to register routes in a React Router application.
55

66
## Exercise Overview
77

88
In this exercise, you will:
9+
910
1. Explore the `app/routes` directory.
1011
2. Register those routes in the `app/routes.ts` file.
1112
3. (Bonus) Create a utility to easily define landing page routes.
12-
1313

1414
## Getting Started
1515

16-
Due to Kody 🐨 being on vacation our assistant will be Kiira the Kakariki 🐥!
17-
18-
To get started, find our helpful assistants comments in the `app/routes.ts` file. (They include 🐥 emoji)
19-
20-
21-
16+
To get started, find our helpful assistants comments in the `app/routes.ts` file. (They include 🐨 emoji)
Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
@import "tailwindcss";
1+
@import 'tailwindcss';
22

33
@theme {
4-
--font-sans: "Inter", ui-sans-serif, system-ui, sans-serif,
5-
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
4+
--font-sans:
5+
'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji',
6+
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
67
}
78

89
html,
910
body {
10-
@apply bg-white dark:bg-gray-950;
11+
@apply bg-white dark:bg-gray-950;
1112

12-
@media (prefers-color-scheme: dark) {
13-
color-scheme: dark;
14-
}
13+
@media (prefers-color-scheme: dark) {
14+
color-scheme: dark;
15+
}
1516
}
Lines changed: 109 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,109 @@
1-
import { ShoppingBag } from "lucide-react"
2-
import { Link } from "react-router";
3-
4-
export const Footer = () => {
5-
return (
6-
<footer className="bg-white dark:bg-gray-900 border-t border-stone-200 dark:border-gray-700">
7-
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
8-
<div className="grid grid-cols-1 md:grid-cols-4 gap-12">
9-
<div className="col-span-1 md:col-span-2">
10-
<div className="flex items-center space-x-3 mb-6">
11-
<ShoppingBag className="w-7 h-7 text-amber-600 dark:text-amber-500" />
12-
<span className="text-xl font-light text-gray-900 dark:text-white tracking-wide">
13-
EpicStore
14-
</span>
15-
</div>
16-
<p className="text-gray-600 dark:text-gray-400 font-light leading-relaxed max-w-md">
17-
Your premier destination for premium epic products. Discover the perfect product that combines
18-
style, comfort, and quality craftsmanship.
19-
</p>
20-
</div>
21-
<div>
22-
<h3 className="text-sm font-medium text-gray-900 dark:text-white uppercase tracking-wider mb-6">
23-
Shop
24-
</h3>
25-
<ul className="space-y-4">
26-
<li><Link to="/products" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">All Products</Link></li>
27-
<li><Link to="/products?category=Running" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">Running</Link></li>
28-
<li><Link to="/products?category=Casual" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">Casual</Link></li>
29-
<li><Link to="/products?category=Formal" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">Formal</Link></li>
30-
</ul>
31-
</div>
32-
<div>
33-
<h3 className="text-sm font-medium text-gray-900 dark:text-white uppercase tracking-wider mb-6">
34-
Company
35-
</h3>
36-
<ul className="space-y-4">
37-
<li><Link to="/about" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">About</Link></li>
38-
<li><Link to="/contact" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">Contact</Link></li>
39-
<li><Link to="/terms-of-service" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">Terms of Service</Link></li>
40-
<li><Link to="/terms-of-use" className="text-gray-600 dark:text-gray-400 hover:text-amber-600 dark:hover:text-amber-500 font-light transition-colors duration-300">Terms of Use</Link></li>
41-
</ul>
42-
</div>
43-
</div>
44-
<div className="mt-12 pt-8 border-t border-stone-200 dark:border-gray-700">
45-
<p className="text-center text-gray-500 dark:text-gray-400 font-light">
46-
© 2025 EpicStore. All rights reserved.
47-
</p>
48-
</div>
49-
</div>
50-
</footer>
51-
)
52-
}
1+
import { ShoppingBag } from 'lucide-react'
2+
import { Link } from 'react-router'
3+
4+
export const Footer = () => {
5+
return (
6+
<footer className="border-t border-stone-200 bg-white dark:border-gray-700 dark:bg-gray-900">
7+
<div className="mx-auto max-w-7xl px-4 py-16 sm:px-6 lg:px-8">
8+
<div className="grid grid-cols-1 gap-12 md:grid-cols-4">
9+
<div className="col-span-1 md:col-span-2">
10+
<div className="mb-6 flex items-center space-x-3">
11+
<ShoppingBag className="h-7 w-7 text-amber-600 dark:text-amber-500" />
12+
<span className="text-xl font-light tracking-wide text-gray-900 dark:text-white">
13+
EpicStore
14+
</span>
15+
</div>
16+
<p className="max-w-md leading-relaxed font-light text-gray-600 dark:text-gray-400">
17+
Your premier destination for premium epic products. Discover the
18+
perfect product that combines style, comfort, and quality
19+
craftsmanship.
20+
</p>
21+
</div>
22+
<div>
23+
<h3 className="mb-6 text-sm font-medium tracking-wider text-gray-900 uppercase dark:text-white">
24+
Shop
25+
</h3>
26+
<ul className="space-y-4">
27+
<li>
28+
<Link
29+
to="/products"
30+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
31+
>
32+
All Products
33+
</Link>
34+
</li>
35+
<li>
36+
<Link
37+
to="/products?category=Running"
38+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
39+
>
40+
Running
41+
</Link>
42+
</li>
43+
<li>
44+
<Link
45+
to="/products?category=Casual"
46+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
47+
>
48+
Casual
49+
</Link>
50+
</li>
51+
<li>
52+
<Link
53+
to="/products?category=Formal"
54+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
55+
>
56+
Formal
57+
</Link>
58+
</li>
59+
</ul>
60+
</div>
61+
<div>
62+
<h3 className="mb-6 text-sm font-medium tracking-wider text-gray-900 uppercase dark:text-white">
63+
Company
64+
</h3>
65+
<ul className="space-y-4">
66+
<li>
67+
<Link
68+
to="/about"
69+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
70+
>
71+
About
72+
</Link>
73+
</li>
74+
<li>
75+
<Link
76+
to="/contact"
77+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
78+
>
79+
Contact
80+
</Link>
81+
</li>
82+
<li>
83+
<Link
84+
to="/terms-of-service"
85+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
86+
>
87+
Terms of Service
88+
</Link>
89+
</li>
90+
<li>
91+
<Link
92+
to="/terms-of-use"
93+
className="font-light text-gray-600 transition-colors duration-300 hover:text-amber-600 dark:text-gray-400 dark:hover:text-amber-500"
94+
>
95+
Terms of Use
96+
</Link>
97+
</li>
98+
</ul>
99+
</div>
100+
</div>
101+
<div className="mt-12 border-t border-stone-200 pt-8 dark:border-gray-700">
102+
<p className="text-center font-light text-gray-500 dark:text-gray-400">
103+
© 2025 EpicStore. All rights reserved.
104+
</p>
105+
</div>
106+
</div>
107+
</footer>
108+
)
109+
}

0 commit comments

Comments
 (0)