Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #206 : added product details page #211

Merged
merged 4 commits into from
Jul 22, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions backend/products/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
# Register your models here.

class ProductAdmin(admin.ModelAdmin) :
list_display = ("name","description","category",'color', 'size', 'price',"created_at","updated_at")
fields = ("name","description","category", "color", "size", "price")
list_display = ("name","seller","type","description","category","tags",'color', 'size', 'price',"created_at","updated_at")
fields = ("name","seller","type","description","category","tags", "color", "size", "price")

class ProductColorAdmin(admin.ModelAdmin) :
list_display = ("color",)
Expand All @@ -23,4 +23,3 @@ class ProductImageAdmin(admin.ModelAdmin) :
admin.site.register(ProductImage,ProductImageAdmin)



Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 4.2 on 2024-07-19 19:06

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('products', '0001_initial'),
]

operations = [
migrations.AddField(
model_name='product',
name='seller',
field=models.CharField(blank=True, max_length=100),
),
migrations.AddField(
model_name='product',
name='tags',
field=models.CharField(blank=True, max_length=200),
),
migrations.AddField(
model_name='product',
name='type',
field=models.CharField(blank=True, max_length=100),
),
migrations.AlterField(
model_name='product',
name='color',
field=models.CharField(blank=True, max_length=200),
),
migrations.AlterField(
model_name='product',
name='size',
field=models.CharField(blank=True, max_length=200),
),
]
10 changes: 6 additions & 4 deletions backend/products/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

class Product(models.Model):
name = models.CharField(max_length=200)
seller = models.CharField(max_length=100, blank=True)
type = models.CharField(max_length=100, blank=True)
description = models.TextField(max_length=600,
blank=True)
category = models.CharField(max_length=100,
choices=category_choices)

color = models.CharField(max_length=100, blank = True)
size = models.CharField(max_length=100, blank = True)
tags = models.CharField(max_length=200, blank=True)
color = models.CharField(max_length=200, blank=True)
size = models.CharField(max_length=200, blank=True)
price = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Expand Down Expand Up @@ -60,4 +62,4 @@ class ProductImage(models.Model):
default=None,)
image = models.ImageField(upload_to='product_images')

