<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lukas</title>
    <description>The latest articles on DEV Community by Lukas (@eless).</description>
    <link>https://dev.to/eless</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1258203%2Fe7a4cd50-f08f-433a-8373-fa7faf7bfd01.png</url>
      <title>DEV Community: Lukas</title>
      <link>https://dev.to/eless</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eless"/>
    <language>en</language>
    <item>
      <title>Im struggling with SSR and CSR.</title>
      <dc:creator>Lukas</dc:creator>
      <pubDate>Tue, 16 Jan 2024 15:20:43 +0000</pubDate>
      <link>https://dev.to/eless/im-struggling-with-ssr-and-csr-1hej</link>
      <guid>https://dev.to/eless/im-struggling-with-ssr-and-csr-1hej</guid>
      <description>&lt;p&gt;I want to create a storage management system for dentists. I don't seem to understand the concept of SSR and CSR and how to properly use it in my project. I have a route app/stock/page.tsx and this file has the "use client" tag. Though I am almost certain this is not the right way, it works. With which I struggle the most is the data fetching and the Next.js API routes. The API Routes just wont work for me when I add /app/stock/api/route.ts and write a GET handler. When i check with Postman I get Error 404.&lt;br&gt;
I just need someone to tell me which functions or logic I should seperate into it's own file and why. &lt;br&gt;
On StackOverflow I just get downvotes and nobody wants to tell me what I'm doing wrong. Thank you in advance.&lt;/p&gt;

&lt;p&gt;The code is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";
import React, { useEffect, useState } from "react";
import "tailwindcss/tailwind.css";
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
import { Button } from "@/components/ui/button"

