Showing AI reviews for avriti
Project AI Score ?
63%
Quality Avg ?
68%
Security Avg ?
45%
Reviews ?
56

Review Result ?

jattin01/avriti · 0b2ae90b
This commit adds a profile page with customer profile management including profile image upload and address display. It includes appropriate states, API calls with authentication headers, and form handling. The user can edit and save their profile information, which is reflected in localStorage for persistence. The UI supports both display and edit modes with clear feedback messages. The profile image upload uses FormData and updates the UI upon success. Some improvements in security checks, input validation, and error handling are recommended.
Quality ?
85%
Security ?
50%
Business Value ?
85%
Maintainability ?
83%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Missing Validation
Where app/profile/page.tsx:170
Issue / Evidence Sending auth headers directly without validation
Suggested Fix add validation or refresh tokens before API calls to improve security and bug risk
Empty Catch Block On Localstorage Set
Where app/profile/page.tsx:134
Issue / Evidence Empty catch block on localStorage set
Suggested Fix add error logging or handling to debug issues on localStorage failures
Missing Validation
Where app/profile/page.tsx:264
Issue / Evidence Email input missing type and validation aside from placeholder
Suggested Fix add proper email validation on client side to improve quality and reduce bug risks
Missing Validation
Where app/profile/page.tsx:210
Issue / Evidence No validation of uploaded image file
Suggested Fix add client-side file type and size validation to reduce bug risks and security issues (e.g. large files or invalid types)
Redirect To Login On Missing Headers
Where app/profile/page.tsx:109
Issue / Evidence Redirect to login on missing headers
Suggested Fix add a user feedback before redirect or handle with route guards to improve user experience and business value
Non Descriptive Message
Where commit message
Issue / Evidence non-descriptive message
Suggested Fix replace with a more detailed commit message explaining what profile page features and fixes are included to improve traceability and business value
Code Change Preview · app/checkout/page.tsx ?
Removed / Before Commit
- };
- 
- const saveAddress = async () => {
-     if (!modalForm.full_name || !modalForm.phone || !modalForm.address_line1 ||
- !modalForm.city || !modalForm.state || !modalForm.pincode || !modalForm.country) {
- setModalError("Please fill all required fields.");
- return;
- )}
- 
- <div className="grid gap-4 sm:grid-cols-2">
-               <label className="block">
-                 <span className={labelCls}>Full Name *</span>
-                 <input type="text" value={ship.full_name} onChange={e => setShip(s => ({ ...s, full_name: e.target.value }))} placeholder="John Doe" className={inputCls} />
-               </label>
-               <label className="block">
-                 <span className={labelCls}>Phone *</span>
-                 <input type="tel" value={ship.phone} onChange={e => setShip(s => ({ ...s, phone: e.target.value }))} placeholder="+91 98765 43210" className={inputCls} />
-               </label>
Added / After Commit
+ };
+ 
+ const saveAddress = async () => {
+     if (!modalForm.full_name || !modalForm.phone || !modalForm.email || !modalForm.address_line1 ||
+ !modalForm.city || !modalForm.state || !modalForm.pincode || !modalForm.country) {
+ setModalError("Please fill all required fields.");
+ return;
+ )}
+ 
+ <div className="grid gap-4 sm:grid-cols-2">
+               {[
+                 ["Full Name", ship.full_name],
+                 ["Phone", ship.phone],
+                 ["Email", ship.email],
+                 ["Country", ship.country],
+                 ["Address Line 1", ship.address_line1, "sm:col-span-2"],
+                 ["Address Line 2", ship.address_line2, "sm:col-span-2"],
+                 ["Landmark", ship.landmark],
Removed / Before Commit
- import type { ReactNode } from "react";
- import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
- import {
-   faBoxOpen, faPen, faTrash, faPlus,
- } from "@fortawesome/free-solid-svg-icons";
- 
- 
- interface Address {
- id: number;
-   type: string;
- full_name: string;
- phone: string;
- email?: string;
- address_line1: string;
- address_line2?: string;
- city: string;
- state: string;
- pincode: string;
Added / After Commit
+ import type { ReactNode } from "react";
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+ import {
+   faBoxOpen, faPen,
+ } from "@fortawesome/free-solid-svg-icons";
+ import { CustomerAddresses } from "@/components/customer-addresses";
+ 
+ 
+ interface Address {
+ id: number;
+ full_name: string;
+ phone: string;
+ email?: string;
+ address_line1: string;
+ address_line2?: string;
+   landmark?: string;
+ city: string;
+ state: string;
Removed / Before Commit
- category: string;
- badge: string;
- description: string;
- };
- 
- export default function ProductDetailPage() {
- const params = useParams();
- const slug = Array.isArray(params?.slug) ? params.slug[0] : (params?.slug ?? "");
- 
- const [featuredProducts, setFeaturedProducts] = useState<FeaturedProduct[]>([]);
- 
- useEffect(() => {
-     fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/product?featured=true`)
- .then((res) => res.json())
- .then((data) => {
- if (data.success && Array.isArray(data.data)) {
-           const mapped: FeaturedProduct[] = data.data.map((p: any, i: number) => {
- const attr = p.attributes?.find((a: any) => a.in_stock) ?? p.attributes?.find((a: any) => a.sr_no === 1);
Added / After Commit
+ category: string;
+ badge: string;
+ description: string;
+   longdescription: string;
+ };
+ 
+ export default function ProductDetailPage() {
+ const params = useParams();
+ const slug = Array.isArray(params?.slug) ? params.slug[0] : (params?.slug ?? "");
+ 
+ const [featuredProducts, setFeaturedProducts] = useState<FeaturedProduct[]>([]);
+   const [description, setDescription] = useState("");
+ 
+ useEffect(() => {
+     fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/product`)
+ .then((res) => res.json())
+ .then((data) => {
+ if (data.success && Array.isArray(data.data)) {
Removed / Before Commit

                                                
Added / After Commit
+ "use client";
+ 
+ import { useState } from "react";
+ 
+ export interface CustomerAddress {
+   id: number;
+   full_name: string;
+   phone: string;
+   email?: string;
+   address_line1: string;
+   address_line2?: string;
+   landmark?: string;
+   city: string;
+   state: string;
+   pincode: string;
+   country: string;
+   address_type: string;
+   is_default: boolean;
Removed / Before Commit
- {product.attrValue ? ` - ${product.attrValue}${product.variantName ? ` ${product.variantName}` : ''}` : ''}
- </h3>
- <button type="button" onClick={handleWishlist} aria-label="Add to wishlist" className="cursor-pointer">
-             <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill={wishlisted ? "#0b3dba" : "none"} stroke="#0b3dba" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
- <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
- </svg>
- </button>
Added / After Commit
+ {product.attrValue ? ` - ${product.attrValue}${product.variantName ? ` ${product.variantName}` : ''}` : ''}
+ </h3>
+ <button type="button" onClick={handleWishlist} aria-label="Add to wishlist" className="cursor-pointer">
+             <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill={wishlisted ? "#FF0000" : "none"} stroke="#FF0000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
+ <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
+ </svg>
+ </button>
Removed / Before Commit
- 
- const tabs = ["Description", "Reviews", "Shipping"];
- 
- const tabContent: Record<string, React.ReactNode> = {
- Description: (
-     <p className="text-gray-600 text-sm leading-relaxed">
-       The world is loud. Notifications, deadlines, demands. Everyone wants your attention, your time, your energy. Somewhere in that noise, you lose yourself.The world is loud. Notifications, deadlines, demands. Everyone wants your attention, your time, your energy. Somewhere in that noise, you lose yourself.The world is loud. Notifications, deadlines, demands. Everyone wants your attention, your time, your energy. Somewhere in that noise, you lose yourself.
-     </p>
- ),
- Reviews: (
- <p className="text-gray-600 text-sm leading-relaxed">
- Free delivery on orders above ₹499. Standard delivery in 3-5 business days.
- </p>
- ),
- };
- 
- export default function ProductTabs() {
- const [activeTab, setActiveTab] = useState("Description");
Added / After Commit
+ 
+ const tabs = ["Description", "Reviews", "Shipping"];
+ 
+ const tabContent = (description?: string): Record<string, React.ReactNode> => ({
+ Description: (
+     <div
+       className="text-gray-600 text-sm leading-relaxed"
+       dangerouslySetInnerHTML={{ __html: description || "No description available." }}
+     />
+ ),
+ Reviews: (
+ <p className="text-gray-600 text-sm leading-relaxed">
+ Free delivery on orders above ₹499. Standard delivery in 3-5 business days.
+ </p>
+ ),
+ });
+ 
+ export default function ProductTabs({ description }: { description?: string }) {
Removed / Before Commit
- title: string;
- slug: string;
- short_description?: string;
- attributes?: Attribute[];
- thumbnail?: string[];
- category?: { name: string };
- )}</div>
- {/* Attribute Pills */}
- {product.attributes && product.attributes.length > 0 && (
-               <div className="mb-5 flex gap-2 items-center">
-                 <p className="text-xs font-semibold uppercase  text-[#000]">Select {product.variant?.name ?? "Variant"} :</p>
- 
-                 <div className="flex flex-wrap gap-2">
- {/* // Old: no out-of-stock strikethrough on variant pills */}
- {product.attributes.map((attr) => (
- <button
Added / After Commit
+ title: string;
+ slug: string;
+ short_description?: string;
+   
+ attributes?: Attribute[];
+ thumbnail?: string[];
+ category?: { name: string };
+ )}</div>
+ {/* Attribute Pills */}
+ {product.attributes && product.attributes.length > 0 && (
+               <div className="mb-5 flex gap-2 items-center ">
+                 <p className="text-xs font-semibold uppercase shrink-0  text-[#000]">Select {product.variant?.name ?? "Variant"} :</p>
+ 
+                 <div className="flex overflow-x-auto whitespace-nowrap gap-2 scrollbar-hide [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]">
+ {/* // Old: no out-of-stock strikethrough on variant pills */}
+ {product.attributes.map((attr) => (
+ <button
Removed / Before Commit
- category?: string | null;
- };
- 
- const API = process.env.NEXT_PUBLIC_API_URL ?? "";
- 
- export async function apiGetWishlist(): Promise<WishlistItem[]> {
- const token = getToken();
Added / After Commit
+ category?: string | null;
+ };
+ 
+ const API = process.env.NEXT_PUBLIC_API_URL;
+ 
+ export async function apiGetWishlist(): Promise<WishlistItem[]> {
+ const token = getToken();