Skip to content

Commit 73944a3

Browse files
committed
added models + response + home + season
1 parent 4f0ae63 commit 73944a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+931
-52
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script setup lang="ts">
2+
3+
defineProps<{
4+
}>()
5+
6+
</script>
7+
8+
<template>
9+
<div></div>
10+
</template>

src/features/home/data-access/homeService.ts

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,44 @@
1-
import axios from 'axios'
2-
import { app } from '@/main'
1+
import axios from '@/middleware/axios-config'
32
import type { HomeRecommendation } from '@/shared/data-access/models/homeRecommendation'
43
import type { Review } from '@/shared/data-access/models/review'
4+
import type { Media } from '@/shared/data-access/models/media'
55

6-
axios.interceptors.response.use(
7-
(response) => {
8-
return response
9-
},
10-
(error) => {
11-
console.error('HTTP error occurred:', error)
12-
app.config.globalProperties.$toast.add({
13-
severity: 'error',
14-
summary: 'Error',
15-
detail: error,
16-
life: 3000
17-
})
6+
const BASE_URL = 'https://api.jikan.moe/v4'
187

19-
return Promise.reject(error)
20-
}
21-
)
8+
const TOP_ANIME_PARAMS: TopAnimeQuery = {
9+
filter: 'airing',
10+
sfw: true,
11+
limit: 10,
12+
page: 1
13+
}
2214

23-
const BASE_URL = 'https://api.jikan.moe/v4'
15+
interface TopAnimeQuery {
16+
filter: string
17+
sfw: boolean
18+
limit: number
19+
page: number
20+
}
2421

