Add types from numista openapi spec
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { readFile, readdir } from "fs/promises";
|
||||
import path from "path";
|
||||
|
||||
@@ -6,7 +6,7 @@ export const getCountryBanknotes = async (country: string) => {
|
||||
try {
|
||||
const banknoteIds = await readdir(path.join("./public/banknotes", country));
|
||||
|
||||
const banknotes: CoinProps[] = [];
|
||||
const banknotes: NumistaType[] = [];
|
||||
|
||||
for (const banknoteId of banknoteIds) {
|
||||
const banknote = await readFile(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { readFile, readdir } from "fs/promises";
|
||||
import path from "path";
|
||||
|
||||
@@ -6,7 +6,7 @@ export const getCountryCoins = async (country: string) => {
|
||||
try {
|
||||
const coinIds = await readdir(path.join("./public/coins", country));
|
||||
|
||||
const coins: CoinProps[] = [];
|
||||
const coins: NumistaType[] = [];
|
||||
|
||||
for (const coinId of coinIds) {
|
||||
const coin = await readFile(
|
||||
|
||||
@@ -1,17 +1,60 @@
|
||||
import * as THREE from "three";
|
||||
import { useLoader } from "@react-three/fiber";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { useMemo } from "react";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { Dispatch, SetStateAction, useEffect, useMemo, useState } from "react";
|
||||
|
||||
export const BanknoteInstance = ({ obverse, reverse }: CoinProps) => {
|
||||
const obverseTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
obverse.picture,
|
||||
);
|
||||
const reverseTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
reverse.picture,
|
||||
const SafeMaterial = ({
|
||||
url,
|
||||
bumpMap,
|
||||
setWidth,
|
||||
side,
|
||||
}: {
|
||||
url: string;
|
||||
bumpMap: THREE.Texture;
|
||||
setWidth?: Dispatch<SetStateAction<number>>;
|
||||
side: "obverse" | "reverse";
|
||||
}) => {
|
||||
const texture: THREE.Texture = useLoader(THREE.TextureLoader, url);
|
||||
|
||||
const index = useMemo(() => {
|
||||
switch (side) {
|
||||
case "obverse":
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return 5;
|
||||
}
|
||||
}, [side]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!setWidth) {
|
||||
return;
|
||||
}
|
||||
|
||||
setWidth(() => {
|
||||
try {
|
||||
return (2 * texture.source.data.width) / texture.source.data.height;
|
||||
} catch {
|
||||
return 4;
|
||||
}
|
||||
});
|
||||
}, [setWidth, texture]);
|
||||
|
||||
return (
|
||||
<meshStandardMaterial
|
||||
color={"#888"}
|
||||
map={texture}
|
||||
bumpMap={bumpMap}
|
||||
bumpScale={0.1}
|
||||
metalness={0}
|
||||
roughness={0.5}
|
||||
attach={"material-" + index}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const BanknoteInstance = ({ obverse, reverse }: NumistaType) => {
|
||||
const [width, setWidth] = useState(0);
|
||||
|
||||
const obverseBumpTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
@@ -26,17 +69,6 @@ export const BanknoteInstance = ({ obverse, reverse }: CoinProps) => {
|
||||
const reverseBumpTexture = obverseBumpTexture.clone();
|
||||
reverseBumpTexture.repeat = new THREE.Vector2(-1, 0.25);
|
||||
|
||||
const width = useMemo(() => {
|
||||
try {
|
||||
return (
|
||||
(2 * obverseTexture.source.data.width) /
|
||||
obverseTexture.source.data.height
|
||||
);
|
||||
} catch {
|
||||
return 4;
|
||||
}
|
||||
}, [obverseTexture]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<boxGeometry attach="geometry" args={[width, 2, 0.005]} />
|
||||
@@ -51,25 +83,40 @@ export const BanknoteInstance = ({ obverse, reverse }: CoinProps) => {
|
||||
/>
|
||||
))}
|
||||
|
||||
<meshStandardMaterial
|
||||
color={"#888"}
|
||||
map={obverseTexture}
|
||||
bumpMap={obverseBumpTexture}
|
||||
bumpScale={0.1}
|
||||
metalness={0}
|
||||
roughness={0.5}
|
||||
attach="material-4"
|
||||
/>
|
||||
{obverse?.picture ? (
|
||||
<SafeMaterial
|
||||
bumpMap={obverseBumpTexture}
|
||||
url={obverse.picture}
|
||||
side={"obverse"}
|
||||
setWidth={setWidth}
|
||||
/>
|
||||
) : (
|
||||
<meshStandardMaterial
|
||||
color={"#888"}
|
||||
bumpMap={obverseBumpTexture}
|
||||
bumpScale={0.1}
|
||||
metalness={0}
|
||||
roughness={0.5}
|
||||
attach="material-4"
|
||||
/>
|
||||
)}
|
||||
|
||||
<meshStandardMaterial
|
||||
color={"#888"}
|
||||
map={reverseTexture}
|
||||
bumpMap={reverseBumpTexture}
|
||||
bumpScale={0.1}
|
||||
metalness={0}
|
||||
roughness={0.5}
|
||||
attach="material-5"
|
||||
/>
|
||||
{reverse?.picture ? (
|
||||
<SafeMaterial
|
||||
bumpMap={reverseBumpTexture}
|
||||
url={reverse.picture}
|
||||
side={"reverse"}
|
||||
/>
|
||||
) : (
|
||||
<meshStandardMaterial
|
||||
color={"#888"}
|
||||
bumpMap={reverseBumpTexture}
|
||||
bumpScale={0.1}
|
||||
metalness={0}
|
||||
roughness={0.5}
|
||||
attach="material-5"
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useGLTF, useTexture } from "@react-three/drei";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
|
||||
export function BahamasCents10(coin: CoinProps) {
|
||||
export function BahamasCents10(coin: NumistaType) {
|
||||
// @ts-expect-error property `nodes` actually exists
|
||||
const { nodes } = useGLTF("/models/bahamas-cents-10.gltf");
|
||||
const texture = useTexture("/api/merge-textures/" + coin.id);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useGLTF, useTexture } from "@react-three/drei";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
|
||||
export function BahamasCents15(coin: CoinProps) {
|
||||
export function BahamasCents15(coin: NumistaType) {
|
||||
// @ts-expect-error property `nodes` actually exists
|
||||
const { nodes } = useGLTF("/models/bahamas-cents-15.gltf");
|
||||
const texture = useTexture("/api/merge-textures/" + coin.id);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useGLTF, useTexture } from "@react-three/drei";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
|
||||
export function EuroCents20(coin: CoinProps) {
|
||||
export function EuroCents20(coin: NumistaType) {
|
||||
// @ts-expect-error property `nodes` actually exists
|
||||
const { nodes } = useGLTF("/models/euro-cents-20.gltf");
|
||||
const texture = useTexture("/api/merge-textures/" + coin.id);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useGLTF, useTexture } from "@react-three/drei";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
|
||||
export function TostaoFurado(coin: CoinProps) {
|
||||
export function TostaoFurado(coin: NumistaType) {
|
||||
// @ts-expect-error property `nodes` actually exists
|
||||
const { nodes } = useGLTF("/models/tostao-furado.gltf");
|
||||
const texture = useTexture("/api/merge-textures/" + coin.id);
|
||||
|
||||
@@ -1,28 +1,62 @@
|
||||
import * as THREE from "three";
|
||||
import { useLoader } from "@react-three/fiber";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { EuroCents20 } from "./custom/euro-cents-20";
|
||||
import { BahamasCents15 } from "./custom/bahamas-cents-15";
|
||||
import { BahamasCents10 } from "./custom/bahamas-cents-10";
|
||||
import { TostaoFurado } from "./custom/tostao-furado";
|
||||
|
||||
const SafeEdgeMaterial = ({ edge }: Pick<CoinProps, "edge">) => {
|
||||
const edgeTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
edge.picture,
|
||||
);
|
||||
edgeTexture.repeat = new THREE.Vector2(4, 1);
|
||||
edgeTexture.offset = new THREE.Vector2(0.5, 0);
|
||||
edgeTexture.wrapS = THREE.MirroredRepeatWrapping;
|
||||
edgeTexture.wrapT = THREE.MirroredRepeatWrapping;
|
||||
const SafeMaterial = ({
|
||||
url,
|
||||
orientation,
|
||||
side,
|
||||
}: Pick<NumistaType, "orientation"> & {
|
||||
url: string;
|
||||
side: "edge" | "obverse" | "reverse";
|
||||
}) => {
|
||||
const texture: THREE.Texture = useLoader(THREE.TextureLoader, url);
|
||||
|
||||
const index = useMemo(() => {
|
||||
switch (side) {
|
||||
case "edge":
|
||||
return 0;
|
||||
|
||||
case "obverse":
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 2;
|
||||
}
|
||||
}, [side]);
|
||||
|
||||
useEffect(() => {
|
||||
switch (side) {
|
||||
case "edge":
|
||||
texture.repeat = new THREE.Vector2(4, 1);
|
||||
texture.offset = new THREE.Vector2(0.5, 0);
|
||||
texture.wrapS = THREE.MirroredRepeatWrapping;
|
||||
texture.wrapT = THREE.MirroredRepeatWrapping;
|
||||
break;
|
||||
|
||||
case "reverse":
|
||||
if (orientation === "medal") {
|
||||
texture.center = new THREE.Vector2(0.5, 0.5);
|
||||
texture.rotation = Math.PI;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}, [orientation, texture, side]);
|
||||
|
||||
return (
|
||||
<meshStandardMaterial
|
||||
map={edgeTexture}
|
||||
map={texture}
|
||||
metalness={1}
|
||||
roughness={0.5}
|
||||
attach="material-0"
|
||||
attach={"material-" + index}
|
||||
/>
|
||||
);
|
||||
};
|
||||
@@ -33,61 +67,49 @@ export const BaseCoin = ({
|
||||
obverse,
|
||||
reverse,
|
||||
edge,
|
||||
}: CoinProps) => {
|
||||
}: NumistaType) => {
|
||||
const sides = useMemo(() => {
|
||||
//const parsed = Number(/(\d+)/.exec(shape)?.[0]);
|
||||
//return Math.min(32, Math.max(4, isNaN(parsed) ? 32 : parsed));
|
||||
return 32;
|
||||
}, []);
|
||||
const obverseTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
obverse.picture,
|
||||
);
|
||||
const reverseTexture: THREE.Texture = useLoader(
|
||||
THREE.TextureLoader,
|
||||
reverse.picture,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (orientation === "medal") {
|
||||
reverseTexture.center = new THREE.Vector2(0.5, 0.5);
|
||||
reverseTexture.rotation = Math.PI;
|
||||
}
|
||||
}, [orientation, reverseTexture]);
|
||||
const defaultProps = {
|
||||
metalness: 1,
|
||||
roughness: 0.5,
|
||||
color,
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<cylinderGeometry attach="geometry" args={[1, 1, 1, sides]} />
|
||||
|
||||
{edge?.picture ? (
|
||||
<SafeEdgeMaterial edge={edge} />
|
||||
<SafeMaterial url={edge.picture} side={"edge"} />
|
||||
) : (
|
||||
<meshStandardMaterial
|
||||
metalness={1}
|
||||
roughness={0.5}
|
||||
color={color}
|
||||
attach="material-0"
|
||||
/>
|
||||
<meshStandardMaterial {...defaultProps} attach="material-0" />
|
||||
)}
|
||||
|
||||
<meshStandardMaterial
|
||||
metalness={1}
|
||||
roughness={0.5}
|
||||
map={obverseTexture}
|
||||
attach="material-1"
|
||||
/>
|
||||
{obverse?.picture ? (
|
||||
<SafeMaterial url={obverse.picture} side={"obverse"} />
|
||||
) : (
|
||||
<meshStandardMaterial {...defaultProps} attach="material-1" />
|
||||
)}
|
||||
|
||||
<meshStandardMaterial
|
||||
metalness={1}
|
||||
roughness={0.5}
|
||||
map={reverseTexture}
|
||||
attach="material-2"
|
||||
/>
|
||||
{reverse?.picture ? (
|
||||
<SafeMaterial
|
||||
url={reverse.picture}
|
||||
side={"reverse"}
|
||||
orientation={orientation}
|
||||
/>
|
||||
) : (
|
||||
<meshStandardMaterial {...defaultProps} attach="material-2" />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export const CoinInstance = (coin: CoinProps) => {
|
||||
export const CoinInstance = (coin: NumistaType) => {
|
||||
if (
|
||||
coin.value?.numeric_value === 0.2 &&
|
||||
coin.value?.currency?.name === "Euro"
|
||||
@@ -98,6 +120,7 @@ export const CoinInstance = (coin: CoinProps) => {
|
||||
if (
|
||||
coin.value?.numeric_value === 25 &&
|
||||
coin.value?.currency?.name === "Peseta" &&
|
||||
coin.min_year &&
|
||||
coin.min_year >= 1990
|
||||
) {
|
||||
return <TostaoFurado {...coin} />;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { CoinInstance } from "../coin";
|
||||
import { useEffect, useRef } from "react";
|
||||
import { InstancedMesh } from "three";
|
||||
import { useCylinder } from "@react-three/cannon";
|
||||
|
||||
export const CoinInstances = (coinProps: CoinProps) => {
|
||||
export const CoinInstances = (coinProps: NumistaType) => {
|
||||
const didInit = useRef(false);
|
||||
const { count = 1, size = 16, thickness = 2, weight = 4 } = coinProps;
|
||||
|
||||
|
||||
@@ -2,14 +2,14 @@ import { Canvas, SpotLightProps } from "@react-three/fiber";
|
||||
import { OrbitControls } from "@react-three/drei";
|
||||
import { useRef } from "react";
|
||||
import { CoinInstances } from "./coin-instances";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { PlaneProps, Physics, usePlane } from "@react-three/cannon";
|
||||
import { Mesh, Vector3 } from "three";
|
||||
import styles from "./index.module.css";
|
||||
import { StageLightModel } from "./stage-light-model";
|
||||
|
||||
type Props = {
|
||||
coins: CoinProps[];
|
||||
coins: NumistaType[];
|
||||
};
|
||||
|
||||
const Plane = (props: PlaneProps) => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import styles from "./index.module.css";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { useEffect } from "react";
|
||||
import { InfoBox } from "./info-box";
|
||||
@@ -9,7 +9,7 @@ import { useShowcaseStore } from "./store";
|
||||
|
||||
type Props = {
|
||||
category: "coins" | "banknotes";
|
||||
types: CoinProps[];
|
||||
types: NumistaType[];
|
||||
};
|
||||
|
||||
export const Showcase = (props: Props) => {
|
||||
|
||||
@@ -50,7 +50,7 @@ export const InfoBox = () => {
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<small>{issuer.name}</small>
|
||||
<small>{issuer?.name}</small>
|
||||
<h1 style={{ textAlign: "center" }}>{title}</h1>
|
||||
<p>{min_year !== max_year ? min_year + " - " + max_year : min_year}</p>
|
||||
<small>{(count ?? 1) + " in collection"}</small>
|
||||
|
||||
@@ -4,14 +4,14 @@ import { CoinInstance } from "@/components/coin";
|
||||
import { Mesh } from "three";
|
||||
import { BanknoteInstance } from "@/components/banknote";
|
||||
import { useShowcaseStore } from "./store";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
|
||||
const SpinninType = ({
|
||||
typeProps,
|
||||
isSelected,
|
||||
...props
|
||||
}: MeshProps & {
|
||||
typeProps?: CoinProps;
|
||||
typeProps?: NumistaType;
|
||||
isSelected?: boolean;
|
||||
}) => {
|
||||
const ref = useRef<Mesh>(null!);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { create } from "zustand";
|
||||
import { OrbitControls } from "three-stdlib";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { MutableRefObject, createRef } from "react";
|
||||
|
||||
type Props = { category: "coins" | "banknotes"; types: CoinProps[] };
|
||||
type Props = { category: "coins" | "banknotes"; types: NumistaType[] };
|
||||
|
||||
interface ShowcaseStore {
|
||||
currentIndex: number;
|
||||
@@ -15,10 +15,10 @@ interface ShowcaseStore {
|
||||
orbitControlsRef: MutableRefObject<OrbitControls | null>;
|
||||
setOrbitControlsRef: (ref: OrbitControls | null) => void;
|
||||
toggleSpin: () => void;
|
||||
types: CoinProps[];
|
||||
types: NumistaType[];
|
||||
category: Props["category"] | null;
|
||||
init: (props: Props) => void;
|
||||
getType: (index?: number) => CoinProps | undefined;
|
||||
getType: (index?: number) => NumistaType | undefined;
|
||||
}
|
||||
|
||||
export const useShowcaseStore = create<ShowcaseStore>((set, get) => ({
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { NumistaType } from "@/types/numista";
|
||||
|
||||
export const sortTypes = (types: NumistaType[]) =>
|
||||
types
|
||||
.sort((a, b) => {
|
||||
if (a.value?.numeric_value && b.value?.numeric_value) {
|
||||
return a.value.numeric_value - b.value.numeric_value;
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (a.value?.currency?.full_name && b.value?.currency?.full_name) {
|
||||
return a.value.currency.full_name.localeCompare(
|
||||
b.value.currency.full_name,
|
||||
);
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (a.issuer && b.issuer) {
|
||||
return a.issuer.name.localeCompare(b.issuer.name);
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (a.max_year && b.max_year) {
|
||||
return a.max_year - b.max_year;
|
||||
}
|
||||
return 0;
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (a.min_year && b.min_year) {
|
||||
return a.min_year - b.min_year;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
@@ -1,17 +1,18 @@
|
||||
import Head from "next/head";
|
||||
import { GetStaticPaths, GetStaticProps, NextPage } from "next";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { readdir } from "fs/promises";
|
||||
import { Showcase } from "@/components/showcase";
|
||||
import { Header } from "@/components/header";
|
||||
import { getCountryBanknotes } from "@/api/banknotes/get-country-banknotes";
|
||||
import { getCountryCoins } from "@/api/coins/get-country-coins";
|
||||
import { sortTypes } from "@/core/utils/numista";
|
||||
|
||||
type Props = {
|
||||
country: string;
|
||||
coinCount: number;
|
||||
banknoteCount: number;
|
||||
banknotes: CoinProps[];
|
||||
banknotes: NumistaType[];
|
||||
};
|
||||
|
||||
const BanknotesPage: NextPage<Props> = ({ banknotes, ...props }) => (
|
||||
@@ -53,7 +54,7 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
|
||||
(total, banknote) => total + (banknote.count ?? 1),
|
||||
0,
|
||||
),
|
||||
banknotes: banknotes.sort((a, b) => a.min_year - b.min_year),
|
||||
banknotes: sortTypes(banknotes),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import Head from "next/head";
|
||||
import { GetStaticPaths, GetStaticProps, NextPage } from "next";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { readdir } from "fs/promises";
|
||||
import { Showcase } from "@/components/showcase";
|
||||
import { Header } from "@/components/header";
|
||||
import { getCountryBanknotes } from "@/api/banknotes/get-country-banknotes";
|
||||
import { getCountryCoins } from "@/api/coins/get-country-coins";
|
||||
import { sortTypes } from "@/core/utils/numista";
|
||||
|
||||
type Props = {
|
||||
country: string;
|
||||
coinCount: number;
|
||||
banknoteCount: number;
|
||||
coins: CoinProps[];
|
||||
coins: NumistaType[];
|
||||
};
|
||||
|
||||
const CoinsPage: NextPage<Props> = ({ coins, ...props }) => (
|
||||
@@ -53,7 +54,7 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
|
||||
0,
|
||||
),
|
||||
coinCount: coins.reduce((total, coin) => total + (coin.count ?? 1), 0),
|
||||
coins: coins.sort((a, b) => a.min_year - b.min_year),
|
||||
coins: sortTypes(coins),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
import Head from "next/head";
|
||||
import { Pile } from "@/components/pile";
|
||||
import { GetStaticPaths, GetStaticProps, NextPage } from "next";
|
||||
import { CoinProps } from "@/types/coin";
|
||||
import { NumistaType } from "@/types/numista";
|
||||
import { readdir } from "fs/promises";
|
||||
import { Header } from "@/components/header";
|
||||
import { getCountryBanknotes } from "@/api/banknotes/get-country-banknotes";
|
||||
import { getCountryCoins } from "@/api/coins/get-country-coins";
|
||||
import { sortTypes } from "@/core/utils/numista";
|
||||
|
||||
type Props = {
|
||||
country: string;
|
||||
coinCount: number;
|
||||
banknoteCount: number;
|
||||
coins: CoinProps[];
|
||||
coins: NumistaType[];
|
||||
};
|
||||
|
||||
const PilePage: NextPage<Props> = ({ coins, ...props }) => (
|
||||
@@ -53,7 +54,7 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
|
||||
0,
|
||||
),
|
||||
coinCount: coins.reduce((total, coin) => total + (coin.count ?? 1), 0),
|
||||
coins: coins.sort((a, b) => a.min_year - b.min_year),
|
||||
coins: sortTypes(coins),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
type Face = {
|
||||
engravers: string[];
|
||||
description: string;
|
||||
lettering: string;
|
||||
lettering_scripts: Array<{
|
||||
name: string;
|
||||
}>;
|
||||
picture: string;
|
||||
thumbnail: string;
|
||||
picture_copyright: string;
|
||||
};
|
||||
|
||||
export type CoinProps = {
|
||||
id: number;
|
||||
url: string;
|
||||
title: string;
|
||||
category: "banknote" | "coin" | "exonumia";
|
||||
issuer: {
|
||||
code: string;
|
||||
name: string;
|
||||
};
|
||||
min_year: number;
|
||||
max_year: number;
|
||||
type: string;
|
||||
ruler: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
wikidata_id: string;
|
||||
}>;
|
||||
value: {
|
||||
text: string;
|
||||
numeric_value: number;
|
||||
currency: {
|
||||
id: number;
|
||||
name: string;
|
||||
full_name: string;
|
||||
};
|
||||
};
|
||||
demonetization: {
|
||||
is_demonetized: boolean;
|
||||
};
|
||||
shape: string;
|
||||
composition: {
|
||||
text: string;
|
||||
};
|
||||
technique: {
|
||||
text: string;
|
||||
};
|
||||
obverse: Face;
|
||||
reverse: Face;
|
||||
comments: string;
|
||||
references: Array<{
|
||||
catalogue: {
|
||||
id: number;
|
||||
code: string;
|
||||
};
|
||||
number: string;
|
||||
}>;
|
||||
weight: number;
|
||||
size: number;
|
||||
thickness: number;
|
||||
orientation: "medal" | "coin";
|
||||
edge: {
|
||||
description: string;
|
||||
picture: string;
|
||||
thumbnail: string;
|
||||
picture_copyright: string;
|
||||
};
|
||||
mints: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
}>;
|
||||
count?: number;
|
||||
color?: string;
|
||||
};
|
||||
@@ -0,0 +1,204 @@
|
||||
export type NumistaCategory = "coin" | "banknote" | "exonumia";
|
||||
|
||||
export interface NumistaType {
|
||||
/** @description Unique ID of the type on Numista */
|
||||
id: number;
|
||||
/** @description URL to the type on Numista */
|
||||
url?: string;
|
||||
/** @description Title of the type */
|
||||
title: string;
|
||||
/**
|
||||
* @description Category
|
||||
* @enum {string}
|
||||
*/
|
||||
category: NumistaCategory;
|
||||
issuer?: Issuer;
|
||||
/** @description First year the type was produced (in the Gregorian calendar). */
|
||||
min_year?: number;
|
||||
/** @description Last year the type was produced (in the Gregorian calendar). */
|
||||
max_year?: number;
|
||||
/** @description Type */
|
||||
type?: string;
|
||||
/** @description Face value */
|
||||
value?: {
|
||||
/** @description Face value in text format */
|
||||
text?: string;
|
||||
/**
|
||||
* Format: float
|
||||
* @description Face value as a floating number.
|
||||
*/
|
||||
numeric_value?: number;
|
||||
/** @description If the value is better described as a fraction, this is the numerator of the fraction */
|
||||
numerator?: number;
|
||||
/** @description If the value is better described as a fraction, this is the denominator of the fraction */
|
||||
denominator?: number;
|
||||
currency?: Currency;
|
||||
};
|
||||
/** @description Ruling authorities (emperor, queen, period, etc.) */
|
||||
ruler?: {
|
||||
/** @description Unique ID of the ruling authority on Numista */
|
||||
id: number;
|
||||
/** @description Name of the ruling authority */
|
||||
name: string;
|
||||
/** @description Identifier of the ruling authority at Wikidata, starting with a "Q" */
|
||||
wikidata_id?: string;
|
||||
/** @description Dynasty, house, extended period, or any other group of ruling authorities */
|
||||
group?: {
|
||||
/** @description Unique ID of the ruling authority group on Numista */
|
||||
id: number;
|
||||
/** @description Name of the ruling authority group */
|
||||
name: string;
|
||||
};
|
||||
}[];
|
||||
/** @description Information about the demonetization of the coin or banknote */
|
||||
demonetization?: {
|
||||
/** @description True if the type is demonetized, false if it is not demonetized */
|
||||
is_demonetized: boolean;
|
||||
/**
|
||||
* Format: date
|
||||
* @description Date of demonetisation (YYYY-MM-DD)
|
||||
*/
|
||||
demonetization_date?: string;
|
||||
};
|
||||
/** @description Shape */
|
||||
shape?: string;
|
||||
/** @description Composition (metallic content) */
|
||||
composition?: {
|
||||
/** @description Description of the composition */
|
||||
text?: string;
|
||||
};
|
||||
/** @description Manufacturing technique */
|
||||
technique?: {
|
||||
/** @description Description of the technique */
|
||||
text?: string;
|
||||
};
|
||||
/**
|
||||
* Format: float
|
||||
* @description Weight in grams
|
||||
*/
|
||||
weight?: number;
|
||||
/**
|
||||
* Format: float
|
||||
* @description Size (diameter) in millimeters
|
||||
*/
|
||||
size?: number;
|
||||
/**
|
||||
* Format: float
|
||||
* @description Thickness of the coin in millimeters
|
||||
*/
|
||||
thickness?: number;
|
||||
/**
|
||||
* @description Orientation of the coin ("coin", "medal", "three" (3 o'clock), "nine" (9 o'clock), or "variable")
|
||||
* @enum {string}
|
||||
*/
|
||||
orientation?: "coin" | "medal" | "variable" | "three" | "nine";
|
||||
obverse?: CoinSide;
|
||||
reverse?: CoinSide;
|
||||
edge?: CoinSide;
|
||||
watermark?: CoinSide;
|
||||
/** @description Mints where the coin was minted */
|
||||
mints?: {
|
||||
/** @description Unique ID of the mint on Numista */
|
||||
id: number;
|
||||
/** @description Name of the mint */
|
||||
name: string;
|
||||
}[];
|
||||
/** @description Printers where the banknote was printed */
|
||||
printers?: {
|
||||
/** @description Unique ID of the printer on Numista */
|
||||
id: number;
|
||||
/** @description Name of the printer */
|
||||
name: string;
|
||||
}[];
|
||||
/** @description For types which are part of a series, the name of the series */
|
||||
series?: string;
|
||||
/** @description For commemorated types, short description of the commemorated topic (event, person, etc.) */
|
||||
commemorated_topic?: string;
|
||||
/** @description General comments about the type (HTML format) */
|
||||
comments?: string;
|
||||
/** @description List of related types */
|
||||
related_types?: {
|
||||
/** @description Unique ID of the type on Numista */
|
||||
id: number;
|
||||
/** @description Title of the type */
|
||||
title: string;
|
||||
/**
|
||||
* @description Category
|
||||
* @enum {string}
|
||||
*/
|
||||
category?: "coin" | "banknote" | "exonumia";
|
||||
issuer?: Issuer;
|
||||
/** @description First year the type was producted (in the Gregorian calendar). */
|
||||
min_year?: number;
|
||||
/** @description Last year the type was producted (in the Gregorian calendar). */
|
||||
max_year?: number;
|
||||
}[];
|
||||
/** @description List of tags */
|
||||
tags?: string[];
|
||||
/** @description References of the type in other catalogues */
|
||||
references?: Reference[];
|
||||
/** @description How many of this type are included in my personal collection */
|
||||
count?: number;
|
||||
/** @description Dominant color calculated from the pictures */
|
||||
color: string;
|
||||
}
|
||||
|
||||
interface Issuer {
|
||||
/** @description Unique ID of the issuer on Numista */
|
||||
code: string;
|
||||
/** @description Name of the issuer */
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Currency {
|
||||
/** @description Unique ID of the currency on Numista */
|
||||
id: number;
|
||||
/** @description Name of the currency */
|
||||
name: string;
|
||||
/** @description Full name of the currency, including dates */
|
||||
full_name: string;
|
||||
}
|
||||
|
||||
interface Reference {
|
||||
/** @description The catalogue in which the reference can be found */
|
||||
catalogue: {
|
||||
/** @description ID of the catalogue in Numista */
|
||||
id: number;
|
||||
/** @description Code identifying the catalogue */
|
||||
code: string;
|
||||
};
|
||||
/** @description Number of the coin in the catalogue */
|
||||
number: string;
|
||||
}
|
||||
|
||||
export interface CoinSide {
|
||||
/** @description Name of the engraver(s) */
|
||||
engravers?: string[];
|
||||
/** @description Name of the designer(s) */
|
||||
designers?: string[];
|
||||
/** @description Description of the side of the coin */
|
||||
description?: string;
|
||||
/** @description Lettering visible on the side of the coin */
|
||||
lettering?: string;
|
||||
/** @description Scripts used to write the lettering on the side of the coins */
|
||||
lettering_scripts?: {
|
||||
/** @description Name of the script */
|
||||
name: string;
|
||||
}[];
|
||||
/** @description Legend visible on the side of the coin with abbreviations replaced by full words */
|
||||
unabridged_legend?: string;
|
||||
/** @description Translation of the lettering visible on the side of the coin */
|
||||
lettering_translation?: string;
|
||||
/** @description URL to the picture of the side of the coin */
|
||||
picture?: string;
|
||||
/** @description URL to the thumbnail of the picture of the side of the coin */
|
||||
thumbnail?: string;
|
||||
/** @description Name of the owner of the picture. Pictures should not be used without consent from their owner. */
|
||||
picture_copyright?: string;
|
||||
/** @description URL to the website of the owner of the picture. Pictures should not be used without consent from their owner. */
|
||||
picture_copyright_url?: string;
|
||||
/** @description Name of the license of the picture, if the owner of the picture specified a license. */
|
||||
picture_license_name?: string;
|
||||
/** @description URL to the license of the picture, if the owner of the picture specified a license. */
|
||||
picture_license_url?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user