fix: Empty states and miscellanous fixes

- Added Wishlist and Product Listing empty states
- Hide ‘Write Review’ button f user is not Customer
- Fixed grid view title (missing arg)
- Render empty state if no items form server side
- Removed unused function
- Guest user redirected to login on clicking Wishlist button
- Fixed ‘Notes’ field clearing issue
diff --git a/erpnext/e_commerce/doctype/website_item/website_item.py b/erpnext/e_commerce/doctype/website_item/website_item.py
index 9f47260..5ced1be 100644
--- a/erpnext/e_commerce/doctype/website_item/website_item.py
+++ b/erpnext/e_commerce/doctype/website_item/website_item.py
@@ -194,6 +194,7 @@
 		if frappe.db.exists("Wishlist Items", {"item_code": self.item_code, "parent": frappe.session.user}):
 			context.wished = True
 
+		context.user_is_customer = check_if_user_is_customer()
 		return context
 
 	def set_variant_context(self, context):
@@ -423,4 +424,21 @@
 
 def on_doctype_update():
 	# since route is a Text column, it needs a length for indexing
-	frappe.db.add_index("Website Item", ["route(500)"])
\ No newline at end of file
+	frappe.db.add_index("Website Item", ["route(500)"])
+
+def check_if_user_is_customer(user=None):
+	from frappe.contacts.doctype.contact.contact import get_contact_name
+
+	if not user:
+		user = frappe.session.user
+
+	contact_name = get_contact_name(user)
+	party = None
+
+	if contact_name:
+		contact = frappe.get_doc('Contact', contact_name)
+		if contact.links:
+			party_doctype = contact.links[0].link_doctype
+			party = contact.links[0].link_name
+
+	return True if party else False
\ No newline at end of file
diff --git a/erpnext/e_commerce/product_grid.js b/erpnext/e_commerce/product_grid.js
index 8712a20..6f7b9cc 100644
--- a/erpnext/e_commerce/product_grid.js
+++ b/erpnext/e_commerce/product_grid.js
@@ -60,7 +60,7 @@
 			<div class="card-body text-left" style="width:100%">
 				<div style="margin-top: 16px; display: flex;">
 		`;
-		body_html += this.get_title_with_indicator(item, title);
+		body_html += this.get_title_with_indicator(item, title, settings);
 
 		if (!item.has_variants && settings.enable_wishlist) {
 			body_html += this.get_wishlist_icon(item);
diff --git a/erpnext/e_commerce/product_view.js b/erpnext/e_commerce/product_view.js
index f6727ca..03fd31e 100644
--- a/erpnext/e_commerce/product_view.js
+++ b/erpnext/e_commerce/product_view.js
@@ -33,15 +33,22 @@
 			args: args,
 			callback: function(result) {
 				if (!result.exc && result) {
-					me.render_filters(result.message[1]);
+					if (!result.message || !result.message[0].length) {
+						console.log("no items");
+						// if result has no items or result is empty
+						me.render_no_products_section();
+					} else {
+						console.log("there are items");
+						me.render_filters(result.message[1]);
 
-					if (me.item_group) {
-						me.render_item_sub_categories(result.message[3]);
+						if (me.item_group) {
+							me.render_item_sub_categories(result.message[3]);
+						}
+						// Render views
+						me.render_list_view(result.message[0], result.message[2]);
+						me.render_grid_view(result.message[0], result.message[2]);
+						me.products = result.message[0];
 					}
-					// Render views
-					me.render_list_view(result.message[0], result.message[2]);
-					me.render_grid_view(result.message[0], result.message[2]);
-					me.products = result.message[0];
 
 					// Bottom paging
 					me.add_paging_section(result.message[2]);
@@ -238,15 +245,19 @@
 	}
 
 	render_no_products_section() {
-		$("#products-area").append(`
-			<div class="d-flex justify-content-center p-3 text-muted">
-				${ __('No products found') }
+		this.products_section.append(`
+			<br><br><br>
+			<div class="cart-empty frappe-card">
+				<div class="cart-empty-state">
+					<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty Cart">
+				</div>
+				<div class="cart-empty-message mt-4">${ __('No products found') }</p>
 			</div>
 		`);
 	}
 
 	render_item_sub_categories(categories) {
-		if (categories) {
+		if (categories && categories.length) {
 			let sub_group_html = `
 				<div class="sub-category-container">
 					<div class="heading"> ${ __('Sub Categories') } </div>
diff --git a/erpnext/public/js/shopping_cart.js b/erpnext/public/js/shopping_cart.js
index 331d04e..80f731e 100644
--- a/erpnext/public/js/shopping_cart.js
+++ b/erpnext/public/js/shopping_cart.js
@@ -54,7 +54,6 @@
 	// update login
 	shopping_cart.show_shoppingcart_dropdown();
 	shopping_cart.set_cart_count();
-	shopping_cart.bind_dropdown_cart_buttons();
 	shopping_cart.show_cart_navbar();
 });
 
@@ -75,7 +74,7 @@
 	},
 
 	update_cart: function(opts) {
-		if(frappe.session.user==="Guest") {
+		if (frappe.session.user==="Guest") {
 			if(localStorage) {
 				localStorage.setItem("last_visited", window.location.pathname);
 			}
@@ -156,29 +155,6 @@
 		});
 	},
 
-
-	bind_dropdown_cart_buttons: function () {
-		$(".cart-icon").on('click', '.number-spinner button', function () {
-			var btn = $(this),
-				input = btn.closest('.number-spinner').find('input'),
-				oldValue = input.val().trim(),
-				newVal = 0;
-
-			if (btn.attr('data-dir') == 'up') {
-				newVal = parseInt(oldValue) + 1;
-			} else {
-				if (oldValue > 1) {
-					newVal = parseInt(oldValue) - 1;
-				}
-			}
-			input.val(newVal);
-			var item_code = input.attr("data-item-code");
-			shopping_cart.shopping_cart_update({item_code, qty: newVal, cart_dropdown: true});
-			return false;
-		});
-
-	},
-
 	show_cart_navbar: function () {
 		frappe.call({
 			method: "erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings.is_cart_enabled",
diff --git a/erpnext/public/js/wishlist.js b/erpnext/public/js/wishlist.js
index 11dae35..1c5bee6 100644
--- a/erpnext/public/js/wishlist.js
+++ b/erpnext/public/js/wishlist.js
@@ -58,6 +58,8 @@
 
 	bind_remove_action: function() {
 		// remove item from wishlist
+		let me = this;
+
 		$('.page_content').on("click", ".remove-wish", (e) => {
 			const $remove_wish_btn = $(e.currentTarget);
 			let item_code = $remove_wish_btn.data("item-code");
@@ -65,6 +67,10 @@
 			let success_action = function() {
 				const $card_wrapper = $remove_wish_btn.closest(".wishlist-card");
 				$card_wrapper.addClass("wish-removed");
+				if (frappe.get_cookie("wish_count") == 0) {
+					$(".page_content").empty();
+					me.render_empty_state();
+				}
 			};
 			let args = { item_code: item_code };
 			this.add_remove_from_wishlist("remove", args, success_action);
@@ -78,6 +84,14 @@
 			const $wish_icon = $btn.find('.wish-icon');
 			let me = this;
 
+			if(frappe.session.user==="Guest") {
+				if(localStorage) {
+					localStorage.setItem("last_visited", window.location.pathname);
+				}
+				window.location.href = "/login";
+				return;
+			}
+
 			let success_action = function() {
 				e_commerce.wishlist.set_wishlist_count();
 			};
@@ -122,30 +136,48 @@
 			success_action: method to execute on successs,
 			failure_action: method to execute on failure,
 			async: make call asynchronously (true/false).	*/
-		let method = "erpnext.e_commerce.doctype.wishlist.wishlist.add_to_wishlist";
-		if (action === "remove") {
-			method = "erpnext.e_commerce.doctype.wishlist.wishlist.remove_from_wishlist";
-		}
-
-		frappe.call({
-			async: async,
-			type: "POST",
-			method: method,
-			args: args,
-			callback: function (r) {
-				if (r.exc) {
-					if (failure_action && (typeof failure_action === 'function')) {
-						failure_action();
-					}
-					frappe.msgprint({
-						message: __("Sorry, something went wrong. Please refresh."),
-						indicator: "red", title: __("Note")
-					});
-				} else if (success_action && (typeof success_action === 'function')) {
-					success_action();
-				}
+		if (frappe.session.user==="Guest") {
+			if(localStorage) {
+				localStorage.setItem("last_visited", window.location.pathname);
 			}
-		});
+			window.location.href = "/login";
+		} else {
+			let method = "erpnext.e_commerce.doctype.wishlist.wishlist.add_to_wishlist";
+			if (action === "remove") {
+				method = "erpnext.e_commerce.doctype.wishlist.wishlist.remove_from_wishlist";
+			}
+
+			frappe.call({
+				async: async,
+				type: "POST",
+				method: method,
+				args: args,
+				callback: function (r) {
+					if (r.exc) {
+						if (failure_action && (typeof failure_action === 'function')) {
+							failure_action();
+						}
+						frappe.msgprint({
+							message: __("Sorry, something went wrong. Please refresh."),
+							indicator: "red", title: __("Note")
+						});
+					} else if (success_action && (typeof success_action === 'function')) {
+						success_action();
+					}
+				}
+			});
+		}
+	},
+
+	render_empty_state() {
+		$(".page_content").append(`
+			<div class="cart-empty frappe-card">
+				<div class="cart-empty-state">
+					<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty Cart">
+				</div>
+				<div class="cart-empty-message mt-4">${ __('Wishlist is empty !') }</p>
+			</div>
+		`);
 	}
 
 });
diff --git a/erpnext/templates/generators/item/item_reviews.html b/erpnext/templates/generators/item/item_reviews.html
index fd03a82..cd38bf3 100644
--- a/erpnext/templates/generators/item/item_reviews.html
+++ b/erpnext/templates/generators/item/item_reviews.html
@@ -5,11 +5,11 @@
 		{{ ratings_summary(reviews, reviews_per_rating, average_rating, average_whole_rating) }}
 
 		<!-- Write a Review for legitimate users -->
-		{% if frappe.session.user != "Guest" %}
-		<button class="btn btn-light btn-write-review mr-2 mt-4 mb-4 w-100"
-			data-web-item="{{ doc.name }}">
-			{{ _("Write a Review") }}
-		</button>
+		{% if frappe.session.user != "Guest" and user_is_customer %}
+			<button class="btn btn-light btn-write-review mr-2 mt-4 mb-4 w-100"
+				data-web-item="{{ doc.name }}">
+				{{ _("Write a Review") }}
+			</button>
 		{% endif %}
 	</div>
 
diff --git a/erpnext/templates/includes/cart.js b/erpnext/templates/includes/cart.js
index f2b026c..f0781ab 100644
--- a/erpnext/templates/includes/cart.js
+++ b/erpnext/templates/includes/cart.js
@@ -19,7 +19,6 @@
 		shopping_cart.bind_request_quotation();
 		shopping_cart.bind_change_qty();
 		shopping_cart.bind_change_notes();
-		shopping_cart.bind_dropdown_cart_buttons();
 		shopping_cart.bind_coupon_code();
 	},
 
@@ -129,8 +128,14 @@
 				}
 			}
 			input.val(newVal);
+
+			let notes = input.closest("td").siblings().find(".notes").text().trim();
 			var item_code = input.attr("data-item-code");
-			shopping_cart.shopping_cart_update({item_code, qty: newVal});
+			shopping_cart.shopping_cart_update({
+				item_code,
+				qty: newVal,
+				additional_notes: notes
+			});
 		});
 	},
 
diff --git a/erpnext/templates/includes/cart/cart_items.html b/erpnext/templates/includes/cart/cart_items.html
index 75441c4..d534b8f 100644
--- a/erpnext/templates/includes/cart/cart_items.html
+++ b/erpnext/templates/includes/cart/cart_items.html
@@ -13,7 +13,7 @@
 			{{ _('Variant of') }} <a href="{{frappe.db.get_value('Item', variant_of, 'route')}}">{{ variant_of }}</a>
 		</span>
 		{% endif %}
-		<div class="mt-2">
+		<div class="mt-2 notes">
 			<textarea data-item-code="{{d.item_code}}" class="form-control" rows="2" placeholder="{{ _('Add notes') }}">{{d.additional_notes or ''}}</textarea>
 		</div>
 	</td>
diff --git a/erpnext/templates/pages/wishlist.html b/erpnext/templates/pages/wishlist.html
index 4c039e3..7a81ded 100644
--- a/erpnext/templates/pages/wishlist.html
+++ b/erpnext/templates/pages/wishlist.html
@@ -17,8 +17,12 @@
 		</div>
 	</div>
 {% else %}
-	<!-- TODO: Make empty state for wishlist -->
-	{% include "erpnext/www/all-products/not_found.html" %}
+	<div class="cart-empty frappe-card">
+		<div class="cart-empty-state">
+			<img src="/assets/erpnext/images/ui-states/cart-empty-state.png" alt="Empty Cart">
+		</div>
+		<div class="cart-empty-message mt-4">{{ _('Wishlist is empty!') }}</p>
+	</div>
 {% endif %}
 
 {% endblock %}
\ No newline at end of file