remove unnecessary pages and files that came with the Vike init
parent
18411402f5
commit
b11c34b660
@ -1,19 +0,0 @@
|
|||||||
interface TodoItem {
|
|
||||||
text: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const todosDefault = [{ text: "Buy milk" }, { text: "Buy strawberries" }];
|
|
||||||
|
|
||||||
const database =
|
|
||||||
// We create an in-memory database.
|
|
||||||
// - We use globalThis so that the database isn't reset upon HMR.
|
|
||||||
// - The database is reset when restarting the server, use a proper database (SQLite/PostgreSQL/...) if you want persistent data.
|
|
||||||
// biome-ignore lint:
|
|
||||||
((
|
|
||||||
globalThis as unknown as { __database: { todos: TodoItem[] } }
|
|
||||||
).__database ??= { todos: todosDefault });
|
|
||||||
|
|
||||||
const { todos } = database;
|
|
||||||
|
|
||||||
export { todos };
|
|
||||||
export type { TodoItem };
|
|
@ -1,20 +1,11 @@
|
|||||||
import { Counter } from "./Counter.js";
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1
|
<h1
|
||||||
css={{ fontWeight: "700", fontSize: "1.875rem", paddingBottom: "1rem" }}
|
css={{ fontWeight: "700", fontSize: "1.875rem", paddingBottom: "1rem" }}
|
||||||
>
|
>
|
||||||
My Vike app
|
Token-Efficient Context Engineering
|
||||||
</h1>
|
</h1>
|
||||||
This page is:
|
|
||||||
<ul>
|
|
||||||
<li>Rendered to HTML.</li>
|
|
||||||
<li>
|
|
||||||
Interactive. <Counter />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
|
|
||||||
export function Counter() {
|
|
||||||
const [count, setCount] = useState(0);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
css={{
|
|
||||||
display: "inline-block",
|
|
||||||
border: "1px solid black",
|
|
||||||
borderRadius: "0.25rem",
|
|
||||||
backgroundColor: "#e5e7eb",
|
|
||||||
padding: "4px 8px 4px 8px",
|
|
||||||
fontSize: "0.75rem",
|
|
||||||
fontWeight: "500",
|
|
||||||
textTransform: "uppercase",
|
|
||||||
lineHeight: "1.5",
|
|
||||||
}}
|
|
||||||
onClick={() => setCount((count) => count + 1)}
|
|
||||||
>
|
|
||||||
Counter {count}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
import { useData } from "vike-react/useData";
|
|
||||||
import type { Data } from "./+data.js";
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const movie = useData<Data>();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>{movie.title}</h1>
|
|
||||||
Release Date: {movie.release_date}
|
|
||||||
<br />
|
|
||||||
Director: {movie.director}
|
|
||||||
<br />
|
|
||||||
Producer: {movie.producer}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
// https://vike.dev/data
|
|
||||||
|
|
||||||
import type { PageContextServer } from "vike/types";
|
|
||||||
import type { MovieDetails } from "../types.js";
|
|
||||||
import { useConfig } from "vike-react/useConfig";
|
|
||||||
|
|
||||||
export type Data = Awaited<ReturnType<typeof data>>;
|
|
||||||
|
|
||||||
export const data = async (pageContext: PageContextServer) => {
|
|
||||||
// https://vike.dev/useConfig
|
|
||||||
const config = useConfig();
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
`https://brillout.github.io/star-wars/api/films/${pageContext.routeParams.id}.json`,
|
|
||||||
);
|
|
||||||
let movie = (await response.json()) as MovieDetails;
|
|
||||||
|
|
||||||
config({
|
|
||||||
// Set <title>
|
|
||||||
title: movie.title,
|
|
||||||
});
|
|
||||||
|
|
||||||
// We remove data we don't need because the data is passed to
|
|
||||||
// the client; we should minimize what is sent over the network.
|
|
||||||
movie = minimize(movie);
|
|
||||||
|
|
||||||
return movie;
|
|
||||||
};
|
|
||||||
|
|
||||||
function minimize(movie: MovieDetails): MovieDetails {
|
|
||||||
const { id, title, release_date, director, producer } = movie;
|
|
||||||
const minimizedMovie = { id, title, release_date, director, producer };
|
|
||||||
return minimizedMovie;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import { useData } from "vike-react/useData";
|
|
||||||
import type { Data } from "./+data.js";
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const movies = useData<Data>();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>Star Wars Movies</h1>
|
|
||||||
<ol>
|
|
||||||
{movies.map(({ id, title, release_date }) => (
|
|
||||||
<li key={id}>
|
|
||||||
<a href={`/star-wars/${id}`}>{title}</a> ({release_date})
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ol>
|
|
||||||
<p>
|
|
||||||
Source:{" "}
|
|
||||||
<a href="https://brillout.github.io/star-wars">
|
|
||||||
brillout.github.io/star-wars
|
|
||||||
</a>
|
|
||||||
.
|
|
||||||
</p>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
// https://vike.dev/data
|
|
||||||
|
|
||||||
import type { Movie, MovieDetails } from "../types.js";
|
|
||||||
import { useConfig } from "vike-react/useConfig";
|
|
||||||
|
|
||||||
export type Data = Awaited<ReturnType<typeof data>>;
|
|
||||||
|
|
||||||
export const data = async () => {
|
|
||||||
// https://vike.dev/useConfig
|
|
||||||
const config = useConfig();
|
|
||||||
|
|
||||||
const response = await fetch(
|
|
||||||
"https://brillout.github.io/star-wars/api/films.json",
|
|
||||||
);
|
|
||||||
const moviesData = (await response.json()) as MovieDetails[];
|
|
||||||
|
|
||||||
config({
|
|
||||||
// Set <title>
|
|
||||||
title: `${moviesData.length} Star Wars Movies`,
|
|
||||||
});
|
|
||||||
|
|
||||||
// We remove data we don't need because the data is passed to the client; we should
|
|
||||||
// minimize what is sent over the network.
|
|
||||||
const movies = minimize(moviesData);
|
|
||||||
|
|
||||||
return movies;
|
|
||||||
};
|
|
||||||
|
|
||||||
function minimize(movies: MovieDetails[]): Movie[] {
|
|
||||||
return movies.map((movie) => {
|
|
||||||
const { title, release_date, id } = movie;
|
|
||||||
return { title, release_date, id };
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
export type Movie = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
release_date: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type MovieDetails = Movie & {
|
|
||||||
director: string;
|
|
||||||
producer: string;
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
import type { Data } from "./+data";
|
|
||||||
import { useData } from "vike-react/useData";
|
|
||||||
import { TodoList } from "./TodoList.js";
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const data = useData<Data>();
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<h1>To-do List</h1>
|
|
||||||
<TodoList initialTodoItems={data.todo} />
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
export const config = {
|
|
||||||
prerender: false,
|
|
||||||
};
|
|
@ -1,13 +0,0 @@
|
|||||||
// https://vike.dev/data
|
|
||||||
import { todos } from "../../database/todoItems";
|
|
||||||
import type { PageContextServer } from "vike/types";
|
|
||||||
|
|
||||||
export type Data = {
|
|
||||||
todo: { text: string }[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async function data(
|
|
||||||
_pageContext: PageContextServer,
|
|
||||||
): Promise<Data> {
|
|
||||||
return { todo: todos };
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
import { useState } from "react";
|
|
||||||
import { useTRPCClient } from "../../trpc/client";
|
|
||||||
|
|
||||||
export function TodoList({
|
|
||||||
initialTodoItems,
|
|
||||||
}: {
|
|
||||||
initialTodoItems: { text: string }[];
|
|
||||||
}) {
|
|
||||||
const [todoItems, setTodoItems] = useState(initialTodoItems);
|
|
||||||
const [newTodo, setNewTodo] = useState("");
|
|
||||||
const trpc = useTRPCClient();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<ul>
|
|
||||||
{todoItems.map((todoItem, index) => (
|
|
||||||
// biome-ignore lint:
|
|
||||||
<li key={index}>{todoItem.text}</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
<div>
|
|
||||||
<form
|
|
||||||
onSubmit={async (ev) => {
|
|
||||||
ev.preventDefault();
|
|
||||||
if (newTodo.trim() === "") return;
|
|
||||||
|
|
||||||
// Optimistic UI update
|
|
||||||
setTodoItems((prev) => [...prev, { text: newTodo }]);
|
|
||||||
try {
|
|
||||||
await trpc.onNewTodo.mutate(newTodo);
|
|
||||||
setNewTodo("");
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
// rollback
|
|
||||||
setTodoItems((prev) => prev.slice(0, -1));
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
onChange={(ev) => setNewTodo(ev.target.value)}
|
|
||||||
value={newTodo}
|
|
||||||
/>
|
|
||||||
<button type="submit">Add to-do</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
Loading…
Reference in New Issue