From 9fb34b910bebbff5c876060943cfc1fd74e956a2 Mon Sep 17 00:00:00 2001
From: ManUtopiK <emmanuel.salomon@gmail.com>
Date: Tue, 21 Sep 2021 03:46:30 +0200
Subject: [PATCH] List and Box global components

---
 components/global/Box.vue  |  48 +++++++++++++++++
 components/global/List.vue | 104 +++++++++++++++++++++++++++++++++++++
 2 files changed, 152 insertions(+)
 create mode 100644 components/global/Box.vue
 create mode 100644 components/global/List.vue

diff --git a/components/global/Box.vue b/components/global/Box.vue
new file mode 100644
index 00000000..ae4b4cda
--- /dev/null
+++ b/components/global/Box.vue
@@ -0,0 +1,48 @@
+<template>
+  <component
+    :is="to ? 'nuxt-link' : 'div'"
+    :to="to"
+    class="block rounded p-4"
+    :class="computedClass"
+  >
+    <slot />
+  </component>
+</template>
+
+<script>
+export default {
+  name: 'Box',
+  props: {
+    to: {
+      type: [String, Object],
+      default: null,
+    },
+    color: {
+      type: String,
+      default: null,
+    },
+  },
+  computed: {
+    computedClass() {
+      let classes = ''
+      if (this.color) {
+        classes += `bg-${this.color}-100 dark:bg-${this.color}-900`
+      } else {
+        classes = `border dark:border-gray-700`
+      }
+      if (this.to)
+        classes +=
+          ' transition transform hover:shadow-xl hover:-translate-y-0.5 is-box-with-link'
+      return classes
+    },
+  },
+}
+</script>
+
+<style lang="postcss" scoped>
+.is-box-with-link {
+  text-decoration: none !important;
+  color: currentColor !important;
+  font-weight: normal !important;
+}
+</style>
diff --git a/components/global/List.vue b/components/global/List.vue
new file mode 100644
index 00000000..1e01318c
--- /dev/null
+++ b/components/global/List.vue
@@ -0,0 +1,104 @@
+<template>
+  <div class="prose dark:prose-dark">
+    <slot />
+
+    <slot v-if="Array.isArray(data)" name="items" :items="data">
+      <ul class="list">
+        <li v-for="(item, i) in data" :key="i">
+          <nuxt-link :to="item.path">
+            <div v-if="title">{{ item.title }}</div>
+          </nuxt-link>
+          <span v-if="description">{{ item.description }}</span>
+        </li>
+      </ul>
+    </slot>
+    <slot v-else-if="data" name="item">
+      <h2 v-if="title">{{ data.title }}</h2>
+      <p v-if="description">{{ data.description }}</p>
+    </slot>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'List',
+  props: {
+    content: {
+      type: String,
+      default: null,
+    },
+    only: {
+      type: [String, Array],
+      default: null,
+    },
+    where: {
+      type: Object,
+      default: null,
+    },
+    sortBy: {
+      type: String,
+      default: null,
+    },
+    direction: {
+      type: String,
+      default: 'asc',
+      validator(value) {
+        return ['asc', 'desc'].includes(value)
+      },
+    },
+    skip: {
+      type: [Number, String],
+      default: null,
+    },
+    search: {
+      type: String,
+      default: null,
+    },
+    searchField: {
+      type: String,
+      default: null,
+    },
+    limit: {
+      type: [Number, String],
+      default: null,
+    },
+
+    title: {
+      type: Boolean,
+      default: true,
+    },
+    description: {
+      type: Boolean,
+      default: false,
+    },
+    readingTime: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      data: null,
+    }
+  },
+  async fetch() {
+    if (this.content) {
+      const content = this.$content(this.content)
+      if (this.only) content.only(this.only)
+      if (this.where) content.where(this.where)
+      if (this.sortBy) content.sortBy(this.sortBy, this.direction)
+      if (this.skip) content.skip(+this.skip)
+      if (this.search) {
+        this.searchField
+          ? content.search(this.searchField, this.search)
+          : content.search(this.search)
+      }
+      if (this.limit) content.limit(+this.limit)
+
+      this.data = await content.fetch()
+    }
+  },
+}
+</script>
+
+<style lang="postcss" scoped></style>
-- 
GitLab