From 159e84532ebdae038e1263efe8832015597a5e20 Mon Sep 17 00:00:00 2001
From: taehoon <th.dev91@gmail.com>
Date: Wed, 13 Feb 2019 21:07:28 -0500
Subject: [PATCH] Add withSubscription hoc

---
 .../with_subscription/with_subscription.js    | 65 +++++++++++++++++++
 .../with_subscription/with_subscription.scss  | 10 +++
 2 files changed, 75 insertions(+)
 create mode 100644 src/hocs/with_subscription/with_subscription.js
 create mode 100644 src/hocs/with_subscription/with_subscription.scss

diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.js
new file mode 100644
index 00000000..31fc106f
--- /dev/null
+++ b/src/hocs/with_subscription/with_subscription.js
@@ -0,0 +1,65 @@
+import Vue from 'vue'
+import filter from 'lodash/filter'
+import isEmpty from 'lodash/isEmpty'
+import './with_subscription.scss'
+
+const withSubscription = (Component, fetch, select, contentPropName = 'content') => {
+  const originalProps = Component.props || []
+  const props = filter(originalProps, v => v !== 'content')
+
+  return Vue.component('withSubscription', {
+    render (createElement) {
+      const props = {
+        props: {
+          ...this.$props,
+          [contentPropName]: this.fetchedData
+        },
+        on: this.$listeners
+      }
+      return (
+        <div class="with-subscription">
+          <Component {...props} />
+          <div class="with-subscription-footer">
+            {this.error && <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>}
+            {!this.error && this.loading && <i class="icon-spin3 animate-spin"/>}
+          </div>
+        </div>
+      )
+    },
+    props,
+    data () {
+      return {
+        loading: false,
+        error: false
+      }
+    },
+    computed: {
+      fetchedData () {
+        return select(this.$props, this.$store)
+      }
+    },
+    created () {
+      if (isEmpty(this.fetchedData)) {
+        this.fetchData()
+      }
+    },
+    methods: {
+      fetchData () {
+        if (!this.loading) {
+          this.loading = true
+          this.error = false
+          fetch(this.$props, this.$store)
+            .then(() => {
+              this.loading = false
+            })
+            .catch(() => {
+              this.error = true
+              this.loading = false
+            })
+        }
+      }
+    }
+  })
+}
+
+export default withSubscription
diff --git a/src/hocs/with_subscription/with_subscription.scss b/src/hocs/with_subscription/with_subscription.scss
new file mode 100644
index 00000000..5114029d
--- /dev/null
+++ b/src/hocs/with_subscription/with_subscription.scss
@@ -0,0 +1,10 @@
+.with-subscription {
+  &-footer {
+    padding: 10px;
+    text-align: center;
+  }
+
+  .error {
+    font-size: 14px;
+  }
+}
\ No newline at end of file