Browse Source

carousel + upload multiplo + form validation

lesion 1 year ago
parent
commit
0377942842
6 changed files with 72 additions and 51 deletions
  1. 7 4
      TODO.md
  2. 13 0
      components/carousel.vue
  3. 10 7
      components/upload.vue
  4. 32 32
      modules/socket.js
  5. 8 6
      pages/c/[cosetta].vue
  6. 2 2
      server/services/upload-service.ts

+ 7 - 4
TODO.md

@@ -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 - 0
components/carousel.vue

@@ -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>

+ 10 - 7
components/upload.vue

@@ -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>

+ 32 - 32
modules/socket.js

@@ -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 })
+        })
+
+      socket.on('message',
+        function message(data) {
+          console.log('message received: %s', data)
+          socket.broadcast.emit('message', { data })
         })
 
-        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 })
-            })
-
-          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`)
         })
     })
+  })
 }

+ 8 - 6
pages/c/[cosetta].vue

@@ -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'

+ 2 - 2
server/services/upload-service.ts

@@ -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;