Skip to content

Commit

Permalink
Merge pull request #405 from rl404/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
rl404 authored Aug 17, 2024
2 parents a01c96e + ae35df9 commit 906fc44
Show file tree
Hide file tree
Showing 22 changed files with 181 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/lib/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export const DefaultVtubersQuery: VtubersQuery = {
character_2d_modeler: '',
character_3d_modeler: '',
in_agency: undefined,
agency: '',
agency_id: '',
language_id: '',
channel_types: '',
birthday_day: '',
start_birthday_month: '',
Expand Down
3 changes: 2 additions & 1 deletion src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ export type VtubersQuery = {
character_2d_modeler: string;
character_3d_modeler: string;
in_agency?: boolean;
agency: string;
agency_id: string;
language_id: string;
channel_types: string;
birthday_day: string;
start_birthday_month: string;
Expand Down
10 changes: 10 additions & 0 deletions src/routes/(app)/statistics/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import VtuberCountByDesignerChart from './VtuberCountByDesignerChart.svelte';
import VtuberCountByGenderChart from './VtuberCountByGenderChart.svelte';
import VtuberCountByInAgencyChart from './VtuberCountByInAgencyChart.svelte';
import VtuberCountByLanguageChart from './VtuberCountByLanguageChart.svelte';
import VtuberCountByStatusChart from './VtuberCountByStatusChart.svelte';
import VtuberCountBySubsChart from './VtuberCountBySubsChart.svelte';
import VtuberCountByZodiacChart from './VtuberCountByZodiacChart.svelte';
Expand Down Expand Up @@ -140,6 +141,15 @@
<Card title="Average Vtuber Weight" class="col-span-6 md:col-span-3">
<VtuberAvgWeight />
</Card>
<Card title="Vtuber Count by Language" class="col-span-6 hidden aspect-chart 2xl:block">
<VtuberCountByLanguageChart />
</Card>
<Card title="Vtuber Count by Language" class="col-span-6 hidden aspect-chart md:block 2xl:hidden">
<VtuberCountByLanguageChart limit={10} />
</Card>
<Card title="Vtuber Count by Language" class="col-span-6 aspect-chart md:hidden">
<VtuberCountByLanguageChart limit={5} />
</Card>
<Card title="Vtuber Count by Blood Type" class="col-span-6 aspect-video md:col-span-3">
<VtuberCountByBloodChart />
</Card>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/(app)/statistics/AgencyMostSubsChart.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@
horizontal
xaxisFormatter={(v) => compactInt(parseInt(v))}
tooltipYFormatter={(v) => (!v ? '0' : compactInt(v))}
on:click={onClick}
on:clickArea={onClick}
/>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
{:else if error !== ''}
<div class="flex h-full w-full items-center justify-center text-red-500">{error}</div>
{:else}
<BarChart {data} horizontal on:click={onClick} />
<BarChart {data} horizontal on:clickArea={onClick} />
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
{:else if error !== ''}
<div class="flex h-full w-full items-center justify-center text-red-500">{error}</div>
{:else}
<BarChart {data} horizontal on:click={onClick} />
<BarChart {data} horizontal on:clickArea={onClick} />
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@
data={data.map((d) => ({ name: d.name, value: d.member }))}
horizontal
seriesName="Members"
on:click={onClick}
on:clickArea={onClick}
/>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@
{:else if error !== ''}
<div class="flex h-full w-full items-center justify-center text-red-500">{error}</div>
{:else}
<BarChart {data} horizontal on:click={onClick} />
<BarChart {data} horizontal on:clickArea={onClick} />
{/if}
42 changes: 42 additions & 0 deletions src/routes/(app)/statistics/VtuberCountByLanguageChart.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<script lang="ts">
import BarChart from '$lib/components/charts/BarChart.svelte';
import { getAxiosError } from '$lib/utils/api';
import axios from 'axios';
import { Spinner } from 'flowbite-svelte';
import { onMount } from 'svelte';
import type { VtuberLanguageCountResponseData } from '../../api/statistics/vtubers/language-count/+server';
export let limit: number = -1;
let data: VtuberLanguageCountResponseData[];
let loading: boolean = true;
let error: string = '';
onMount(() => {
axios
.get(`/api/statistics/vtubers/language-count`)
.then((resp) => (data = resp.data.data.slice(0, limit)))
.catch((err) => (error = getAxiosError(err)))
.finally(() => (loading = false));
});
const onClick = (d: any) =>
window.open(`/vtubers?language_id=${data[d.detail].id}`, '_blank')?.focus();
</script>

{#if loading}
<div class="flex h-full w-full items-center justify-center">
<Spinner />
</div>
{:else if error !== ''}
<div class="flex h-full w-full items-center justify-center text-red-500">{error}</div>
{:else}
<BarChart
data={data.map((d) => ({
name: d.name,
value: d.count
}))}
seriesName="Count"
on:clickArea={onClick}
/>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@
(1000 * 3600 * 24 * 30 * 12)
}))}
seriesName="Years"
on:click={onClick}
on:clickArea={onClick}
/>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@
horizontal
xaxisFormatter={(v) => intToDurationStr(parseInt(v))}
tooltipYFormatter={(v) => (!v ? '0' : intToDurationStr(v))}
on:click={onClick}
on:clickArea={onClick}
/>
{/if}
2 changes: 1 addition & 1 deletion src/routes/(app)/statistics/VtuberMostSubsChart.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@
horizontal
xaxisFormatter={(v) => compactInt(parseInt(v))}
tooltipYFormatter={(v) => (!v ? '0' : compactInt(v))}
on:click={onClick}
on:clickArea={onClick}
/>
{/if}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,6 @@
<BarChart
data={data.map((d) => ({ name: d.name, value: d.video_count }))}
horizontal
on:click={onClick}
on:clickArea={onClick}
/>
{/if}
6 changes: 5 additions & 1 deletion src/routes/(app)/vtubers/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { SHIMAKAZE_HOST } from '$env/static/private';
import { handleAPIResponse } from '$lib/utils/api';
import type { AgenciesResponse } from '../../api/agencies/+server';
import type { LanguagesResponse } from '../../api/languages/+server';
import type { BaseAPIResponse } from '../../api/types';
import type { PageServerLoad } from './$types';

