La in dapper, och routing. fixade upp lite exempelsidor

This commit is contained in:
2025-09-09 17:15:11 +02:00
parent 8c54a120d1
commit 01e341fce0
15 changed files with 260 additions and 24 deletions

View File

@@ -17,6 +17,7 @@
"vite-plugin-solid": "^2.11.8"
},
"dependencies": {
"@solidjs/router": "^0.15.3",
"bootstrap": "^5.3.8",
"solid-bootstrap": "^1.0.21",
"solid-js": "^1.9.9"

View File

@@ -1,32 +1,54 @@
import { Router, Route } from "@solidjs/router";
import type { Component } from "solid-js";
import { createSignal, For, onMount } from "solid-js";
import CalibreService from "./services/calibreservice";
import { book } from "./types/calibretypes";
import BookCard from "./components/BookCard";
import Home from "./components/Home";
import BookList from "./components/BookList";
import AuthorList from "./components/AuthorList";
const App: Component = () => {
const [books, setBooks] = createSignal<book[]>([]);
onMount(() => {
CalibreService.getBooks().then(setBooks);
});
return (
<div>
<header>
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
href="https://github.com/solidjs/solid"
target="_blank"
rel="noopener noreferrer"
>
Learn Solid
</a>
<nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container">
<a class="navbar-brand" href="#">
Navbar
</a>
<button
class="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link active" href="/">
Home
</a>
<a class="nav-link" href="/books">
Books
</a>
<a class="nav-link" href="/authors">
Authors
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="book-grid d-flex flex-wrap justify-content-between gap-3 p-3">
<For each={books()}>{(item) => <BookCard book={item} />}</For>
</div>
<main class="container">
<Router>
<Route path="/books/author/:authorid" component={BookList} />
<Route path="/books" component={BookList} />
<Route path="/authors" component={AuthorList} />
<Route path="/" component={Home} />
</Router>
</main>
</div>
);
};

View File

@@ -0,0 +1,27 @@
import { Show, type Component } from "solid-js";
import { author } from "../types/types";
import { Card } from "solid-bootstrap";
const AuthorCard: Component<{ author: author }> = (props: {
author: author;
}) => {
return (
<Card class="book-card col-lg-2 col-md-3 col-sm-4">
<Card.Img
variant="top"
class="padding-1"
src={"/api/biiblan/authorcover/" + encodeURIComponent(props.author.id)}
/>
<Card.Body>
<Card.Title>{props.author.name}</Card.Title>
<Card.Subtitle>
<a href={`/books/author/${props.author.id}`}>
{props.author.bookCount} books
</a>
</Card.Subtitle>
</Card.Body>
</Card>
);
};
export default AuthorCard;

View File

@@ -0,0 +1,22 @@
import { createSignal, onMount, For, type Component } from "solid-js";
import AuthorCard from "./AuthorCard";
import BibblanService from "../services/bibblanservice";
import { author } from "../types/types";
const BookList: Component = () => {
const [authors, setAuthors] = createSignal<author[]>([]);
onMount(() => {
BibblanService.getAuthors().then(setAuthors);
});
return (
<div>
<h1>Books!</h1>
<div class="book-grid d-flex flex-wrap justify-content-between gap-3 p-3">
<For each={authors()}>{(item) => <AuthorCard author={item} />}</For>
</div>
</div>
);
};
export default BookList;

View File

@@ -1,5 +1,5 @@
import { Show, type Component } from "solid-js";
import { book } from "../types/calibretypes";
import { book } from "../types/types";
import { Card } from "solid-bootstrap";
const BookCard: Component<{ book: book }> = (props: { book: book }) => {

View File

@@ -0,0 +1,24 @@
import { createSignal, onMount, For, type Component } from "solid-js";
import { useParams } from "@solidjs/router";
import BookCard from "./BookCard";
import BibblanService from "../services/bibblanservice";
import { book } from "../types/types";
const BookList: Component = () => {
const [books, setBooks] = createSignal<book[]>([]);
const params = useParams();
onMount(() => {
BibblanService.getBooks(params.authorid).then(setBooks);
});
return (
<div>
<h1>Books!</h1>
<div class="book-grid d-flex flex-wrap justify-content-between gap-3 p-3">
<For each={books()}>{(item) => <BookCard book={item} />}</For>
</div>
</div>
);
};
export default BookList;

View File

@@ -0,0 +1,6 @@
import { type Component } from "solid-js";
const Home: Component = () => {
return <h1>Home!</h1>;
};
export default Home;

View File

@@ -0,0 +1,21 @@
import { book, author } from "../types/types";
const BibblanService = {
getBooks: async (
authorid: string | undefined = undefined
): Promise<book[]> => {
let url = "/api/bibblan/books";
if (authorid != undefined) {
url += `/author/${authorid}`;
}
const response = await fetch(url);
return response.json();
},
getAuthors: async (): Promise<author[]> => {
const response = await fetch("/api/bibblan/authors");
return response.json();
},
};
export default BibblanService;

View File

@@ -1,4 +1,4 @@
import { book } from "../types/calibretypes";
import { book } from "../types/types";
const CalibreService = {
getBooks: async (): Promise<book[]> => {

View File

@@ -12,4 +12,10 @@ interface book {
seriesNumber: number;
}
export type { book };
interface author {
id: number;
name: string;
bookCount: number;
}
export type { book, author };

View File

@@ -541,6 +541,11 @@
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz#d81efe6a12060c7feddf9805e2a94c3ab0679f48"
integrity sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==
"@solidjs/router@^0.15.3":
version "0.15.3"
resolved "https://registry.yarnpkg.com/@solidjs/router/-/router-0.15.3.tgz#2c5e7aa637980ab7fce956aedc8cd20614163f2a"
integrity sha512-iEbW8UKok2Oio7o6Y4VTzLj+KFCmQPGEpm1fS3xixwFBdclFVBvaQVeibl1jys4cujfAK5Kn6+uG2uBm3lxOMw==
"@types/babel__core@^7.20.4":
version "7.20.5"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"