feat: initial project

This commit is contained in:
MasutaYunikon committed 2026-03-10 22:36:34 +01:00
commit eaf01cfc59
38 files changed
+5807

No files matched your search

+57
View File
@@ -0,0 +1,57 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useAuthStore = defineStore('auth', () => {
const loggedIn = ref(false)
const setup = ref(false)
const loading = ref(true)
async function checkStatus() {
try {
const res = await fetch('/api/auth/status')
const data = await res.json()
setup.value = data.setup
loggedIn.value = data.loggedIn
} catch {
loggedIn.value = false
} finally {
loading.value = false
}
}
async function login(username: string, password: string): Promise<string | null> {
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
})
const data = await res.json()
if (res.ok) {
loggedIn.value = true
return null
}
return data.error
}
async function setupAccount(username: string, password: string): Promise<string | null> {
const res = await fetch('/api/auth/setup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password })
})
const data = await res.json()
if (res.ok) {
loggedIn.value = true
setup.value = true
return null
}
return data.error
}
async function logout() {
await fetch('/api/auth/logout', { method: 'POST' })
loggedIn.value = false
}
return { loggedIn, setup, loading, checkStatus, login, setupAccount, logout }
})
+33
View File
@@ -0,0 +1,33 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
import {
fetchProductions,
fetchProduction,
type Production,
type ProductionDetail
} from '@/api/fankai'
export const useCatalogStore = defineStore('catalog', () => {
const productions = ref<Production[]>([])
const loading = ref(false)
const error = ref<string | null>(null)
async function loadProductions() {
if (productions.value.length > 0) return
loading.value = true
error.value = null
try {
productions.value = await fetchProductions()
} catch (err) {
error.value = err instanceof Error ? err.message : 'Erreur inconnue'
} finally {
loading.value = false
}
}
async function loadProduction(id: number, name: string): Promise<ProductionDetail> {
return await fetchProduction(id, name)
}
return { productions, loading, error, loadProductions, loadProduction }
})
+114
View File
@@ -0,0 +1,114 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export interface TorrentRef {
torrent_raw: string
torrent_url: string | null
magnet: string | null
type: string
}
export interface Episode {
id: number
episode_number: number
display_episode: number | null
title: string
plot: string | null
aired: string | null
duration: number | null
thumb_image: string | null
has_thumbnail: boolean
season_id: number
available: boolean
torrent: TorrentRef | null // non-null seulement si type=episode
}
export interface Season {
id: number
season_number: number
title: string
plot: string | null
poster_image: string | null
episode_count: number
premiered: string | null
episodes: Episode[]
torrent: TorrentRef | null
}
export interface Serie {
id: number
title: string
sort_title: string
plot: string | null
poster_image: string | null
fanart_image: string | null
year: number | null
status: string | null
torrent_count: number
has_torrents: boolean
}
export interface SerieDetail {
serie: Serie
seasons: Season[]
torrents_integrale: { raw: string; torrent_url: string | null; magnet: string | null }[]
}
export const useSeriesStore = defineStore('series', () => {
const series = ref<Serie[]>([])
const currentSerie = ref<SerieDetail | null>(null)
const loadingSeries = ref(false)
const loadingDetail = ref(false)
const error = ref<string | null>(null)
async function fetchSeries() {
loadingSeries.value = true
error.value = null
try {
const res = await fetch('/api/series')
if (!res.ok) throw new Error(`Erreur ${res.status}`)
const data = await res.json()
series.value = data.series
} catch (err) {
error.value = err instanceof Error ? err.message : 'Erreur inconnue'
} finally {
loadingSeries.value = false
}
}
async function fetchSerieDetail(id: number) {
loadingDetail.value = true
error.value = null
currentSerie.value = null
try {
const res = await fetch(`/api/series/${id}`)
if (!res.ok) throw new Error(`Erreur ${res.status}`)
currentSerie.value = await res.json()
} catch (err) {
error.value = err instanceof Error ? err.message : 'Erreur inconnue'
} finally {
loadingDetail.value = false
}
}
async function download(torrent_url: string | null, magnet: string | null): Promise<{ success: boolean; error?: string }> {
try {
const res = await fetch('/api/download', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ torrent_url, magnet })
})
const data = await res.json()
if (res.ok) return { success: true }
return { success: false, error: data.error }
} catch (err) {
return { success: false, error: err instanceof Error ? err.message : 'Erreur inconnue' }
}
}
return {
series, currentSerie,
loadingSeries, loadingDetail, error,
fetchSeries, fetchSerieDetail, download
}
})