feat : buzz feedback
This commit is contained in:
@@ -42,6 +42,10 @@ function createAuth() {
|
||||
transaction: true,
|
||||
}),
|
||||
baseURL: required("BETTER_AUTH_URL"),
|
||||
trustedOrigins: process.env.BETTER_AUTH_TRUSTED_ORIGINS
|
||||
?.split(",")
|
||||
.map((origin) => origin.trim())
|
||||
.filter(Boolean),
|
||||
secret: required("BETTER_AUTH_SECRET"),
|
||||
emailAndPassword: {
|
||||
enabled: true,
|
||||
|
||||
Vendored
+47
@@ -3,6 +3,13 @@ import "server-only";
|
||||
import { cacheLife, cacheTag } from "next/cache";
|
||||
|
||||
import { getPublicPage, listPublicCharacters } from "@/lib/content/queries";
|
||||
import {
|
||||
getPublicArtifactExport,
|
||||
getPublicGuide,
|
||||
getPublicTeamExport,
|
||||
getPublicWeaponExport,
|
||||
listGuideCards,
|
||||
} from "@/lib/guides/queries";
|
||||
import {
|
||||
characterCacheTag,
|
||||
dataSourceCacheTag,
|
||||
@@ -40,3 +47,43 @@ export async function getCachedPublicPage(
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getCachedPublicGuideCards() {
|
||||
"use cache: remote";
|
||||
cacheLife({ stale: 30, revalidate: 60, expire: 60 * 60 });
|
||||
cacheTag(DIRECTORY_CACHE_TAG);
|
||||
return listGuideCards();
|
||||
}
|
||||
|
||||
export async function getCachedPublicGuide(slug: string) {
|
||||
"use cache: remote";
|
||||
cacheLife({ stale: 15, revalidate: 60, expire: 60 * 60 });
|
||||
const result = await getPublicGuide(slug);
|
||||
cacheTag(DIRECTORY_CACHE_TAG);
|
||||
if (result) cacheTag(pageCacheTag(result.id));
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getCachedPublicTeamExport(teamId: string) {
|
||||
"use cache: remote";
|
||||
cacheLife({ stale: 15, revalidate: 60, expire: 60 * 60 });
|
||||
const result = await getPublicTeamExport(teamId);
|
||||
if (result) cacheTag(pageCacheTag(result.guideId));
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getCachedPublicWeaponExport(guideId: string) {
|
||||
"use cache: remote";
|
||||
cacheLife({ stale: 15, revalidate: 60, expire: 60 * 60 });
|
||||
const result = await getPublicWeaponExport(guideId);
|
||||
cacheTag(pageCacheTag(guideId));
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function getCachedPublicArtifactExport(guideId: string) {
|
||||
"use cache: remote";
|
||||
cacheLife({ stale: 15, revalidate: 60, expire: 60 * 60 });
|
||||
const result = await getPublicArtifactExport(guideId);
|
||||
cacheTag(pageCacheTag(guideId));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export function artifactTierCount(secondName: string | null): 2 | 4 {
|
||||
return secondName ? 2 : 4;
|
||||
}
|
||||
@@ -175,6 +175,7 @@ export async function getPublicTeamExport(teamId: string) {
|
||||
|
||||
return {
|
||||
...row.team,
|
||||
guideId: row.guide.id,
|
||||
guideName: row.guide.name,
|
||||
members: members.map(({ member, character }) => {
|
||||
const weapon = weapons.find((item) => item.key === member.weaponKey);
|
||||
|
||||
@@ -113,6 +113,7 @@ export const extraSectionSchema = z.strictObject({
|
||||
title: z.string().trim().min(1).max(160),
|
||||
rows: z.array(z.strictObject({
|
||||
mediaId: z.string().uuid().nullable(),
|
||||
ratio: z.enum(["1:1", "16:9"]),
|
||||
heading: z.string().trim().min(1).max(200),
|
||||
body: z.string().trim().max(2_000),
|
||||
percent: percent.nullable(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { normalizeTalentPriorities, reorderTalentPriorities, talentRelationSymbol } from "@/lib/guides/talents";
|
||||
import { normalizeTalentPriorities, reorderTalentPriorities, talentRelationSymbol, talentTypeLabel } from "@/lib/guides/talents";
|
||||
|
||||
describe("talent priorities", () => {
|
||||
it("normalizes legacy talents to strict comparisons", () => {
|
||||
@@ -32,4 +32,10 @@ describe("talent priorities", () => {
|
||||
expect(talentRelationSymbol("gte")).toBe("≥");
|
||||
expect(talentRelationSymbol()).toBe(">");
|
||||
});
|
||||
|
||||
it("labels each talent type in Thai", () => {
|
||||
expect(talentTypeLabel("NA")).toBe("ตีปกติ");
|
||||
expect(talentTypeLabel("E")).toBe("สกิลธาตุ");
|
||||
expect(talentTypeLabel("Q")).toBe("ท่าไม้ตาย");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,3 +41,7 @@ export function reorderTalentPriorities(
|
||||
export function talentRelationSymbol(relation?: TalentRelation): ">" | "≥" {
|
||||
return relation === "gte" ? "≥" : ">";
|
||||
}
|
||||
|
||||
export function talentTypeLabel(type: TalentPriority["type"]): string {
|
||||
return type === "E" ? "สกิลธาตุ" : type === "Q" ? "ท่าไม้ตาย" : "ตีปกติ";
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
export function navigationIconPath(slug: string): string | null {
|
||||
if (slug === "overview") return "/icon/nav/Overview.webp";
|
||||
if (slug === "weapon") return "/icon/nav/Weapon.png";
|
||||
if (slug === "artifact") return "/icon/nav/Artifact.webp";
|
||||
if (slug === "constellations") return "/icon/nav/Constellations.webp";
|
||||
if (slug === "team") return "/icon/nav/Team-calc.webp";
|
||||
if (slug === "extra" || slug.startsWith("extra-")) return "/icon/nav/Extra.webp";
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user