La in dapper, och routing. fixade upp lite exempelsidor
This commit is contained in:
		@@ -17,6 +17,7 @@
 | 
				
			|||||||
		"vite-plugin-solid": "^2.11.8"
 | 
							"vite-plugin-solid": "^2.11.8"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	"dependencies": {
 | 
						"dependencies": {
 | 
				
			||||||
 | 
							"@solidjs/router": "^0.15.3",
 | 
				
			||||||
		"bootstrap": "^5.3.8",
 | 
							"bootstrap": "^5.3.8",
 | 
				
			||||||
		"solid-bootstrap": "^1.0.21",
 | 
							"solid-bootstrap": "^1.0.21",
 | 
				
			||||||
		"solid-js": "^1.9.9"
 | 
							"solid-js": "^1.9.9"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,32 +1,54 @@
 | 
				
			|||||||
 | 
					import { Router, Route } from "@solidjs/router";
 | 
				
			||||||
import type { Component } from "solid-js";
 | 
					import type { Component } from "solid-js";
 | 
				
			||||||
import { createSignal, For, onMount } from "solid-js";
 | 
					import Home from "./components/Home";
 | 
				
			||||||
import CalibreService from "./services/calibreservice";
 | 
					import BookList from "./components/BookList";
 | 
				
			||||||
import { book } from "./types/calibretypes";
 | 
					import AuthorList from "./components/AuthorList";
 | 
				
			||||||
import BookCard from "./components/BookCard";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const App: Component = () => {
 | 
					const App: Component = () => {
 | 
				
			||||||
	const [books, setBooks] = createSignal<book[]>([]);
 | 
					 | 
				
			||||||
	onMount(() => {
 | 
					 | 
				
			||||||
		CalibreService.getBooks().then(setBooks);
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
	return (
 | 
						return (
 | 
				
			||||||
		<div>
 | 
							<div>
 | 
				
			||||||
			<header>
 | 
								<header>
 | 
				
			||||||
				<p>
 | 
									<nav class="navbar navbar-expand-lg bg-body-tertiary">
 | 
				
			||||||
					Edit <code>src/App.tsx</code> and save to reload.
 | 
										<div class="container">
 | 
				
			||||||
				</p>
 | 
											<a class="navbar-brand" href="#">
 | 
				
			||||||
				<a
 | 
												Navbar
 | 
				
			||||||
					href="https://github.com/solidjs/solid"
 | 
											</a>
 | 
				
			||||||
					target="_blank"
 | 
											<button
 | 
				
			||||||
					rel="noopener noreferrer"
 | 
												class="navbar-toggler"
 | 
				
			||||||
				>
 | 
												type="button"
 | 
				
			||||||
					Learn Solid
 | 
												data-bs-toggle="collapse"
 | 
				
			||||||
				</a>
 | 
												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>
 | 
								</header>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			<div class="book-grid d-flex flex-wrap justify-content-between gap-3 p-3">
 | 
								<main class="container">
 | 
				
			||||||
				<For each={books()}>{(item) => <BookCard book={item} />}</For>
 | 
									<Router>
 | 
				
			||||||
			</div>
 | 
										<Route path="/books/author/:authorid" component={BookList} />
 | 
				
			||||||
 | 
										<Route path="/books" component={BookList} />
 | 
				
			||||||
 | 
										<Route path="/authors" component={AuthorList} />
 | 
				
			||||||
 | 
										<Route path="/" component={Home} />
 | 
				
			||||||
 | 
									</Router>
 | 
				
			||||||
 | 
								</main>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								Frontend/src/components/AuthorCard.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								Frontend/src/components/AuthorCard.tsx
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
							
								
								
									
										22
									
								
								Frontend/src/components/AuthorList.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Frontend/src/components/AuthorList.tsx
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { Show, type Component } from "solid-js";
 | 
					import { Show, type Component } from "solid-js";
 | 
				
			||||||
import { book } from "../types/calibretypes";
 | 
					import { book } from "../types/types";
 | 
				
			||||||
import { Card } from "solid-bootstrap";
 | 
					import { Card } from "solid-bootstrap";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const BookCard: Component<{ book: book }> = (props: { book: book }) => {
 | 
					const BookCard: Component<{ book: book }> = (props: { book: book }) => {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								Frontend/src/components/BookList.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								Frontend/src/components/BookList.tsx
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
							
								
								
									
										6
									
								
								Frontend/src/components/Home.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								Frontend/src/components/Home.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					import { type Component } from "solid-js";
 | 
				
			||||||
 | 
					const Home: Component = () => {
 | 
				
			||||||
 | 
						return <h1>Home!</h1>;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Home;
 | 
				
			||||||
							
								
								
									
										21
									
								
								Frontend/src/services/bibblanservice.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Frontend/src/services/bibblanservice.ts
									
									
									
									
									
										Normal 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;
 | 
				
			||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { book } from "../types/calibretypes";
 | 
					import { book } from "../types/types";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const CalibreService = {
 | 
					const CalibreService = {
 | 
				
			||||||
	getBooks: async (): Promise<book[]> => {
 | 
						getBooks: async (): Promise<book[]> => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,4 +12,10 @@ interface book {
 | 
				
			|||||||
	seriesNumber: number;
 | 
						seriesNumber: number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type { book };
 | 
					interface author {
 | 
				
			||||||
 | 
						id: number;
 | 
				
			||||||
 | 
						name: string;
 | 
				
			||||||
 | 
						bookCount: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type { book, author };
 | 
				
			||||||
@@ -541,6 +541,11 @@
 | 
				
			|||||||
  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz#d81efe6a12060c7feddf9805e2a94c3ab0679f48"
 | 
					  resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.0.tgz#d81efe6a12060c7feddf9805e2a94c3ab0679f48"
 | 
				
			||||||
  integrity sha512-xMmiWRR8sp72Zqwjgtf3QbZfF1wdh8X2ABu3EaozvZcyHJeU0r+XAnXdKgs4cCAp6ORoYoCygipYP1mjmbjrsg==
 | 
					  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":
 | 
					"@types/babel__core@^7.20.4":
 | 
				
			||||||
  version "7.20.5"
 | 
					  version "7.20.5"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
 | 
					  resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@
 | 
				
			|||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <PackageReference Include="Dapper" Version="2.1.66" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.6" />
 | 
					    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.6" />
 | 
				
			||||||
    <PackageReference Include="Microsoft.AspNetCore.SpaProxy">
 | 
					    <PackageReference Include="Microsoft.AspNetCore.SpaProxy">
 | 
				
			||||||
      <Version>9.*-*</Version>
 | 
					      <Version>9.*-*</Version>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								Server/Business/Services/DatabaseService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								Server/Business/Services/DatabaseService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					using Bibblan.Models;
 | 
				
			||||||
 | 
					using Bibblan.ViewModels;
 | 
				
			||||||
 | 
					using Dapper;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Options;
 | 
				
			||||||
 | 
					using Npgsql;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bibblan.Business.Services
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class BookFilter
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public int? Author;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class DatabaseService
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        BibblanOptions settings;
 | 
				
			||||||
 | 
					        public DatabaseService(IOptions<BibblanOptions> options) {
 | 
				
			||||||
 | 
					            settings = options.Value;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<Books> GetBooks(int count, BookFilter filter = null)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var conn = new NpgsqlConnection(settings.BibblanConnection);
 | 
				
			||||||
 | 
					            var query = "select * from books";
 | 
				
			||||||
 | 
					            if(filter != null)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                query += " where ";
 | 
				
			||||||
 | 
					                if(filter.Author != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    query += $"id in (select book from books_authors_link where author = {filter.Author})";
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return conn.Query<Books>(query).Take(count).ToList();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<AuthorVm> GetAuthors(int count)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var query = "select a.id, a.name, count(bal.*) as bookcount\r\nfrom authors a\r\nleft join books_authors_link bal on a.id  = bal.author\r\ngroup by a.id , a.name ";
 | 
				
			||||||
 | 
					            var conn = new NpgsqlConnection(settings.BibblanConnection);
 | 
				
			||||||
 | 
					            return conn.Query<AuthorVm>(query).Take(count).ToList();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								Server/Controllers/BibblanController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								Server/Controllers/BibblanController.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					using Bibblan.Business.Services;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Bibblan.Controllers
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [ApiController]
 | 
				
			||||||
 | 
					    [Route("api/[controller]")]
 | 
				
			||||||
 | 
					    public class BibblanController : ControllerBase
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        DatabaseService _db;
 | 
				
			||||||
 | 
					        CalibreService _calibre;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public BibblanController(DatabaseService databaseService, CalibreService calibre)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _db = databaseService;
 | 
				
			||||||
 | 
					            _calibre = calibre;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpGet("cover")]
 | 
				
			||||||
 | 
					        public IActionResult GetCover(string path)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            //TODO: Bör kanske inte gå direkt mot calibres filer.. 
 | 
				
			||||||
 | 
					            var bytes = _calibre.Cover(path);
 | 
				
			||||||
 | 
					            return File(bytes, "image/jpeg", true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpGet("books")]
 | 
				
			||||||
 | 
					        public IActionResult GetBooks()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var authors = _db.GetBooks(100).ToList();
 | 
				
			||||||
 | 
					            return Ok(authors);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpGet("authors")]
 | 
				
			||||||
 | 
					        public IActionResult GetAuthors()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var authors = _db.GetAuthors(100).ToList();
 | 
				
			||||||
 | 
					            return Ok(authors);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [HttpGet("books/author/{authorid}")]
 | 
				
			||||||
 | 
					        public IActionResult GetBooksByAuthor(int authorid)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var authors = _db.GetBooks(100, new BookFilter
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Author = authorid
 | 
				
			||||||
 | 
					            }).ToList();
 | 
				
			||||||
 | 
					            return Ok(authors);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -13,6 +13,7 @@ configSection.Bind(config);
 | 
				
			|||||||
builder.Services.Configure<BibblanOptions>(configSection);
 | 
					builder.Services.Configure<BibblanOptions>(configSection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
builder.Services.AddScoped<CalibreService, CalibreService>();
 | 
					builder.Services.AddScoped<CalibreService, CalibreService>();
 | 
				
			||||||
 | 
					builder.Services.AddScoped<DatabaseService, DatabaseService>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
builder.Services.AddControllers();
 | 
					builder.Services.AddControllers();
 | 
				
			||||||
@@ -26,6 +27,8 @@ builder.Services.AddDbContext<PostgresCalibreContext>(options => options.UseNpgs
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var app = builder.Build();
 | 
					var app = builder.Build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dapper.DefaultTypeMap.MatchNamesWithUnderscores = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.UseDefaultFiles();
 | 
					app.UseDefaultFiles();
 | 
				
			||||||
app.MapStaticAssets();
 | 
					app.MapStaticAssets();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user