carousel + upload multiplo + form validation

This commit is contained in:
lesion 2022-08-24 17:46:36 +02:00
parent 3472b11168
commit 0377942842
6 changed files with 71 additions and 50 deletions

11
TODO.md
View file

@ -1,10 +1,13 @@
- [x] attach db connection / setup on nuxt listen hook
- [ ] carousel in detail (o un modo per avere piu' immagini per un oggetto)
- [ ] filtrare i file dell'input type file del form per mostrare solo mimetype image/*
- [x] filtrare i file dell'input type file del form per mostrare solo mimetype image/*
- [x] carousel in detail (o un modo per avere piu' immagini per un oggetto)
- [x] stringo la pagina dei dettagli
- [x] next / prev in page
- [ ] i tag da trimmare ed eliminare se son vuoti
- [ ] un load per next / prev
- [ ] favicon (solo perche' senza ci mette un sacco a fare il load)
- [ ] form validation
- [ ] api rate (mi sa di no perche' tutti usciremo con lo stesso ip)
- [x] form validation
- [ ] ci vuole un modo per segnare che un oggetto e' stato preso!
- [ ] api rate (mi sa di no perche' tutti usciremo con lo stesso ip)
- [ ] mail in lista

13
components/carousel.vue Normal file
View file

@ -0,0 +1,13 @@
<script setup>
// piccolo carosello da mettere in alto alle pagine delle cosette
const { images } = defineProps(['images'])
</script>
<template>
<div class='carousel max-h-100 bg-neutral'>
<div v-for='image in images' class='carousel-item' :key='image'>
<img class='carousel-center object-contain' :src="`/${image}`">
</div>
</div>
</template>

View file

@ -8,35 +8,38 @@
<label for='name' class="label label-text pb-0">Che roba è?</label>
<input type="text" name='name' id='name' placeholder="Nome" required autocomplete='off'
class="input secondary peer input-bordered invalid:border-orange-300 w-full" />
<label class="label label-text-alt peer-invalid:text-orange-500 transition pt-0">Metti il nome
<label class="label label-text-alt peer-invalid:text-orange-500 transition pt-0" for='name'>Metti il nome
della cosetta, il modello, una sigla</label>
<!-- DESCRIPTION -->
<label for="description" class="label label-text pb-0">Descrizione</label>
<textarea name='description' id='description'
class='textarea input-bordered w-full peer invalid:border-orange-300' required></textarea>
<label class="label label-text-alt peer-invalid:text-orange-500 pt-0">In che stato è? Dove l'hai
<label class="label label-text-alt peer-valid:text-grey-300 peer-invalid:text-orange-500 pt-0"
for='description'>In che stato è?
Dove l'hai
trovato? Insomma dacci una corposa descrizione.</label>
<!-- TAG -->
<label class="label label-text pb-0">Tag</label>
<input type="text" name='tags' placeholder="Tags" class="input input-bordered w-full" />
<label class="label label-text-alt pt-0">Delle parole chiavi per venirne a capo, separate da virgole (no non si
autocompleta)</label>
<label for='images' class="label label-text pb-0">Immagini</label>
<label for='images' class="label label-text mt-3 pb-0">Immagini - massimo 10 </label>
<input class='text-sm text-grey-500
file:mr-5 file:py-2 file:px-6
file:rounded-full file:border-0
file:rounded-md file:border-0
file:text-sm file:font-medium
file:bg-blue-50 file:text-blue-700
hover:file:cursor-pointer hover:file:bg-amber-50
hover:file:text-amber-700' type="file" name='images' accept="image/*" multiple />
hover:file:text-orange-700' required type="file" name='images' accept="image/*" multiple />
<div class="modal-action">
<div class="modal-action divider mt-10">
<a href="#" class="btn">Annulla</a>
<button class='btn btn-success' type='submit'>Aggiungi</button>
<button class='btn btn-primary' type='submit'>Aggiungi</button>
</div>
</form>
</div>

View file

@ -1,42 +1,42 @@
import { Server } from 'socket.io'
export default (_, nuxt) => {
nuxt.hook('listen', server => {
const io = new Server(server)
nuxt.hook('listen', server => {
const io = new Server(server)
nuxt.hook('close', () => io.close())
nuxt.hook('close', () => io.close())
io.on('connection', (socket) => {
console.log('Connection', socket.id)
io.on('connection', (socket) => {
console.log('Connection', socket.id)
})
io.on('connect', (socket) => {
socket.emit('message', `welcome ${socket.id}`)
socket.broadcast.emit('message', `${socket.id} joined`)
socket.on('joinRoom', (room) => {
socket.join(room)
socket.emit('message', `joinRoom ${room}`)
socket.broadcast.to(room).emit('message', `${socket.id} joined ${room}`)
})
socket.on('newComment',
function comment(message, room) {
console.log('new comment received: %s', message)
socket.broadcast.to(room).emit('newComment', { message })
})
io.on('connect', (socket) => {
socket.emit('message', `welcome ${socket.id}`)
socket.broadcast.emit('message', `${socket.id} joined`)
socket.on('message',
function message(data) {
console.log('message received: %s', data)
socket.broadcast.emit('message', { data })
})
socket.on('joinRoom', (room) => {
socket.join(room)
socket.emit('message', `joinRoom ${room}`)
socket.broadcast.to(room).emit('message', `${socket.id} joined ${room}`)
})
socket.on('newComment',
function comment(message, room) {
console.log('new comment received: %s', message)
socket.broadcast.to(room).emit('newComment', { message })
})
socket.on('message',
function message(data) {
console.log('message received: %s', data)
socket.broadcast.emit('message', { data })
})
socket.on('disconnecting',
() => {
console.log('disconnected', socket.id)
socket.broadcast.emit('message', `${socket.id} left`)
})
socket.on('disconnecting',
() => {
console.log('disconnected', socket.id)
socket.broadcast.emit('message', `${socket.id} left`)
})
})
})
}

View file

@ -10,22 +10,24 @@ const addComment = async () => {
comment.message = ''
const db_comment = await $fetch(`/api/comment/${ret.comment.uuid}`)
comments.unshift(db_comment)
$socket.emit("newComment", db_comment, route.params.cosetta )
// should we put this server-side?
$socket.emit("newComment", db_comment, route.params.cosetta)
}
onMounted(() => {
$socket.emit("joinRoom", route.params.cosetta)
$socket.on("newComment", (newComment) => {
comments.unshift(newComment.message)
})
$socket.on("newComment", newComment => comments.unshift(newComment.message))
})
</script>
<template>
<section class="bg-white py-8">
<section class="bg-white py-8 mx-auto max-w-4xl">
<!-- CAROUSEL -->
<Carousel :images='cosetta.images' />
<div class="container mx-auto pt-4 pb-12">
<img v-if='cosetta.images' :src="`/${cosetta.images[0]}`" />
<div class='carousel text-'></div>
<h2 class="text-pink-500 text-2xl card-title uppercase mb-2 divider" v-text='cosetta.name' />
<div class="px-6 pt-4 pb-2">
<span v-for='tag in cosetta.tags' :key='tag'

View file

@ -13,7 +13,7 @@ export const uploadService = () => {
limits: {
files: 10,
fieldNameSize: 400,
fileSize: 80 * 1024 * 1024,
fileSize: 800 * 1024 * 1024,
},
};
@ -36,7 +36,7 @@ export const uploadService = () => {
}),
};
return multer(options).array('images', 5);
return multer(options).array('images', 10);
} catch (e) {
console.error('Upload error', e)
throw e;