Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
90 changes: 89 additions & 1 deletion src/actions/chat_actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ interface JobsResponse {
}

export const fetchJobs = async (chatdata: any) => {
console.log("Sending API request with data:", chatdata);
const token = await getCookie("token");

try {
Expand Down Expand Up @@ -35,4 +34,93 @@ export const fetchJobs = async (chatdata: any) => {
console.error("Error fetching jobs:", error)
throw error; // Re-throw to handle in the component
}
}

export const deleteById = async (path: string) => {
const token = await getCookie("token");

try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}${path}`,
{
method: "DELETE",
headers: {
"Content-Type": "application/json",
Cookie: `token=${token}`,
},
credentials: "include",
}
);

if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}

const data = await response.json();
return data;
Comment on lines +59 to +60
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function may incorrectly throw an error on a successful deletion. A DELETE request can successfully complete with a 204 No Content status code, which means the response body will be empty. Attempting to call response.json() on an empty body will cause a JSON parsing error, making the function throw even though the operation succeeded on the backend.

Confidence: 5/5

Suggested Fix
Suggested change
const data = await response.json();
return data;
if (response.status === 204) {
return null;
}
return response.json();

To fix this, check if the response status is 204. If it is, you can return null or another indicator of success, avoiding the attempt to parse a non-existent JSON body. This ensures that successful deletions are handled correctly.

Prompt for AI

Copy this prompt to your AI IDE to fix this issue locally:

In src/actions/chat_actions.ts around line 59, the code unconditionally calls response.json(), which will fail for successful DELETE requests that return a 204 No Content status. Before calling response.json(), add a check for `response.status === 204`. If it's true, return null to indicate success without a body. Otherwise, proceed to call and return `response.json()`.

📍 This suggestion applies to lines 59-60

} catch (error) {
console.error("Error deleting resource:", error);
throw error;
}
}

export const renameChatById = async (chatId: string, newName: string) => {
const token = await getCookie("token");

try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/chat/rename?id=${chatId}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
},

credentials: "include",
body: JSON.stringify({
name: newName,
}),
}
);

if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}

const data = await response.json();
console.log("Chat renamed successfully:", data);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug console.log statement should be removed before merging to production. This log provides minimal value and clutters the console output.

Suggested change
console.log("Chat renamed successfully:", data);

Copilot uses AI. Check for mistakes.
return data;
} catch (error) {
console.error("Error renaming chat:", error);
throw error;
}
}

export const fetchChats = async () => {
const token = await getCookie("token");

try {
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_BASE_URL}/api/chat/all`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},

credentials: "include",
}
);

if (!response.ok) {
throw new Error(`API request failed with status ${response.status}`);
}

const data = await response.json();
console.log("Chats fetched successfully:", data);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Debug console.log statement should be removed before merging to production. This log provides minimal value and clutters the console output.

Suggested change
console.log("Chats fetched successfully:", data);