required = ['image']
required = ['image']
5 changes: 4 additions & 1 deletion backend/products/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ class Meta:
fields = (
'id',
'name',
'seller',
'type',
'description',
'tags',
'price',
'color',
'size',
Expand All @@ -42,4 +45,4 @@ def to_representation(self, instance):
representation = super().to_representation(instance)
filtered_images = instance.product_images.filter(product=instance)
representation['product_images'] = ProductImageSerializer(filtered_images, many=True).data
return representation
return representation
3 changes: 3 additions & 0 deletions frontend/assets/buynow_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/assets/cart_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/assets/dropdown_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/assets/nextBtn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/assets/prevBtn.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/assets/share_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/assets/sizeChart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions frontend/components/MerchCard.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<template>
<div class="flex group flex-col items-center bg-white rounded shadow relative transition-all overflow-clip min-w-[350px]">
<div class="flex group flex-col items-center bg-white rounded shadow relative transition-all overflow-clip max-w-[350px]">
<div class="max-h-[350px] max-w-[350px] overflow-clip">
<img width="29" height="29" src="../assets/cart.svg"
class="absolute z-30 left-2 top-2 opacity-0 transition-all group-hover:opacity-100" />
<div class="absolute right-2 top-2 bg-white rounded-md py-1 px-2 text-[#9E3500] z-30 poppins text-xs">{{ type }}</div>
<div v-if="type!=''" class="absolute right-2 top-2 bg-white rounded-md py-1 px-2 text-[#9E3500] z-30 poppins text-xs">{{ type }}</div>
<img :src="imageUrl"
alt="Merch Image" class="object-cover transition-all group-hover:scale-125 rounded-t">
</div>
Expand All @@ -17,7 +17,7 @@
class="relative flex flex-col z-20 justify-start w-full gap-2 bg-white pt-2 px-3 pb-5 transition-all group-hover:-translate-y-20">
<div class="flex justify-between w-full text-base"><span class="text-[#9E3500] poppins font-bold">{{ seller
}}</span> <span class="poppins font-bold">₹{{ price }}</span></div>
<p class="text-black font-normal text-xs poppins">{{ description }}</p>
<p class="text-black font-normal text-xs poppins">{{ title }}</p>
<div
class=" gap-4 bg-white w-full flex absolute opacity-0 group-hover:opacity-100 group-hover:delay-150 ease-in-out group-hover:duration-300 transition duration-75 -bottom-6 h-min">
<div v-for="item in colors" :key="item"
Expand All @@ -43,11 +43,11 @@ export default {
props: {
title: {
type: String,
required: false
required: true
},
type: {
type: String,
required: true
required: false
},
imageUrl: {
type: String,
Expand Down
131 changes: 131 additions & 0 deletions frontend/components/productImageGallery.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
<template>
<div class="">
<div class="flex justify-center mb-4">
<img
class="h-auto max-w-full rounded-lg"
:src="`${config.public.API_BASE_URL}${product.product_images[imageIdx].image}`"
:alt="`Product Image ${imageIdx + 1}`"
/>
</div>
<div class="flex justify-center items-center">
<div
v-if="product.product_images.length >= 4"
class="flex justify-center items-center"
>
<div>
<button class="w-4" @click="prev" :disabled="imageGalleryIndex === 0">
<img class="w-4" src="assets/prevBtn.svg" alt="left" />
</button>
</div>
<div class="grid grid-cols-4 gap-4 mx-3">
<div
v-for="(image, index) in visibleImages"
:key="index"
class="max-h-32"
>
<img
class="max-h-32 max-w-full rounded-lg"
:src="`${config.public.API_BASE_URL}${image.image}`"
:alt="`Product Image ${index + 1}`"
@click="imageSelector(index + imageGalleryIndex)"
:style="{
outline:
index + imageGalleryIndex === imageIdx
? '2px solid black'
: 'none',
outlineOffset:
index + imageGalleryIndex === imageIdx ? '2px' : '0',
}"
/>
</div>
</div>

<div>
<button
class="w-4"
@click="next"
:disabled="imageGalleryIndex + 4 >= product.product_images.length"
>
<img class="w-4" src="assets/nextBtn.svg" alt="right" />
</button>
</div>
</div>

<div
v-if="product.product_images.length < 4"
class="grid gap-4 mx-3"
:class="gridClass"
>
<div
v-for="(image, index) in visibleImages"
:key="index"
class="max-h-32"
>
<img
class="max-h-32 max-w-full rounded-lg"
:src="`${config.public.API_BASE_URL}${image.image}`"
:alt="`Product Image ${index + 1}`"
@click="imageSelector(index + imageGalleryIndex)"
:style="{
outline:
index + imageGalleryIndex === imageIdx
? '2px solid black'
: 'none',
outlineOffset:
index + imageGalleryIndex === imageIdx ? '2px' : '0',
}"
/>
</div>
</div>
</div>
</div>
</template>

<script>
export default {
props: {
product: Object,
config: Object,
},
data() {
return {
imageIdx: 0,
imageGalleryIndex: 0,
};
},
computed: {
visibleImages() {
return this.product.product_images.slice(
this.imageGalleryIndex,
this.imageGalleryIndex + 4
);
},
gridClass() {
const numColumns = this.product.product_images.length;
return `grid-cols-${numColumns}`;
},
},
methods: {
imageSelector(index) {
this.imageIdx = index;
},
next() {
if (this.imageGalleryIndex + 4 < this.product.product_images.length) {
this.imageGalleryIndex += 1;
}
},
prev() {
if (this.imageGalleryIndex > 0) {
this.imageGalleryIndex -= 1;
}
},
},
};
</script>

<style scoped>
.poppins {
font-family: "Poppins", sans-serif;
font-smooth: always;
}
</style>
6 changes: 3 additions & 3 deletions frontend/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@
:to="`/products/${data.id}`"
:key="data.id"
>
<MerchCard
:title= "data.title"
<MerchCard
:title= "data.name"
:type= "data.type"
:imageUrl= "data.product_images"
:imageUrl="data.product_images[0].image"
:seller = "data.seller"
:price = "data.price"
:description = "data.description"
Expand Down
Loading
Loading