more. cant seem to get under 200 errors

This commit is contained in:
diceypotato
2025-04-24 14:42:01 -05:00
parent b1add2d594
commit f2082e2292
17 changed files with 189 additions and 205 deletions

1
frontend/.prettierignore Normal file
View File

@@ -0,0 +1 @@
src/api-schema/schema.d.ts

View File

@@ -22,7 +22,7 @@ import { Image } from 'primevue'
defineProps<{
// TODO: type properly
affiliated_artist: Record<string, any>
}>();
}>()
</script>
<style scoped>
.affiliated-artist {

View File

@@ -1,7 +1,12 @@
<template>
<ContentContainer class="header-wrapper artist-full-header">
<div class="header">
<Image class="artist-pictures" :src="artist.pictures[0]" preview>
<Image
class="artist-pictures"
v-if="artist.pictures?.length"
:src="artist.pictures[0]"
preview
>
<template #previewicon>
<i class="pi pi-search"></i>
</template>
@@ -13,18 +18,14 @@
</div>
</ContentContainer>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import ContentContainer from '@/components/ContentContainer.vue'
import { type Artist } from '@/services/api/artistService'
import { Image } from 'primevue'
export default defineComponent({
components: { ContentContainer, Image },
props: { artist: {} },
data() {
return {}
},
})
defineProps<{
artist: Artist
}>()
</script>
<style scoped>
.header-wrapper {

View File

@@ -1,6 +1,6 @@
<template>
<div class="artist-sidebar">
<Image class="artist-pictures" :src="artist.pictures[0]" preview>
<Image class="artist-pictures" v-if="artist.pictures?.length" :src="artist.pictures[0]" preview>
<template #previewicon>
<i class="pi pi-search"></i>
</template>
@@ -10,18 +10,14 @@
</ContentContainer>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import ContentContainer from '@/components/ContentContainer.vue'
import { type Artist } from '@/services/api/artistService'
import { Image } from 'primevue'
export default defineComponent({
components: { ContentContainer, Image },
props: { artist: {} },
data() {
return {}
},
})
defineProps<{
artist: Artist
}>()
</script>
<style scoped>
.artist-sidebar {

View File

@@ -1,16 +1,12 @@
<template>
<div class="name">{{ artist.name }}</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { type Artist } from '@/services/api/artistService'
export default defineComponent({
components: {},
props: { artist: {} },
data() {
return {}
},
})
defineProps<{
artist: Artist
}>()
</script>
<style scoped>
.name {

View File

@@ -21,16 +21,13 @@
</ContentContainer>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import ContentContainer from '@/components/ContentContainer.vue'
import { type TitleGroupHierarchy } from '@/services/api/torrentService'
export default defineComponent({
components: { ContentContainer },
props: {
comment: {},
},
})
defineProps<{
comment: TitleGroupHierarchy
}>()
</script>
<style scoped>

View File

@@ -11,7 +11,7 @@
:validateOnValueUpdate="false"
>
<div class="new-comment">
<BBCodeEditor @value-change="newCommentUpdated" :label="$t('community.new_comment')" />
<BBCodeEditor @value-change="newCommentUpdated" :label="t('community.new_comment')" />
<Message v-if="$form.content?.invalid" severity="error" size="small" variant="simple">
{{ $form.content.error?.message }}
</Message>
@@ -26,67 +26,77 @@
</Form>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { ref } from 'vue'
import GeneralComment from './GeneralComment.vue'
import { Button } from 'primevue'
import { postTitleGroupComment } from '@/services/api/commentService'
import { type TitleGroupHierarchy } from '@/services/api/torrentService'
import BBCodeEditor from './BBCodeEditor.vue'
import { Form } from '@primevue/forms'
import { Form, type FormResolverOptions, type FormSubmitEvent } from '@primevue/forms'
import Message from 'primevue/message'
import { useUserStore } from '@/stores/user'
import { useRoute } from 'vue-router'
export default defineComponent({
components: { GeneralComment, BBCodeEditor, Button, Form, Message },
props: {
comments: [],
},
data() {
return {
new_comment: {
content: '',
refers_to_torrent_id: null,
answers_to_comment_id: null,
},
sending_comment: false,
}
},
methods: {
resolver({ values }) {
const errors = {}
defineProps<{
comments: TitleGroupHierarchy[]
}>()
if (values.content.length < 5) {
errors.content = [{ message: this.$t('error.write_more_than_x_chars', [5]) }]
}
const { t } = useI18n()
return {
errors,
}
},
onFormSubmit({ valid }) {
if (valid) {
this.sendComment()
}
},
newCommentUpdated(content: string) {
this.new_comment.content = content
},
sendComment() {
this.sending_comment = true
this.new_comment.title_group_id = parseInt(this.$route.query.id)
postTitleGroupComment(this.new_comment).then((data) => {
this.new_comment.content = ''
this.new_comment.refers_to_torrent_id = null
this.new_comment.answers_to_comment_id = null
data.created_by = {}
data.created_by = useUserStore()
// eslint-disable-next-line vue/no-mutating-props -- TODO: don't mutate the prop
this.comments.push(data)
this.sending_comment = false
})
},
},
const route = useRoute()
type NewComment = {
content: string
refers_to_torrent_id: number | null
answers_to_comment_id: number | null
title_group_id: number | null
}
const new_comment = ref<NewComment>({
content: '',
refers_to_torrent_id: null,
answers_to_comment_id: null,
title_group_id: null,
})
const sending_comment = ref(false)
const resolver = ({ values }: FormResolverOptions): Record<string, any> => {
const errors: Record<string, any> = {}
if (values.content.length < 5) {
errors.content = [{ message: t('error.write_more_than_x_chars', [5]) }]
}
return {
errors,
}
}
const onFormSubmit = ({ valid }: FormSubmitEvent) => {
if (valid) {
sendComment()
}
}
const newCommentUpdated = (content: string) => {
new_comment.value.content = content
}
const sendComment = async () => {
sending_comment.value = true
new_comment.value.title_group_id = parseInt(route.params.id as string)
let data = await postTitleGroupComment(new_comment.value)
new_comment.value.content = ''
new_comment.value.refers_to_torrent_id = null
new_comment.value.answers_to_comment_id = null
data.created_by = {}
data.created_by = useUserStore()
// eslint-disable-next-line vue/no-mutating-props -- TODO: don't mutate the prop
// this.comments.push(data)
sending_comment.value = false
}
</script>
<style scoped>
.new-comment {

View File

@@ -172,7 +172,7 @@ import Select from 'primevue/select'
import Button from 'primevue/button'
import DatePicker from 'primevue/datepicker'
import Message from 'primevue/message'
import { Form } from '@primevue/forms'
import { Form, type FormResolverOptions } from '@primevue/forms'
export default defineComponent({
components: {
@@ -206,7 +206,7 @@ export default defineComponent({
}
},
methods: {
resolver({ values }) {
resolver({ values }: FormResolverOptions) {
const errors = {}
if (values.name.length < 5) {

View File

@@ -234,7 +234,7 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { Form } from '@primevue/forms'
import { Form, type FormResolverOptions } from '@primevue/forms'
import FloatLabel from 'primevue/floatlabel'
import InputText from 'primevue/inputtext'
import Textarea from 'primevue/textarea'
@@ -291,7 +291,7 @@ export default defineComponent({
},
methods: {
resolver({ values }) {
resolver({ values }: FormResolverOptions) {
const errors = {}
if (values.name.length < 5) {

View File

@@ -1,19 +1,14 @@
<template>
<div class="title-group-preview-cover-only">
<a :href="'/title-group/' + id">
<img
class="title-group-cover"
:src="cover"
v-tooltip.top="name"
alt="Title Group Cover"
/>
<img class="title-group-cover" :src="cover" v-tooltip.top="name" alt="Title Group Cover" />
</a>
</div>
</template>
<script setup lang="ts">
defineProps<{
id: number,
name: string,
id: number
name: string
cover: string
}>()
</script>

View File

@@ -16,9 +16,7 @@
<Column :header="$t('torrent.properties')" style="min-width: 300px">
<template #body="slotProps">
<a
:href="
preview ? `/title-group/${title_group.id}&torrentId=${slotProps.data.id}` : null
"
:href="preview ? `/title-group/${title_group.id}&torrentId=${slotProps.data.id}` : null"
@click="preview ? null : toggleRow(slotProps.data)"
class="cursor-pointer"
>

View File

@@ -289,7 +289,7 @@ import Checkbox from 'primevue/checkbox'
import FileUpload from 'primevue/fileupload'
import MultiSelect from 'primevue/multiselect'
import Message from 'primevue/message'
import { FormField } from '@primevue/forms'
import { FormField, type FormResolverOptions } from '@primevue/forms'
import { Form } from '@primevue/forms'
import { getFileInfo } from '@/services/fileinfo/fileinfo.js'
import { useEditionGroupStore } from '@/stores/editionGroup'
@@ -384,7 +384,7 @@ export default defineComponent({
}
},
methods: {
resolver({ values }) {
resolver({ values }: FormResolverOptions) {
const errors = {}
if (values.release_name.length < 5) {

View File

@@ -8,39 +8,45 @@
v-model="searchForm.title_group_name"
name="title_group_name"
/>
<label for="title_group_name">{{ $t('general.search_terms') }}</label>
<label for="title_group_name">{{ t('general.search_terms') }}</label>
</FloatLabel>
<FloatLabel>
<InputText class="tags" size="small" v-model="searchForm.tags" name="tags" />
<label for="tags">{{ $t('general.tags_comma_separated') }}</label>
<!-- <InputText class="tags" size="small" v-model="searchForm.tags" name="tags" /> -->
<label for="tags">{{ t('general.tags_comma_separated') }}</label>
</FloatLabel>
<div class="flex justify-content-center" style="margin-top: 15px">
<Button :loading :label="$t('general.search')" @click="$emit('search', searchForm)" />
<Button :loading :label="t('general.search')" @click="emit('search', searchForm)" />
</div>
</div>
</ContentContainer>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useI18n } from 'vue-i18n'
import ContentContainer from '../ContentContainer.vue'
import InputText from 'primevue/inputtext'
import FloatLabel from 'primevue/floatlabel'
import Button from 'primevue/button'
export default defineComponent({
components: { ContentContainer, Button, InputText, FloatLabel },
props: { loading: { default: false }, initialTitleGroupName: {} },
data() {
return {
searchForm: {
title_group_name: '',
},
}
},
created() {
this.searchForm.title_group_name = this.initialTitleGroupName
},
const { t } = useI18n()
defineProps<{
loading: boolean
}>()
export type SearchForm = {
title_group_name: string
tags: string
}
const emit = defineEmits<{
search: [form: SearchForm]
}>()
const searchForm = ref<SearchForm>({
title_group_name: '',
tags: '',
})
</script>

View File

@@ -1,4 +1,4 @@
import { createRouter, createWebHistory, type RouteRecordInfo } from 'vue-router'
import { createRouter, createWebHistory, type RouteRecordInfo, type ParamValue } from 'vue-router'
import HomeView from '../views/HomeView.vue'
export interface RouteNamedMap {
@@ -8,8 +8,8 @@ export interface RouteNamedMap {
{ id: string | number },
{ id: number }
>
Series: RouteRecordInfo<'Series', '/series/:id', { id: string | number }, { id: number }>
Artist: RouteRecordInfo<'Artist', '/artist/:id', { id: string | number }, { id: number }>
Series: RouteRecordInfo<'Series', '/series/:id', { id: string | number }, { id: string }>
Artist: RouteRecordInfo<'Artist', '/artist/:id', { id: string | number }, { id: string }>
}
declare module 'vue-router' {

View File

@@ -20,7 +20,7 @@ export const bytesToReadable = (bytes: number): string => {
return `${size.toFixed(2)} ${units[unitIndex]}`
}
export const getEditionGroupSlug = (editionGroup) => {
export const getEditionGroupSlug = (editionGroup: string): string => {
let slug = ''
if (editionGroup.additional_information?.date_from) {
@@ -50,7 +50,7 @@ export const getEditionGroupSlug = (editionGroup) => {
slug += editionGroup.distributor ? ' / ' + editionGroup.distributor : ''
return slug
}
export const getFeatures = (contentType) => {
export const getFeatures = (contentType: string): string[] => {
if (contentType == 'book' || contentType == 'music') {
return ['Cue', 'Booklet']
} else if (contentType == 'tv_show' || contentType == 'movie') {

View File

@@ -28,41 +28,32 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import ContentContainer from '@/components/ContentContainer.vue'
import TitleGroupPreviewCoverOnly from '@/components/title_group/TitleGroupPreviewCoverOnly.vue'
import TitleGroupPreviewTable from '@/components/title_group/TitleGroupPreviewTable.vue'
import { searchTorrents } from '@/services/api/torrentService'
import TorrentSearchInputs from '@/components/torrent/TorrentSearchInputs.vue'
export default {
components: {
ContentContainer,
TitleGroupPreviewCoverOnly,
TitleGroupPreviewTable,
TorrentSearchInputs,
},
data() {
return {
search_results: null,
title_group_preview_mode: 'table', // TODO: make a select button to switch from cover-only to table
loading: false,
initialTitleGroupName: '',
}
},
methods: {
search(searchForm) {
this.loading = true
searchTorrents(searchForm).then((data) => {
this.search_results = data
this.loading = false
})
},
},
created() {
this.initialTitleGroupName = this.$route.query.title_group_name ?? ''
this.search({ title_group_name: this.initialTitleGroupName })
},
import { searchTorrents, type TorrentSearch } from '@/services/api/torrentService'
import TorrentSearchInputs, { type SearchForm } from '@/components/torrent/TorrentSearchInputs.vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const search_results = ref<TorrentSearch>()
const title_group_preview_mode = ref<'table' | 'cover-only'>('table') // TODO: make a select button to switch from cover-only to table
const loading = ref(false)
const initialTitleGroupName = ref('')
const search = async (searchForm: SearchForm) => {
loading.value = true
search_results.value = await searchTorrents(searchForm)
loading.value = false
}
onMounted(async () => {
initialTitleGroupName.value = route.query.title_group_name ?? ''
search({ title_group_name: initialTitleGroupName.value, tags: '' })
})
</script>
<style scoped>

View File

@@ -1,9 +1,9 @@
<template>
<div>
<div class="title">{{ $t('torrent.upload_torrent') }}</div>
<div class="title">{{ t('torrent.upload_torrent') }}</div>
<Accordion :value="titleGroupAccordionValue" class="upload-step-accordion">
<AccordionPanel value="0" :disabled="uploadStep != 1">
<AccordionHeader>{{ $t('title_group.title') }}</AccordionHeader>
<AccordionHeader>{{ t('title_group.title') }}</AccordionHeader>
<AccordionContent>
<CreateOrSelectTitleGroup @done="titleGroupDone" />
</AccordionContent>
@@ -11,7 +11,7 @@
</Accordion>
<Accordion :value="editionGroupAccordionValue" class="upload-step-accordion">
<AccordionPanel value="0" :disabled="uploadStep != 2">
<AccordionHeader>{{ $t('torrent.edition') }}</AccordionHeader>
<AccordionHeader>{{ t('torrent.edition') }}</AccordionHeader>
<AccordionContent>
<CreateOrSelectEditionGroup v-if="uploadStep > 1" @done="editionGroupDone" />
</AccordionContent>
@@ -19,7 +19,7 @@
</Accordion>
<Accordion :value="torrentAccordionValue" class="upload-step-accordion">
<AccordionPanel value="0" :disabled="uploadStep != 3">
<AccordionHeader>{{ $t('torrent.torrent') }}</AccordionHeader>
<AccordionHeader>{{ t('torrent.torrent') }}</AccordionHeader>
<AccordionContent>
<CreateOrEditTorrent v-if="uploadStep > 2" @done="torrentDone" />
</AccordionContent>
@@ -27,7 +27,8 @@
</Accordion>
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { ref } from 'vue'
import Accordion from 'primevue/accordion'
import AccordionPanel from 'primevue/accordionpanel'
import AccordionHeader from 'primevue/accordionheader'
@@ -37,45 +38,37 @@ import CreateOrSelectEditionGroup from '@/components/edition_group/CreateOrSelec
import CreateOrEditTorrent from '@/components/torrent/CreateOrEditTorrent.vue'
import { useEditionGroupStore } from '@/stores/editionGroup'
import { useTitleGroupStore } from '@/stores/titleGroup'
import { useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'
export default {
components: {
CreateOrSelectTitleGroup,
CreateOrSelectEditionGroup,
Accordion,
AccordionContent,
AccordionHeader,
AccordionPanel,
CreateOrEditTorrent,
},
data() {
return {
titleGroupAccordionValue: '0',
editionGroupAccordionValue: '',
torrentAccordionValue: '',
uploadStep: 1,
editionGroup: {},
}
},
created() {},
methods: {
titleGroupDone() {
this.titleGroupAccordionValue = ''
this.editionGroupAccordionValue = '0'
this.uploadStep = 2
},
editionGroupDone(editionGroup: object) {
this.editionGroup = editionGroup
const editionGroupStore = useEditionGroupStore()
editionGroupStore.id = editionGroup.id
this.editionGroupAccordionValue = ''
this.torrentAccordionValue = '0'
this.uploadStep = 3
},
torrentDone(torrent) {
this.$router.push('/title-group/' + useTitleGroupStore().id + '&torrentId=' + torrent.id)
},
},
const router = useRouter()
const { t } = useI18n()
const editionGroupStore = useEditionGroupStore()
const titleGroupStore = useTitleGroupStore()
const titleGroupAccordionValue = ref('0')
const editionGroupAccordionValue = ref('')
const torrentAccordionValue = ref('')
const uploadStep = ref(1)
const editionGroup = ref({})
const titleGroupDone = () => {
titleGroupAccordionValue.value = ''
editionGroupAccordionValue.value = '0'
uploadStep.value = 2
}
const editionGroupDone = (editionGroup: object) => {
editionGroup.value = editionGroup
editionGroupStore.id = editionGroup.id
editionGroupAccordionValue.value = ''
torrentAccordionValue.value = '0'
uploadStep.value = 3
}
const torrentDone = (torrent) => {
router.push('/title-group/' + titleGroupStore.id + '&torrentId=' + torrent.id)
}
</script>