2522
export const getTopAiringAnimes = async () => {
2623
try {
27-
const res = await axios.get(`${BASE_URL}/top/anime`)
28-
return res.data
24+
const res = await axios.get(`${BASE_URL}/top/anime`, { params: TOP_ANIME_PARAMS })
25+
const topAiringAnimes: Media[] = res.data.data.map(
26+
(item: any) =>
27+
({
28+
id: item.mal_id,
29+
title: item.title,
30+
titleEnglish: item.title_english,
31+
from: item.aired?.from,
32+
episodes: item.episodes,
33+
imageSrc: item.images.jpg.image_url,
34+
synopsis: item.synopsis,
35+
score: item.score,
36+
members: item.members,
37+
genres: item.genres.map((r: any) => r.name),
38+
imageLargeSrc: item.images.jpg.large_image_url
39+
}) satisfies Media
40+
)
41+
return topAiringAnimes
2942
} catch (error) {
3043
console.error('Error fetching top airing animes:', error)
3144
throw error

src/features/home/views/HomeView.vue

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@ import { useQuery } from '@tanstack/vue-query';
44
import { getTopAiringAnimes, getRecentAnimeRecommendations, getRecentAnimeReviews } from '../data-access/homeService';
55
import HomeRecommendationsComponent from '../ui/HomeRecommendationsComponent.vue';
66
import HomeReviewsComponentVue from '../ui/HomeReviewsComponent.vue';
7+
import MainPreviewComponent from '@/shared/ui/MainPreviewComponent.vue';
78
8-
// const { isPending, isError, data, error } = useQuery({
9-
// queryKey: ['topAiringAnimes'],
10-
// queryFn: getTopAiringAnimes,
11-
// })
12-
const { data: animes } = useQuery({
9+
const { data: animes, isPending: areAnimesPending} = useQuery({
1310
queryKey: ['topAiringAnimes'],
1411
queryFn: getTopAiringAnimes,
1512
})
@@ -24,7 +21,13 @@ const { data: recommendations, isPending: areRecommendationsPending} = useQuery(
2421
</script>
2522

2623
<template>
27-
<PanelComponent class="my-1 col-12" title="Top Airing Animes" :isCollapsed="false" />
24+
<!-- <PanelComponent class="my-1 col-12" title="Top Airing Animes" :isCollapsed="false" /> -->
25+
<MainPreviewComponent
26+
class="my-1 col-12"
27+
header="Top Airing Animes"
28+
:data="animes"
29+
:isLoading="areAnimesPending"
30+
/>
2831
<div class="flex flex-wrap">
2932
<PanelComponent class="xl:col-6 lg:col-6 col-12" title="Latest Reviews" :isCollapsed="false">
3033
<HomeReviewsComponentVue :reviews="reviews" :isLoading="areReviewsPending" />
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script setup lang="ts">
2+
3+
defineProps<{
4+
}>()
5+
6+
</script>
7+
8+
<template>
9+
<div></div>
10+
</template>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script setup lang="ts">
2+
3+
defineProps<{
4+
}>()
5+
6+
</script>
7+
8+
<template>
9+
<div></div>
10+
</template>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import axios from '@/middleware/axios-config'
2+
import type { DropdownOption } from '@/shared/data-access/models/dropdownOption'
3+
import type { Media } from '@/shared/data-access/models/media'
4+
import type { Pagination } from '@/shared/data-access/models/pagination'
5+
import type { SeasonData } from '@/shared/data-access/models/seasonData'
6+
import type { SeasonParams } from '@/shared/data-access/models/seasonParams'
7+
8+
const BASE_URL = 'https://api.jikan.moe/v4'
9+
10+
// export const getSeasonMediaData = async (params: SeasonParams) => {
11+
12+
export const getSeasonMediaData = async () => {
13+
try {
14+
const res = await axios.get(`${BASE_URL}/seasons/${2024}/${'winter'}`)
15+
const data: Media[] = res.data.data.map((item: any) => ({
16+
id: item.mal_id,
17+
title: item.title,
18+
titleEnglish: item.title_english,
19+
from: item.aired?.from,
20+
episodes: item.episodes,
21+
genres: item.genres.map((r: any) => r.name),
22+
imageSrc: item.images.jpg.image_url,
23+
synopsis: item.synopsis,
24+
score: item.score,
25+
members: item.members
26+
}))
27+
const pagination: Pagination = {
28+
first: res.data.pagination.current_page,
29+
rows: res.data.pagination.items.per_page,
30+
total: res.data.pagination.items.total
31+
}
32+
return { mediaData: { data, pagination } }
33+
} catch (error) {
34+
console.error('Error fetching top airing animes:', error)
35+
throw error
36+
}
37+
}
38+
39+
export const getSeasonData = async () => {
40+
try {
41+
const res = await axios.get(`${BASE_URL}/seasons`)
42+
const seasonData: SeasonData[] = res.data.data.map(
43+
(item: any) =>
44+
({
45+
year: item.year,
46+
seasonOptions: item.seasons.map(
47+
(s: string) =>
48+
({
49+
label: s.charAt(0).toUpperCase() + s.slice(1),
50+
value: s
51+
}) satisfies DropdownOption
52+
)
53+
}) satisfies SeasonData
54+
)
55+
const yearOptions: DropdownOption[] = seasonData.map(
56+
(s: SeasonData) =>
57+
({
58+
label: s.year,
59+
value: s.year.toString()
60+
}) satisfies DropdownOption
61+
)
62+
return { yearsSeasonsData: { seasonData, yearOptions } }
63+
} catch (error) {
64+
console.error('Error fetching top airing animes:', error)
65+
throw error
66+
}
67+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup lang="ts">
2+
import MediaDataComponent from '@/shared/ui/MediaDataComponent.vue';
3+
import { getSeasonData, getSeasonMediaData } from '../data-access/seasonService';
4+
import { useQuery } from '@tanstack/vue-query';
5+
6+
// const { data: animes, isPending: isPending } = useQuery({
7+
// queryKey: ['topAiringAnimes'],
8+
// queryFn: getSeasonData,
9+
// })
10+
// const season = 'winter',
11+
// const year = 2024
12+
const { data: animes, isPending: isPending } = useQuery({
13+
queryKey: ['seasonMediaData'],
14+
queryFn: getSeasonMediaData,
15+
})
16+
17+
defineProps<{
18+
}>()
19+
20+
</script>
21+
22+
<template>
23+
<div></div>
24+
<!-- <app-data-view-filter
25+
*ngIf="filters$ | async as vm"
26+
[filterDropdowns]="vm.filters"
27+
[isLoading]="vm.isLoading"
28+
/> -->
29+
<MediaDataComponent
30+
:isLoading="isPending"
31+
:data="animes?.mediaData.data ?? []"
32+
type="anime"
33+
34+
/>
35+
<!-- [pagination]="vm.pagination" -->
36+
<!-- (onPageChange)="handlePageChange($event)" -->
37+
</template>

src/layout/ui/HeaderComponent.vue

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,27 @@
33
import { ref } from 'vue'
44
import Menubar from 'primevue/menubar'
55
import Avatar from 'primevue/avatar'
6+
import { getCurrentSeason } from '@/shared/utils/currentSeason';
67
8+
const currentSeason = getCurrentSeason();
9+
const currentYear = new Date().getFullYear();
10+
const seasonUrl = `/season/${currentYear}/${currentSeason}`;
711
const items = ref([
812
{
9-
label: 'Home'
13+
label: 'Home',
14+
url: '/'
1015
},
1116
{
12-
label: 'Animes'
17+
label: 'Animes',
18+
url: '/animes'
1319
},
1420
{
15-
label: 'Mangas'
21+
label: 'Mangas',
22+
url: '/mangas'
1623
},
1724
{
18-
label: 'Season'
25+
label: 'Season',
26+
url: seasonUrl
1927
}
2028
])
2129
</script>

src/middleware/axios-config.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import axios from 'axios'
2+
import { app } from '@/main'
3+
4+
const axiosInstance = axios.create({
5+
baseURL: 'https://api.jikan.moe/v4'
6+
})
7+
8+
axiosInstance.interceptors.response.use(
9+
(response) => {
10+
return response
11+
},
12+
(error) => {
13+
console.error('HTTP error occurred:', error)
14+
app.config.globalProperties.$toast.add({
15+
severity: 'error',
16+
summary: 'Error',
17+
detail: error.message,
18+
life: 3000
19+
})
20+
21+
return Promise.reject(error)
22+
}
23+
)
24+
25+
export default axiosInstance

src/router/index.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,16 @@ const router = createRouter({
1111
{
1212
path: '/animes',
1313
name: 'animes',
14-
// route level code-splitting
15-
// this generates a separate chunk (About.[hash].js) for this route
16-
// which is lazy-loaded when the route is visited.
1714
component: () => import('../features/animes/views/AnimeListView.vue')
1815
},
1916
{
20-
path: '/season',
17+
path: '/season/:year/:season',
2118
name: 'season',
22-
// route level code-splitting
23-
// this generates a separate chunk (About.[hash].js) for this route
24-
// which is lazy-loaded when the route is visited.
2519
component: () => import('../features/season/views/SeasonListView.vue')
2620
},
2721
{
2822
path: '/mangas',
2923
name: 'mangas',
30-
// route level code-splitting
31-
// this generates a separate chunk (About.[hash].js) for this route
32-
// which is lazy-loaded when the route is visited.
3324
component: () => import('../features/mangas/views/MangaListView.vue')
3425
}
3526
]

0 commit comments

Comments
 (0)