Copilot uses AI. Check for mistakes.
return data;
} catch (error) {
console.error("Error fetching chats:", error);
throw error;
}
}
90 changes: 77 additions & 13 deletions src/app/(root)/(chat)/_components/heroSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ import Image from 'next/image';
import { FaPaperclip, FaUpload, FaGlobe, FaTwitter, FaLinkedin, FaGithub } from 'react-icons/fa';
import { useGoogleLogin } from '@react-oauth/google';
import { useAppDispatch } from '@/redux/hooks';
import axios from 'axios';
import { userData } from '@/redux/slices/userSlice';
import GlowButton from '@/components/ui/glowButton';
import toast from 'react-hot-toast';
import { Loader2, SparklesIcon } from 'lucide-react';
import JobSearchResults from './job-result';
Expand All @@ -28,6 +27,13 @@ const HeroSection = ({ isLoggedIn }: { isLoggedIn: boolean }) => {
const [showResumePopup, setShowResumePopup] = useState(false); // New state for resume popup
const [jobApiData, setJobApiData] = useState<any>(null)
const [isApiLoading, setIsApiLoading] = useState(false)
const buttonItems = [
{ text: 'NEW', secondaryText: 'Build a mobile app with Expo', icon: null },
{ text: 'Recharts dashboard', secondaryText: null, icon: null },
{ text: 'Habit tracker', secondaryText: null, icon: null },
{ text: 'Real estate listings', secondaryText: null, icon: null },
{ text: 'Developer portfolio', secondaryText: null, icon: null }
Comment on lines +31 to +35
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buttonItems array defines properties (secondaryText, icon) that are never used. The first item has secondaryText 'Build a mobile app with Expo' and all items have icon: null, but these properties are not rendered anywhere. Additionally, buttonItems.slice(1) is used, meaning the first item ('NEW') is never displayed. Consider cleaning up unused data or implementing the missing UI elements.

Suggested change
{ text: 'NEW', secondaryText: 'Build a mobile app with Expo', icon: null },
{ text: 'Recharts dashboard', secondaryText: null, icon: null },
{ text: 'Habit tracker', secondaryText: null, icon: null },
{ text: 'Real estate listings', secondaryText: null, icon: null },
{ text: 'Developer portfolio', secondaryText: null, icon: null }
{ text: 'NEW' },
{ text: 'Recharts dashboard' },
{ text: 'Habit tracker' },
{ text: 'Real estate listings' },
{ text: 'Developer portfolio' }

Copilot uses AI. Check for mistakes.
];
Comment on lines +30 to +36
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The buttonItems array is defined inside the component body, causing it to be recreated on every render. Since this is static data, it should be moved outside the component to prevent unnecessary re-renders and improve performance.

Copilot uses AI. Check for mistakes.

useEffect(() => {
const storedCount = localStorage.getItem(STORAGE_KEY);
Expand Down Expand Up @@ -98,7 +104,7 @@ const HeroSection = ({ isLoggedIn }: { isLoggedIn: boolean }) => {
transition: 'opacity 0.25s linear',
} as React.CSSProperties}
>
{/* Light Rays (existing code) */}
{/* Light Ray 1 */}
<div className="absolute rounded-full"
style={{
background: 'var(--ray-gradient)',
Expand All @@ -110,7 +116,64 @@ const HeroSection = ({ isLoggedIn }: { isLoggedIn: boolean }) => {
filter: 'blur(110px)'
}}
/>
{/* Other light rays... */}
{/* Light Ray 2 */}
<div className="absolute rounded-full"
style={{
background: 'var(--ray-gradient)',
width: '110px',
height: '400px',
transform: 'rotate(-20deg)',
top: '-280px',
left: '350px',
mixBlendMode: 'overlay',
opacity: '0.6',
filter: 'blur(60px)'
}}
/>
{/* Light Ray 3 */}
<div className="absolute rounded-full"
style={{
background: 'var(--ray-gradient)',
width: '400px',
height: '370px',
transform: 'rotate(95deg)',
top: '-350px',
left: '200px',
mixBlendMode: 'overlay',
opacity: '0.6',
filter: 'blur(21px)'
}}
/>
{/* Light Ray 4 */}
<div className="absolute rounded-full"
style={{
background: 'var(--ray-gradient)',
position: 'absolute',
width: '330px',
height: '370px',
transform: 'rotate(75deg)',
top: '-330px',
left: '50px',
mixBlendMode: 'overlay',
opacity: '0.5',
filter: 'blur(21px)'
}}
/>
{/* Light Ray 5 */}
<div className="absolute rounded-full"
style={{
background: 'var(--ray-gradient)',
position: 'absolute',
width: '110px',
height: '400px',
transform: 'rotate(-40deg)',
top: '-280px',
left: '-10px',
mixBlendMode: 'overlay',
opacity: '0.8',
filter: 'blur(60px)'
}}
/>
</div>

{/* Conditional Rendering for Hero Content or Job Search Results */}
Expand Down Expand Up @@ -173,15 +236,16 @@ const HeroSection = ({ isLoggedIn }: { isLoggedIn: boolean }) => {
{/* Only show suggestion buttons when no results */}
{(!showResults || queryCount >= QUERY_LIMIT) && (
<div className="flex flex-wrap justify-center gap-3 mt-6">
{['Recharts dashboard', 'Habit tracker', 'Real estate listings', 'Developer portfolio'].map((item) => (
<button
key={item}
className="bg-zinc-700 hover:bg-zinc-600 text-white rounded-lg px-5 py-2 text-sm font-medium"
>
{item}
</button>
))}
</div>
{buttonItems.slice(1).map((item) => (
<GlowButton
key={item.text}
size="sm"
variant="secondary"
>
{item.text}
</GlowButton>
))}
</div>
)}
</div>
)}
Expand Down
Loading