const StockPage: React.FC = () =&amp;gt; {
  const [items, setItems] = useState&amp;lt;any[]&amp;gt;([]);
  const [sortedItems, setSortedItems] = useState&amp;lt;any[]&amp;gt;([]);
  const [subcategories, setSubcategories] = useState&amp;lt;any[]&amp;gt;([]);
  const [selectedSubcategory, setSelectedSubcategory] = useState&amp;lt;any | null&amp;gt;(
    null
  );
  const [selectedItem, setSelectedItem] = useState&amp;lt;any | null&amp;gt;(null);

  useEffect(() =&amp;gt; {
    const fetchData = async () =&amp;gt; {
      try {
        const res = await fetch("http://localhost:5000/get_items", {
          method: "GET",
          cache: "no-store",
        });
        const data = await res.json();
        setItems(data);
        setSortedItems(data);
      } catch (error) {
        console.error("Error fetching data:", error);
      }
    };

    fetchData();
  }, []);

  useEffect(() =&amp;gt; {
    const fetchSubcategories = async () =&amp;gt; {
      try {
        const res = await fetch("http://localhost:5000/get_subcategories", {
          method: "GET",
          cache: "no-store",
        });
        const data = await res.json();
        setSubcategories(data);
      } catch (error) {
        console.error("Error fetching subcategories:", error);
      }
    };

    fetchSubcategories();
  }, []);

  const handleSortBySubcategory = (selectedSubcategory: any) =&amp;gt; {
    const sorted = items.filter((item) =&amp;gt; item.subcategory === selectedSubcategory.id);
    setSortedItems(sorted);
    setSelectedSubcategory(selectedSubcategory);
  };

  const handleViewAll = () =&amp;gt; {
    // Reset the sorting and display all items
    setSortedItems(items);
    setSelectedSubcategory(null);
  };

  const getSubcategoryName = (subcategoryId: string) =&amp;gt; {
    const subcategory = subcategories.find(sub =&amp;gt; sub.id === subcategoryId);
    return subcategory ? subcategory.name : "Unknown";
  };

  const handleRowClick = (item: any) =&amp;gt; {
    // Toggle selection on row click
    setSelectedItem(selectedItem === item ? null : item);
  };

  const handleIncrementAmount = async () =&amp;gt; {
    if (selectedItem) {
      // Make an API call to update the amount in the database
      try {
        const res = await fetch(`http://localhost:5000/updateAmount?id=${selectedItem.id}`, {
          method: 'PUT',
          cache: 'no-store',
        });

        if (res.ok) {
          // Update the amount in the local state only if the API call is successful
          const updatedItems = items.map((item) =&amp;gt;
            item.id === selectedItem.id
              ? { ...item, amount: item.amount + 1 }
              : item
          );

          // Update state to trigger a re-render
          setItems(updatedItems);
          setSortedItems(updatedItems);
        } else {
          console.error('Failed to update amount in the database');
        }
      } catch (error) {
        console.error('Error updating amount:', error);
      }
    }
  };

  const handleDecrementAmount = () =&amp;gt; {
    if (selectedItem &amp;amp;&amp;amp; selectedItem.amount &amp;gt; 0) {
      // Update the amount of the selected item by subtracting 1
      const updatedItems = items.map((item) =&amp;gt;
        item.id === selectedItem.id
          ? { ...item, amount: item.amount - 1 }
          : item
      );

      // Update state to trigger a re-render
      setItems(updatedItems);
      setSortedItems(updatedItems);
    }
  };


  return (
    &amp;lt;ResizablePanelGroup
      direction="horizontal"
      className="fit-w-md rounded-lg border"
    &amp;gt;
      &amp;lt;ResizablePanel defaultSize={50}&amp;gt;
        &amp;lt;div className="flex h-full items-center justify-center p-full"&amp;gt;
        &amp;lt;table&amp;gt;
            &amp;lt;thead&amp;gt;
              &amp;lt;tr&amp;gt;
                &amp;lt;th&amp;gt;ID&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;Subcategory&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;Amount&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;Limit&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;TimestampE&amp;lt;/th&amp;gt;
                &amp;lt;th&amp;gt;TimestampR&amp;lt;/th&amp;gt;
              &amp;lt;/tr&amp;gt;
            &amp;lt;/thead&amp;gt;
            &amp;lt;tbody&amp;gt;
              {sortedItems.map((item) =&amp;gt; (
                &amp;lt;tr
                  key={item.id}
                  onClick={() =&amp;gt; handleRowClick(item)} // Handle row click
                  className={selectedItem === item ? "selected-row" : ""}
                &amp;gt;
                  &amp;lt;td&amp;gt;{item.id}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{item.name}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{getSubcategoryName(item.subcategory)}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{item.amount}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{item.limit}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{item.description}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{item.timestampE}&amp;lt;/td&amp;gt;
                  &amp;lt;td&amp;gt;{item.timestampR}&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
              ))}
            &amp;lt;/tbody&amp;gt;
          &amp;lt;/table&amp;gt;

            {selectedItem &amp;amp;&amp;amp; (
              &amp;lt;p&amp;gt;Selected Row: {selectedItem.name}&amp;lt;/p&amp;gt;
            )}

            {selectedSubcategory &amp;amp;&amp;amp; (
              &amp;lt;p&amp;gt;Sorted by Subcategory: {selectedSubcategory.name}&amp;lt;/p&amp;gt;
            )}
        &amp;lt;/div&amp;gt;
      &amp;lt;/ResizablePanel&amp;gt;
      &amp;lt;ResizableHandle /&amp;gt;
      &amp;lt;ResizablePanel defaultSize={50}&amp;gt;
        &amp;lt;ResizablePanelGroup direction="vertical"&amp;gt;
          &amp;lt;ResizablePanel defaultSize={25}&amp;gt;
            &amp;lt;div className="flex-wrap h-full items-center justify-center p-full"&amp;gt;
              {subcategories.map((subcategory) =&amp;gt; (
              &amp;lt;Button variant="custom"
                key={subcategory.id}
                onClick={() =&amp;gt; handleSortBySubcategory(subcategory)}
              &amp;gt;
                {subcategory.name}
              &amp;lt;/Button&amp;gt;
              ))}
              &amp;lt;Button variant="custom" onClick={handleViewAll}&amp;gt;View All&amp;lt;/Button&amp;gt;
            &amp;lt;/div&amp;gt;
          &amp;lt;/ResizablePanel&amp;gt;
          &amp;lt;ResizableHandle /&amp;gt;
          &amp;lt;ResizablePanel defaultSize={75}&amp;gt;
            &amp;lt;div className="flex h-full  justify-center p-full"&amp;gt;
            {selectedItem ? (
              &amp;lt;&amp;gt;
                &amp;lt;div&amp;gt;
                  &amp;lt;p&amp;gt;Selected Row: {selectedItem.name}&amp;lt;/p&amp;gt;
                  &amp;lt;p&amp;gt;Amount: {selectedItem.amount}&amp;lt;/p&amp;gt;
                  {/* Add a button to increment amount */}
                  &amp;lt;Button onClick={handleIncrementAmount}&amp;gt;+&amp;lt;/Button&amp;gt;
                  &amp;lt;Button onClick={handleDecrementAmount}&amp;gt;-&amp;lt;/Button&amp;gt;
                &amp;lt;/div&amp;gt;
              &amp;lt;/&amp;gt;
            ) : null}
            &amp;lt;/div&amp;gt;
          &amp;lt;/ResizablePanel&amp;gt;
        &amp;lt;/ResizablePanelGroup&amp;gt;
      &amp;lt;/ResizablePanel&amp;gt;
    &amp;lt;/ResizablePanelGroup&amp;gt;
  );
};

export default StockPage;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>nextjs</category>
      <category>react</category>
      <category>mysql</category>
    </item>
  </channel>
</rss>