export type VtuberSearchResponse = {
agencies: AgenciesResponse;
languages: LanguagesResponse;
characterDesigners: VtuberCharacterDesignersResponse;
character2dModelers: VtuberCharacterDesignersResponse;
character3dModelers: VtuberCharacterDesignersResponse;
Expand All @@ -22,15 +24,17 @@ export const config = {
};

export const load = (async () => {
const [agenciesResp, characterDesignersResp, character2dResp, character3dResp] =
const [agenciesResp, languagesResp, characterDesignersResp, character2dResp, character3dResp] =
await Promise.all([
await fetch(`${SHIMAKAZE_HOST}/agencies?limit=-1`),
await fetch(`${SHIMAKAZE_HOST}/languages`),
await fetch(`${SHIMAKAZE_HOST}/vtubers/character-designers`),
await fetch(`${SHIMAKAZE_HOST}/vtubers/character-2d-modelers`),
await fetch(`${SHIMAKAZE_HOST}/vtubers/character-3d-modelers`)
]);
return {
agencies: await handleAPIResponse(agenciesResp),
languages: await handleAPIResponse(languagesResp),
characterDesigners: await handleAPIResponse(characterDesignersResp),
character2dModelers: await handleAPIResponse(character2dResp),
character3dModelers: await handleAPIResponse(character3dResp)
Expand Down
13 changes: 10 additions & 3 deletions src/routes/(app)/vtubers/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@
params.get('in_agency') === null || params.get('in_agency') === ''
? undefined
: params.get('in_agency') === 'true',
agency: params.get('agency') || '',
agency_id: params.get('agency_id') || '',
language_id: params.get('language_id') || '',
channel_types: params.get('channel_types') || '',
birthday_day: params.get('birthday_day') || '',
start_birthday_month: params.get('start_birthday_month') || '',
Expand Down Expand Up @@ -165,15 +166,21 @@
{loading}
bind:query
on:submit={onSearch}
agencies={data.agencies.data.map((a) => a.name)}
agencies={data.agencies.data}
languages={data.languages.data}
characterDesigners={data.characterDesigners.data}
character2dModelers={data.character2dModelers.data}
character3dModelers={data.character3dModelers.data}
/>
</div>
</div>
<div class="flex items-center justify-between gap-2">
<QueryBadges bind:query on:change={onSearch} />
<QueryBadges
bind:query
on:change={onSearch}
agencies={data.agencies.data}
languages={data.languages.data}
/>
<div class="flex items-center gap-2">
<VtuberSortButton bind:value={query.sort} on:change={onSearch} class="hidden sm:flex" />
<span class="hidden opacity-50 sm:block">|</span>
Expand Down
14 changes: 14 additions & 0 deletions src/routes/(app)/vtubers/QueryBadges.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@
import { compactInt, toTitleCase } from '$lib/utils/utils';
import { Badge } from 'flowbite-svelte';
import { createEventDispatcher } from 'svelte';
import type { AgencyResponseData } from '../../api/agencies/[id]/+server';
import type { LanguageResponseData } from '../../api/languages/+server';
const dispatch = createEventDispatcher<{ change: null }>();
export let query: VtubersQuery;
export let agencies: AgencyResponseData[];
export let languages: LanguageResponseData[];
const onClose = (name: keyof VtubersQuery, value: any, callDispatch = true) => {
query = { ...query, [name]: value };
Expand Down Expand Up @@ -127,6 +131,11 @@
{#if query.in_agency === false}
<Badge dismissable on:close={() => onClose('in_agency', undefined)}>Independent</Badge>
{/if}
{#if query.agency_id !== ''}
<Badge dismissable on:close={() => onClose('agency_id', '')}>
Agency: {agencies.find((a) => a.id.toString() === query.agency_id)?.name}
</Badge>
{/if}
{#if query.channel_types !== ''}
{#each query.channel_types.split(',') as channel, i}
<Badge dismissable>
Expand Down Expand Up @@ -154,6 +163,11 @@
{MonthNames[parseInt(query.start_birthday_month) - 1]}
</Badge>
{/if}
{#if query.language_id !== ''}
<Badge dismissable on:close={() => onClose('language_id', '')}>
Language: {languages.find((l) => l.id.toString() === query.language_id)?.name}
</Badge>
{/if}
{#if query.blood_types !== ''}
<Badge dismissable on:close={() => onClose('blood_types', '')}>
Blood: {query.blood_types}
Expand Down
25 changes: 22 additions & 3 deletions src/routes/(app)/vtubers/SearchModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import type { VtubersQuery } from '$lib/types';
import { Button, Input, Label, Modal, Select, Tooltip } from 'flowbite-svelte';
import { createEventDispatcher } from 'svelte';
import type { AgencyResponseData } from '../../api/agencies/[id]/+server';
import type { LanguageResponseData } from '../../api/languages/+server';
import InputBirthday from './InputBirthday.svelte';
import InputChannel from './InputChannel.svelte';
import InputStatus from './InputStatus.svelte';
Expand All @@ -13,7 +15,8 @@
export let query: VtubersQuery;
export let loading: boolean;
export let agencies: string[];
export let agencies: AgencyResponseData[];
export let languages: LanguageResponseData[];
export let characterDesigners: string[];
export let character2dModelers: string[];
export let character3dModelers: string[];
Expand Down Expand Up @@ -84,8 +87,11 @@
id="agency"
size="sm"
placeholder=""
items={[{ name: 'any', value: '' }, ...agencies.map((a) => ({ name: a, value: a }))]}
bind:value={query.agency}
items={[
{ name: 'any', value: '' },
...agencies.map((a) => ({ name: a.name, value: a.id.toString() }))
]}
bind:value={query.agency_id}
/>
</div>
<div class="grid grid-cols-2 gap-2">
Expand Down Expand Up @@ -164,6 +170,19 @@
bind:endBirthdayMonth={query.end_birthday_month}
/>
</div>
<div class="grid gap-2">
<Label for="language">Language</Label>
<Select
id="language"
size="sm"
placeholder=""
items={[
{ name: 'any', value: '' },
...languages.map((a) => ({ name: a.name, value: a.id.toString() }))
]}
bind:value={query.language_id}
/>
</div>
<div class="grid gap-2">
<Label for="gender">Gender</Label>
<Input
Expand Down
10 changes: 10 additions & 0 deletions src/routes/(app)/vtubers/[id]/[...name]/Details.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@
{/each}
{/if}
</div>
<div>
<h4 class="font-bold">Languages</h4>
{#if isEmptyArray(vtuber.languages)}
<P>-</P>
{:else}
{#each vtuber.languages as language}
<P>{language.name}</P>
{/each}
{/if}
</div>
</div>
</Card>

Expand Down
25 changes: 25 additions & 0 deletions src/routes/api/languages/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { SHIMAKAZE_HOST } from '$env/static/private';
import type { RequestHandler } from './$types';
import type { BaseAPIResponse, MetaAPIResponse } from '../types';

export type LanguagesResponse = BaseAPIResponse & {
data: LanguageResponseData[];
meta: MetaAPIResponse;
};

export type LanguageResponseData = {
id: number;
name: string;
};

export const GET = (async () => {
const resp = await fetch(`${SHIMAKAZE_HOST}/languages`);
const data = await resp.json();
return new Response(JSON.stringify(data), {
headers: {
'content-type': 'application/json',
'cache-control': 'max-age=86400, s-maxage=86400, stale-while-revalidate=86400'
},
status: resp.status
});
}) satisfies RequestHandler;
25 changes: 25 additions & 0 deletions src/routes/api/statistics/vtubers/language-count/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { RequestHandler } from './$types';
import { SHIMAKAZE_HOST } from '$env/static/private';
import type { BaseAPIResponse } from '../../../types';

export type VtuberLanguageCountResponse = BaseAPIResponse & {
data: VtuberLanguageCountResponseData[];
};

export type VtuberLanguageCountResponseData = {
id: number;
name: string;
count: number;
};

export const GET = (async () => {
const resp = await fetch(`${SHIMAKAZE_HOST}/statistics/vtubers/language-count`);
const data = await resp.json();
return new Response(JSON.stringify(data), {
headers: {
'content-type': 'application/json',
'cache-control': 'max-age=86400, s-maxage=86400, stale-while-revalidate=86400'
},
status: resp.status
});
}) satisfies RequestHandler;
2 changes: 1 addition & 1 deletion src/routes/api/vtubers/+server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export const GET = (async ({ url }) => {
'character_2d_modeler',
'character_3d_modeler',
'in_agency',
'agency',
'agency_id',
'language_id',
'channel_types',
'birthday_day',
'start_birthday_month',
Expand Down
Loading

0 comments on commit 906fc44

Please sign in to comment.