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

Review Result ?

jattin01/avriti · ab8c8576
The commit adds multiple frontend improvements including UI elements, image rendering, CSS styling for products, and content rendering with innerHTML. There are some concerns about security with the widespread use of dangerouslySetInnerHTML which can introduce XSS risks. Quality is decent given CSS and UI updates, but better validation or sanitization of HTML content would improve safety. Business value is moderate reflecting user-facing feature completions. Bug risk is moderate due to potential unsafe HTML injection and some dependencies on environment variables without error handling. Fake work risk is low as changes are substantial and related to frontend functionality.
Quality ?
75%
Security ?
30%
Business Value ?
70%
Maintainability ?
68%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Security Issue
Where components/ProductDetailSection.tsx:164
Issue / Evidence security risk with dangerouslySetInnerHTML
Suggested Fix sanitize HTML content before rendering
Security Issue
Where components/product-accordion.tsx:267
Issue / Evidence security risk with dangerouslySetInnerHTML
Suggested Fix sanitize HTML content before rendering
Security Issue
Where components/product-accordion.tsx:302
Issue / Evidence security risk with dangerouslySetInnerHTML
Suggested Fix sanitize HTML content before rendering
Security Issue
Where components/product-accordion.tsx:313
Issue / Evidence security risk with dangerouslySetInnerHTML
Suggested Fix sanitize HTML content before rendering
Security Issue
Where components/product-accordion.tsx:324
Issue / Evidence security risk with dangerouslySetInnerHTML
Suggested Fix sanitize HTML content before rendering
Missing Error Handling In Fetch Call
Where app/contact/page.tsx:30
Issue / Evidence missing error handling in fetch call
Suggested Fix add try/catch and handle fetch errors gracefully
Reliance On Process.env.next Public Api Ur...
Where app/contact/page.tsx:30
Issue / Evidence reliance on process.env.NEXT_PUBLIC_API_URL without fallback
Suggested Fix validate environment variable presence and provide fallback or error
Missing Validation
Where app/services/[slug]/page.tsx:79
Issue / Evidence missing alt text validation
Suggested Fix ensure image alt text is always present for accessibility
Too Generic Description
Where commit message
Issue / Evidence too generic description
Suggested Fix provide more detailed commit messages describing key changes and motivations
Code Change Preview · app/contact/page.tsx ?
Removed / Before Commit
- // import { Mail, MapPin, MessageCircle, Phone } from "lucide-react";
- // import { Badge } from "@/components/ui/badge";
- // import { Button } from "@/components/ui/button";
- // import { Card } from "@/components/ui/card";
- // import { Input } from "@/components/ui/input";
- // import InnerBanner from "@/components/inner-banner";
- 
- // export default function ContactPage() {
- //   return (
- //     <div>
- //       <InnerBanner title="Contact Us" />
- 
- //       <section className="mx-auto grid max-w-7xl gap-8 px-4 py-14 sm:px-6 lg:grid-cols-[0.8fr_1.2fr] lg:px-8">
- //         <div className="space-y-4">
- //           {[
- //             { icon: MessageCircle, label: "WhatsApp", value: "+91 00000 00000" },
- //             { icon: Mail, label: "Email", value: "hello@avriti.com" },
- //             { icon: Phone, label: "Consultation support", value: "Mon-Sat, 10 AM - 7 PM IST" },
Added / After Commit
+ 
+ "use client";
+ 
+ useEffect(() => {
+ const loadServices = async () => {
+ try {
+         const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/service-details`);
+ const data = await res.json();
+         const names = (data?.data || [])
+           .map((s: { name?: string }) => s.name)
+ .filter(Boolean);
+ setServices(names);
+ } catch (err) {
Removed / Before Commit
- <div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-14 items-start">
- 
- {/* LEFT — Image */}
-         <div className="relative overflow-hidden border border-[#ffebdfde] rounded-[10px] p-[20px] md:p-[40px] min-h-[280px] flex items-center justify-center">
- {service.image ? (
-             <img src={service.image} alt={service.name} className="block mx-auto max-w-[42%]" />
- ) : service.icon ? (
- <img src={service.icon} alt={service.name} className="block mx-auto h-28 w-28 object-contain" />
- ) : (
Added / After Commit
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-8 md:gap-14 items-start">
+ 
+ {/* LEFT — Image */}
+         <div className="relative overflow-hidden border border-[#ffebdfde] rounded-[10px] p-[20px] md:p-[40px] min-h-[380px] max-h-[400px] flex items-center justify-center">
+ {service.image ? (
+             <img src={service.image} alt={service.name} className="block mx-auto max-w-[80%] max-h-90 object-contain" />
+ ) : service.icon ? (
+ <img src={service.icon} alt={service.name} className="block mx-auto h-28 w-28 object-contain" />
+ ) : (
Removed / Before Commit
- href={`/services/${sd.slug}`}
- className="group flex flex-col gap-4 rounded-md bg-[#f2f2f2] p-6 transition hover:bg-[#eef2ff]"
- >
-                   <div className="flex h-16 w-16 items-center justify-center rounded-full border border-[var(--color-primary-300)] text-[var(--color-primary-700)]">
- {sd.icon ? (
- <img src={sd.icon} alt={sd.name} className="h-8 w-8 object-contain" />
- ) : null}
- </div>
- <h2 className="text-lg font-semibold leading-tight text-[var(--color-primary-700)]">
Added / After Commit
+ href={`/services/${sd.slug}`}
+ className="group flex flex-col gap-4 rounded-md bg-[#f2f2f2] p-6 transition hover:bg-[#eef2ff]"
+ >
+                   <div className="flex h-16 w-16 items-center justify-center overflow-hidden rounded-full border border-[var(--color-primary-300)] text-[var(--color-primary-700)]">
+ {sd.icon ? (
+ <img src={sd.icon} alt={sd.name} className="h-8 w-8 object-contain" />
+                     ) : sd.image ? (
+                       <img src={sd.image} alt={sd.name} className="h-full  object-cover" />
+ ) : null}
+ </div>
+ <h2 className="text-lg font-semibold leading-tight text-[var(--color-primary-700)]">
Removed / Before Commit

                                                
Added / After Commit
+ /* Rich content (Quill/HTML) — matches the site's body text style */
+ 
+ .product-content {
+   font-size: 15px;
+   line-height: 1.7;
+   color: #6b6060;
+ }
+ 
+ .product-content p { margin: 0 0 12px; }
+ .product-content p:last-child { margin-bottom: 0; }
+ /* collapse Quill's empty spacer paragraphs so gaps stay even */
+ .product-content p:empty { display: none; }
+ 
+ .product-content ul { list-style: disc !important; padding-left: 22px !important; margin: 0 0 12px; }
+ .product-content ol { list-style: decimal !important; padding-left: 22px !important; margin: 0 0 12px; }
+ .product-content li { display: list-item !important; margin-bottom: 6px; }
+ .product-content li:last-child { margin-bottom: 0; }
+ 
Removed / Before Commit
- "use client";
- 
- import { useState, useEffect } from "react";
- 
- type AccordionItem = {
- title: string;
- ...(dailyUse
- ? [{ title: "Daily Use", defaultOpen: false, content: <div style={{ whiteSpace: "pre-line" }}>{dailyUse}</div> }]
- : []),
-     ...(whatToExpect
-       ? [{ title: "What to Expect", defaultOpen: false, content: <div style={{ whiteSpace: "pre-line" }}>{whatToExpect}</div> }]
-       : []),
- ...(storageInstructions
- ? [
- {
- title: "Storage Instructions",
- defaultOpen: false,
- content: (
Added / After Commit
+ "use client";
+ 
+ import { useState, useEffect } from "react";
+ import "@/app/shop/product.css";
+ 
+ type AccordionItem = {
+ title: string;
+ ...(dailyUse
+ ? [{ title: "Daily Use", defaultOpen: false, content: <div style={{ whiteSpace: "pre-line" }}>{dailyUse}</div> }]
+ : []),
+ ...(storageInstructions
+ ? [
+ {
+ title: "Storage Instructions",
+ defaultOpen: false,
+ content: (
+ <div
+                 className="product-content"
Removed / Before Commit
- if (found) {
- setProduct(found);
- // // Old: setSelectedAttr(found.attributes?.[0] ?? null);
-             const firstInStock = (found.attributes ?? []).find((a: Attribute) => a.in_stock) ?? found.attributes?.[0] ?? null;
- setSelectedAttr(firstInStock);
- setActiveImg(found.thumbnail?.[0] ? `${apiUrl}/${found.thumbnail[0]}` : null);
- }
- className="block mx-auto max-w-[40%]"
- />
- ) : (
-               <div className="flex flex-col items-center justify-center gap-2 text-[#d6d3cc]">
- <svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1">
- <rect x="3" y="3" width="18" height="18" rx="2" strokeLinecap="round"/>
- <circle cx="8.5" cy="8.5" r="1.5"/>
- {product.closing_tagline && (
- <div className="mt-1 px-1 py-1 text-[13px] italic text-[#9e8a7a]">
- <span className="font-semibold not-italic text-[#2c2420]">Tagline: </span>
-                 {product.closing_tagline}
Added / After Commit
+ if (found) {
+ setProduct(found);
+ // // Old: setSelectedAttr(found.attributes?.[0] ?? null);
+             // Prefer an attribute that has a value; fall back to first in-stock / first.
+             const attrs: Attribute[] = found.attributes ?? [];
+             const withValue = attrs.filter((a) => (a.value ?? "").trim() !== "");
+             const pool = withValue.length > 0 ? withValue : attrs;
+             const firstInStock = pool.find((a) => a.in_stock) ?? pool[0] ?? null;
+ setSelectedAttr(firstInStock);
+ setActiveImg(found.thumbnail?.[0] ? `${apiUrl}/${found.thumbnail[0]}` : null);
+ }
+ className="block mx-auto max-w-[40%]"
+ />
+ ) : (
+               <div className="flex flex-col items-center justify-center gap-2 text-[#d6d3cc] min-h-[280px] max-h-[280px] ">
+ <svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="1">
+ <rect x="3" y="3" width="18" height="18" rx="2" strokeLinecap="round"/>
+ <circle cx="8.5" cy="8.5" r="1.5"/>