Skip to content

Commit

Permalink
✨ feat: show products without filled digital goods
Browse files Browse the repository at this point in the history
  • Loading branch information
shurco committed Nov 20, 2023
1 parent 07fe60c commit ed762f4
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 42 deletions.
11 changes: 6 additions & 5 deletions internal/models/products.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,10 @@ func (v Metadata) Validate() error {

// Digital is ...
type Digital struct {
Type string `json:"type"`
Files []File `json:"files,omitempty"`
Data []Data `json:"data,omitempty"`
Type string `json:"type"`
Filled bool `json:"filled,omitempty"`
Files []File `json:"files,omitempty"`
Data []Data `json:"data,omitempty"`
}

// Validate is ...
Expand All @@ -86,7 +87,7 @@ func (v File) Validate() error {
return validation.ValidateStruct(&v,
validation.Field(&v.ID, validation.Length(15, 15)),
validation.Field(&v.Name, is.UUIDv4),
//validation.Field(&v.Ext, validation.In("jpeg", "png")),
// validation.Field(&v.Ext, validation.In("jpeg", "png")),
)
}

Expand All @@ -102,6 +103,6 @@ func (v Data) Validate() error {
return validation.ValidateStruct(&v,
validation.Field(&v.ID, validation.Length(15, 15)),
validation.Field(&v.Content, validation.Length(1, 254)),
//validation.Field(&v.Ext, validation.In("jpeg", "png")),
// validation.Field(&v.Ext, validation.In("jpeg", "png")),
)
}
11 changes: 11 additions & 0 deletions internal/queries/products.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ func (q *ProductQueries) ListProducts(private bool, idList ...models.CartProduct
product.amount,
product.active,
product.digital,
CASE
WHEN (SELECT COUNT(id) FROM digital_data WHERE product_id = product.id AND cart_id IS NULL) > 0 THEN TRUE
WHEN (SELECT COUNT(id) FROM digital_file WHERE product_id = product.id) > 0 THEN TRUE
ELSE FALSE
END digital_filled,
(SELECT json_group_array(json_object('id', product_image.id, 'name', product_image.name, 'ext', product_image.ext)) as images FROM product_image WHERE product_id = product.id GROUP BY id LIMIT 1) as image,
strftime('%s', created)
FROM product
Expand Down Expand Up @@ -72,6 +77,7 @@ func (q *ProductQueries) ListProducts(private bool, idList ...models.CartProduct

for rows.Next() {
var image, digitalType sql.NullString
var digitalFilled sql.NullBool
product := models.Product{}
err := rows.Scan(
&product.ID,
Expand All @@ -80,6 +86,7 @@ func (q *ProductQueries) ListProducts(private bool, idList ...models.CartProduct
&product.Amount,
&product.Active,
&digitalType,
&digitalFilled,
&image,
&product.Created,
)
Expand All @@ -95,6 +102,10 @@ func (q *ProductQueries) ListProducts(private bool, idList ...models.CartProduct
product.Digital.Type = digitalType.String
}

if private && digitalType.Valid {
product.Digital.Filled = digitalFilled.Bool
}

products.Products = append(products.Products, product)
}

Expand Down
1 change: 0 additions & 1 deletion web/admin/src/components/product/Add.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ const product = ref({
})
const emits = defineEmits(["update:modelValue"]);
const products = computed({
get: () => {
return props.products;
Expand Down
80 changes: 52 additions & 28 deletions web/admin/src/components/product/Digital.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<div class="flex items-center">
<div class="pr-3">
<h1>Digital {{ digital.type }}</h1>
<p class="mt-4" v-if="digital.type === 'file'">This is the product that the user purchases. Upload the files that will be sent to the buyer after payment to the email address provided during checkout.</p>
<p class="mt-4" v-if="digital.type === 'file'">This is the product that the user purchases. Upload the files that will be sent to the buyer after payment to the email
address provided during checkout.</p>
<p class="mt-4" v-if="digital.type === 'data'">Enter the digital product that you intend to sell. It can be a unique item, such as a license key.</p>
</div>
</div>
Expand Down Expand Up @@ -57,7 +58,7 @@
</template>

<script setup>
import { onMounted, ref } from "vue";
import { onMounted, ref, computed } from "vue";
import FormInput from "@/components/form/Input.vue";
import FormUpload from "@/components/form/Upload.vue";
Expand All @@ -68,11 +69,24 @@ const props = defineProps({
drawer: {
required: true,
},
products: {
required: true,
},
close: Function,
});
const digital = ref({});
const emits = defineEmits(["update:modelValue"]);
const products = computed({
get: () => {
return props.products;
},
set: (val) => {
emits("update:modelValue", val);
},
});
onMounted(() => {
listDigitals();
});
Expand All @@ -89,29 +103,56 @@ const listDigitals = async () => {
const addDigitalFile = (e) => {
if (e.success) {
const productToUpdate = products.value.products.find((e) => e.id === props.drawer.product.id)
if (!productToUpdate.digital.filled) {
productToUpdate.digital.filled = true;
}
digital.value.files.push(e.result);
}
};
const addDigitalData = async () => {
apiPost(`/api/_/products/${props.drawer.product.id}/digital`).then(res => {
if (res.success) {
const productToUpdate = products.value.products.find((e) => e.id === props.drawer.product.id)
if (!productToUpdate.digital.filled) {
productToUpdate.digital.filled = true;
}
digital.value.data.push(res.result);
} else {
showMessage(res.result, "connextError");
}
});
};
const saveData = async (index) => {
const update = {
content: digital.value.data[index].content,
};
apiUpdate(`/api/_/products/${props.drawer.product.id}/digital/${digital.value.data[index].id}`, update)
};
const deleteDigital = async (type, index) => {
var digitalId;
switch (type) {
case "file":
digitalId = digital.value.files[index].id;
break;
case "data":
digitalId = digital.value.data[index].id;
break;
}
const digitalId = type === "file" ? digital.value.files[index].id : digital.value.data[index].id;
apiDelete(`/api/_/products/${props.drawer.product.id}/digital/${digitalId}`).then(res => {
if (res.success) {
const productToUpdate = products.value.products.find((e) => e.id === props.drawer.product.id);
switch (type) {
case "file":
digital.value.files.splice(index, 1);
if (digital.value.files.length === 0) {
productToUpdate.digital.filled = false;
}
break;
case "data":
digital.value.data.splice(index, 1);
const free_data = digital.value.data.filter((e) => e.cart_id === "").length
if (free_data === 0) {
productToUpdate.digital.filled = false;
}
break;
}
} else {
Expand All @@ -120,21 +161,4 @@ const deleteDigital = async (type, index) => {
});
};
const addDigitalData = async () => {
apiPost(`/api/_/products/${props.drawer.product.id}/digital`).then(res => {
if (res.success) {
digital.value.data.push(res.result);
} else {
showMessage(res.result, "connextError");
}
});
};
const saveData = async (index) => {
const update = {
content: digital.value.data[index].content,
};
apiUpdate(`/api/_/products/${props.drawer.product.id}/digital/${digital.value.data[index].id}`, update)
};
</script>
1 change: 0 additions & 1 deletion web/admin/src/components/product/Update.vue
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ const amount = ref()
const product = ref({})
const emits = defineEmits(["update:modelValue"]);
const products = computed({
get: () => {
return props.products;
Expand Down
14 changes: 7 additions & 7 deletions web/admin/src/pages/Products.vue
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
{{ costFormat(item.amount) }} {{ products.currency }}
</td>
<td class="px-4 py-2">
<SvgIcon :name="digitalTypeIco(item.digital.type)" class="h-5 w-5" @click="openDrawer(index, 'digital')" stroke="currentColor" />
<SvgIcon :name="digitalTypeIco(item.digital.type)" class="h-5 w-5" :class="{ 'text-red-500': !item.digital.filled }" @click="openDrawer(index, 'digital')" stroke="currentColor" />
</td>
<td class="px-4 py-2">
<div class="flex">
Expand All @@ -62,11 +62,11 @@
<div class="mx-auto" v-else>Add first product</div>

<drawer :is-open="isDrawer.open" max-width="710px" @close="closeDrawer">
<ProjectView :drawer="isDrawer" :close="closeDrawer" :updateActive="updateProductActive" v-if="isDrawer.action === 'view'" />
<ProjectAdd :drawer="isDrawer" :close="closeDrawer" :products="products" v-if="isDrawer.action === 'add'" />
<ProjectUpdate :drawer="isDrawer" :close="closeDrawer" :products="products" :updateActive="updateProductActive" v-if="isDrawer.action === 'update'" />
<ProjectSeo :drawer="isDrawer" :close="closeDrawer" v-if="isDrawer.action === 'seo'" />
<ProjectDigital :drawer="isDrawer" :close="closeDrawer" v-if="isDrawer.action === 'digital'" />
<ProjectView :drawer="isDrawer" :close="closeDrawer" :updateActive="updateProductActive" v-if="isDrawer.action === 'view'" />
<ProjectAdd :drawer="isDrawer" :close="closeDrawer" :products="products" v-if="isDrawer.action === 'add'" />
<ProjectUpdate :drawer="isDrawer" :close="closeDrawer" :products="products" :updateActive="updateProductActive" v-if="isDrawer.action === 'update'" />
<ProjectSeo :drawer="isDrawer" :close="closeDrawer" v-if="isDrawer.action === 'seo'" />
<ProjectDigital :drawer="isDrawer" :close="closeDrawer" :products="products" v-if="isDrawer.action === 'digital'" />
</drawer>
</MainLayouts>
</template>
Expand Down Expand Up @@ -129,7 +129,7 @@ const updateProductActive = async (index) => {
const openDrawer = (index, action) => {
isDrawer.value.open = true;
isDrawer.value.action = action;
if (index!==null) {
if (index !== null) {
isDrawer.value.product = {
index: index,
id: products.value.products[index].id,
Expand Down

0 comments on commit ed762f4

Please sign in to comment.