-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add catalog (summary and paginated)
- Loading branch information
Showing
10 changed files
with
193 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { EndpointView, LiteFanfictionOutput } from "@common"; | ||
import { z } from "@deps"; | ||
|
||
const CatalogItemSchema = z.custom<LiteFanfictionOutput>(); | ||
const CatalogPageSchema = z.object({ | ||
href: z.string(), | ||
isActive: z.boolean().default(false), | ||
index: z.number().int(), | ||
}); | ||
|
||
const options = { | ||
projection: { | ||
_id: 0, | ||
chapters: 0, | ||
kind: 0, | ||
}, | ||
limit: 5, | ||
sort: { created_at: -1 as const }, | ||
}; | ||
|
||
export default EndpointView.init({ | ||
method: "get", | ||
path: "/fanfiction-catalog/pages/:page", | ||
view: "catalog-paginated", | ||
payload: { | ||
params: z.object({ | ||
page: z.coerce.number().int(), | ||
}), | ||
}, | ||
context: z.object({ | ||
fanfictions: z.array(CatalogItemSchema), | ||
pages: z.array(CatalogPageSchema), | ||
currentPage: z.number().int(), | ||
}), | ||
}).registerHandler(async function main(req, res) { | ||
const total = await res.app.fanfics.countDocuments(); | ||
const totalPages = Math.ceil(total / options.limit); | ||
const currentPage = req.params.page; | ||
const pages = Array.from( | ||
{ length: totalPages }, | ||
(_, index) => | ||
CatalogPageSchema.parse({ | ||
href: this.path.replace(":page", String(index + 1)), | ||
isActive: currentPage === index + 1, | ||
index: index + 1, | ||
}), | ||
); | ||
const skip = currentPage === 1 | ||
? 0 | ||
: currentPage * options.limit - options.limit; | ||
const fanfictions = await res.app.fanfics | ||
.find({}, options) | ||
.skip(skip) | ||
.toArray(); | ||
|
||
return this.renderOk(res, { fanfictions, pages, currentPage }); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { EndpointView, LiteFanfictionOutput } from "@common"; | ||
import { z } from "@deps"; | ||
|
||
const CatalogSummarySchema = z.custom<LiteFanfictionOutput>(); | ||
|
||
const limit = 3; | ||
const projection = { | ||
_id: 0, | ||
chapters: 0, | ||
kind: 0, | ||
}; | ||
|
||
const recentlyAddedOptions = { | ||
limit, | ||
projection, | ||
sort: { created_at: -1 as const }, | ||
}; | ||
|
||
const recentlyUpdatedQuery = { | ||
$expr: { $gt: ["$updated_at", "$created_at"] }, | ||
}; | ||
|
||
const recentlyUpdatedOptions = { | ||
limit, | ||
projection, | ||
sort: { | ||
updated_at: -1 as const, | ||
}, | ||
}; | ||
|
||
export default EndpointView.init({ | ||
method: "get", | ||
path: "/", | ||
view: "catalog-summary", | ||
context: z.object({ | ||
recentlyAdded: z.array(CatalogSummarySchema), | ||
recentlyUpdated: z.array(CatalogSummarySchema), | ||
}), | ||
}).registerHandler(async function main(_req, res) { | ||
const recentlyAdded = await res.app.fanfics | ||
.find({}, recentlyAddedOptions) | ||
.toArray(); | ||
const recentlyUpdated = await res.app.fanfics | ||
.find(recentlyUpdatedQuery, recentlyUpdatedOptions) | ||
.toArray(); | ||
|
||
return this.renderOk(res, { recentlyAdded, recentlyUpdated }); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { | ||
getAuthorTag, | ||
getFandomTag, | ||
getLanguageTag, | ||
getOriginTag, | ||
getRelationshipTag, | ||
type LiteFanfictionOutput, | ||
type Tag, | ||
type TextOutput, | ||
type TextWithTranslationsOutput, | ||
} from "@common"; | ||
|
||
export function getTags(fanfiction: LiteFanfictionOutput) { | ||
const tags: Tag[] = [getAuthorTag(fanfiction.author.name)]; | ||
|
||
if (fanfiction.fandom) { | ||
tags.push(getFandomTag(fanfiction.fandom)); | ||
} | ||
|
||
if (fanfiction.relationship) { | ||
tags.push(getRelationshipTag(fanfiction.relationship)); | ||
} | ||
|
||
tags.push(getLanguageTag(fanfiction.language_code)); | ||
tags.push(getOriginTag(fanfiction.source)); | ||
|
||
return tags; | ||
} | ||
|
||
export function getTextToDisplay(text: TextOutput | TextOutput[]) { | ||
if (typeof text === "undefined") { | ||
return; | ||
} | ||
|
||
if (Array.isArray(text)) { | ||
if (text.length === 0) { | ||
return; | ||
} | ||
|
||
return text[0].rich || text[0].raw; | ||
} | ||
|
||
return text.rich || text.raw; | ||
} | ||
|
||
export function getMainTranslation(localized: TextWithTranslationsOutput) { | ||
return localized.translations[0]; | ||
} | ||
|
||
export function isCurrentPage(page: number) { | ||
const currentPage = window.location.pathname.split("/").reverse()[0]; | ||
|
||
return Number(currentPage) === page; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{{#each fanfictions}} | ||
{{> fanfiction-card . }} | ||
{{/each}} | ||
<nav aria-label="Navigation"> | ||
<ul class="pagination"> | ||
{{#each pages}} | ||
<li class="page-item{{#if isActive}} active{{/if}}"> | ||
<a href="{{href}}" class="page-link">{{index}}</a> | ||
</li> | ||
{{/each}} | ||
</ul> | ||
</nav> |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters