<?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: Elvis Munene</title>
    <description>The latest articles on DEV Community by Elvis Munene (@elvis_munene_eaa0c75fb775).</description>
    <link>https://dev.to/elvis_munene_eaa0c75fb775</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%2F2081162%2F363480c2-0bc1-4b19-a85f-3f6f5c03be42.png</url>
      <title>DEV Community: Elvis Munene</title>
      <link>https://dev.to/elvis_munene_eaa0c75fb775</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/elvis_munene_eaa0c75fb775"/>
    <language>en</language>
    <item>
      <title>my journey with next,js and django for the past two weeks.</title>
      <dc:creator>Elvis Munene</dc:creator>
      <pubDate>Mon, 16 Sep 2024 19:37:18 +0000</pubDate>
      <link>https://dev.to/elvis_munene_eaa0c75fb775/my-journey-with-nextjs-and-django-for-the-past-two-weeks-nd6</link>
      <guid>https://dev.to/elvis_munene_eaa0c75fb775/my-journey-with-nextjs-and-django-for-the-past-two-weeks-nd6</guid>
      <description>&lt;p&gt;My Journey with Next.js and Django: Building a Finance App and Polling App&lt;br&gt;
Introduction&lt;br&gt;
In this article, I'll walk you through two projects I’ve built using Next.js and Django. The first is a simple finance app built with Next.js, PostgreSQL, and deployed on Vercel. The second is a polling app developed using Django, with models for questions and choices.&lt;/p&gt;

&lt;p&gt;Table of Contents&lt;br&gt;
Next.js Finance App&lt;br&gt;
Introduction&lt;br&gt;
Project Setup&lt;br&gt;
Styling&lt;br&gt;
Routing&lt;br&gt;
Data Fetching&lt;br&gt;
Error Handling&lt;br&gt;
Form Validation&lt;br&gt;
Authentication&lt;br&gt;
Optimization&lt;br&gt;
Deployment on Vercel&lt;br&gt;
Django Polling App&lt;br&gt;
Introduction&lt;br&gt;
Models: Question and Choice&lt;br&gt;
Admin Site&lt;br&gt;
Views and Templates&lt;br&gt;
URL Routing&lt;br&gt;
Voting and Tallying&lt;br&gt;
Error Handling&lt;br&gt;
Deployment&lt;br&gt;
Next.js Finance App&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Introduction
The finance app allows users to log in, create invoices, manage customers, and perform CRUD operations (Create, Read, Update, Delete). We use PostgreSQL as the database, and I followed MySQL logic for data management.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This project was deployed on Vercel, leveraging its seamless integration with Next.js.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Project Setup
To set up a Next.js app, I initialized the project using the following command:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
npx create-next-app@latest finance-app&lt;br&gt;
cd finance-app&lt;br&gt;
npm install&lt;br&gt;
Key Dependencies:&lt;/p&gt;

&lt;p&gt;PostgreSQL (pg)&lt;br&gt;
Authentication (next-auth)&lt;br&gt;
Database Setup:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
npm install pg&lt;br&gt;
I connected to PostgreSQL by creating a db.js file:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
import { Pool } from 'pg';&lt;/p&gt;

&lt;p&gt;const pool = new Pool({&lt;br&gt;
  user: 'yourUser',&lt;br&gt;
  host: 'localhost',&lt;br&gt;
  database: 'finance_db',&lt;br&gt;
  password: 'yourPassword',&lt;br&gt;
  port: 5432,&lt;br&gt;
});&lt;/p&gt;

&lt;p&gt;export default pool;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Styling
For styling, I used CSS Modules and styled-components:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
import styles from './Home.module.css';&lt;/p&gt;

&lt;p&gt;function HomePage() {&lt;br&gt;
  return (&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
      &lt;h1&gt;Welcome to Finance App&lt;/h1&gt;
&lt;br&gt;
    &lt;br&gt;
  );&lt;br&gt;
}&lt;br&gt;


&lt;ol&gt;
&lt;li&gt;Routing
Next.js uses a file-based routing system. For each page, a corresponding .js file is created inside the pages/ directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
/pages/invoice.js&lt;br&gt;
The routing looks like:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
import Link from 'next/link';&lt;/p&gt;

&lt;p&gt;function Invoice() {&lt;br&gt;
  return (&lt;br&gt;
    &lt;/p&gt;
&lt;br&gt;
      &lt;h1&gt;Invoices&lt;/h1&gt;
&lt;br&gt;
      View Customers&lt;br&gt;
    &lt;br&gt;
  );&lt;br&gt;
}

&lt;p&gt;export default Invoice;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data Fetching
Next.js supports Server-Side Rendering (SSR) and Static Generation. For my app, I used getServerSideProps to fetch invoice data:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
export async function getServerSideProps() {&lt;br&gt;
  const res = await fetch('&lt;a href="http://api.yourapp.com/invoices'" rel="noopener noreferrer"&gt;http://api.yourapp.com/invoices'&lt;/a&gt;);&lt;br&gt;
  const invoices = await res.json();&lt;/p&gt;

&lt;p&gt;return {&lt;br&gt;
    props: {&lt;br&gt;
      invoices,&lt;br&gt;
    },&lt;br&gt;
  };&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Error Handling
Error handling was implemented using a combination of try-catch blocks and a custom error page (pages/_error.js):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
try {&lt;br&gt;
  const res = await fetch(...);&lt;br&gt;
  if (!res.ok) throw new Error('Failed to fetch data');&lt;br&gt;
} catch (error) {&lt;br&gt;
  console.error(error);&lt;br&gt;
  return { props: { error: 'Failed to load data' } };&lt;br&gt;
}&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Form Validation
For form validation, I used Formik and Yup:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
npm install formik yup&lt;br&gt;
Sample code:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
import { useFormik } from 'formik';&lt;br&gt;
import * as Yup from 'yup';&lt;/p&gt;

&lt;p&gt;const formik = useFormik({&lt;br&gt;
  initialValues: { name: '' },&lt;br&gt;
  validationSchema: Yup.object({&lt;br&gt;
    name: Yup.string().required('Name is required'),&lt;br&gt;
  }),&lt;br&gt;
  onSubmit: (values) =&amp;gt; {&lt;br&gt;
    console.log(values);&lt;br&gt;
  },&lt;br&gt;
});&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication
NextAuth.js was used for authentication, supporting multiple providers:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
npm install next-auth&lt;br&gt;
Set up authentication in pages/api/auth/[...nextauth].js:&lt;/p&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
import NextAuth from 'next-auth';&lt;br&gt;
import Providers from 'next-auth/providers';&lt;/p&gt;

&lt;p&gt;export default NextAuth({&lt;br&gt;
  providers: [&lt;br&gt;
    Providers.Google({&lt;br&gt;
      clientId: process.env.GOOGLE_ID,&lt;br&gt;
      clientSecret: process.env.GOOGLE_SECRET,&lt;br&gt;
    }),&lt;br&gt;
  ],&lt;br&gt;
});&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Optimization
For performance optimization, I used lazy loading for images and components:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;javascript&lt;br&gt;
Copy code&lt;br&gt;
const LazyComponent = dynamic(() =&amp;gt; import('../components/LazyComponent'));&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deployment on Vercel
Deployment on Vercel was seamless:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
vercel deploy&lt;br&gt;
You can view the app live at: Finance App Link.&lt;/p&gt;

&lt;p&gt;Django Polling App&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Introduction&lt;br&gt;
The polling app is a simple web application where users can vote on polls. There are two models: Question and Choice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Models: Question and Choice&lt;br&gt;
I defined two models in models.py:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
from django.db import models&lt;/p&gt;

&lt;p&gt;class Question(models.Model):&lt;br&gt;
    question_text = models.CharField(max_length=200)&lt;br&gt;
    pub_date = models.DateTimeField('date published')&lt;/p&gt;

&lt;p&gt;class Choice(models.Model):&lt;br&gt;
    question = models.ForeignKey(Question, on_delete=models.CASCADE)&lt;br&gt;
    choice_text = models.CharField(max_length=200)&lt;br&gt;
    votes = models.IntegerField(default=0)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Admin Site
To manage the polls, I registered the models in the Django admin:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
from django.contrib import admin&lt;br&gt;
from .models import Question, Choice&lt;/p&gt;

&lt;p&gt;admin.site.register(Question)&lt;br&gt;
admin.site.register(Choice)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Views and Templates
I created views for listing polls and voting. For example, the view for poll detail:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
from django.shortcuts import render, get_object_or_404&lt;br&gt;
from .models import Question&lt;/p&gt;

&lt;p&gt;def detail(request, question_id):&lt;br&gt;
    question = get_object_or_404(Question, pk=question_id)&lt;br&gt;
    return render(request, 'polls/detail.html', {'question': question})&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;URL Routing
The URL configuration for the polls:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
from django.urls import path&lt;br&gt;
from . import views&lt;/p&gt;

&lt;p&gt;urlpatterns = [&lt;br&gt;
    path('&lt;a&gt;int:question_id&lt;/a&gt;/', views.detail, name='detail'),&lt;br&gt;
]&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Voting and Tallying
The voting view updates the vote tally:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
def vote(request, question_id):&lt;br&gt;
    question = get_object_or_404(Question, pk=question_id)&lt;br&gt;
    selected_choice = question.choice_set.get(pk=request.POST['choice'])&lt;br&gt;
    selected_choice.votes += 1&lt;br&gt;
    selected_choice.save()&lt;br&gt;
    return redirect('polls:results', question_id=question.id)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Error Handling
Django handles errors gracefully with its built-in middleware. I used custom 404 and 500 error pages for better user experience.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;python&lt;br&gt;
Copy code&lt;br&gt;
def custom_404_view(request, exception):&lt;br&gt;
    return render(request, '404.html', status=404)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deployment
I deployed the Django polling app using Heroku. It integrates easily with PostgreSQL and Django’s settings.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;bash&lt;br&gt;
Copy code&lt;br&gt;
heroku create&lt;br&gt;
git push heroku master&lt;br&gt;
The app is live at: Polling App Link.&lt;/p&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Documentation: Finance App (Next.js) &amp; Polling App (Django)</title>
      <dc:creator>Elvis Munene</dc:creator>
      <pubDate>Mon, 16 Sep 2024 13:49:18 +0000</pubDate>
      <link>https://dev.to/elvis_munene_eaa0c75fb775/documentation-finance-app-nextjs-polling-app-django-2m87</link>
      <guid>https://dev.to/elvis_munene_eaa0c75fb775/documentation-finance-app-nextjs-polling-app-django-2m87</guid>
      <description>&lt;p&gt;Project 1: Finance App (Next.js)&lt;br&gt;
&lt;strong&gt;Overview&lt;/strong&gt;&lt;br&gt;
The Finance App built using Next.js allows users to:&lt;/p&gt;

&lt;p&gt;Log in to their accounts.&lt;br&gt;
Create, delete, and edit invoices.&lt;br&gt;
Add customers.&lt;br&gt;
The backend is powered by PostgreSQL, with MySQL logic integrated. The application is successfully deployed on Vercel for seamless hosting and access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;br&gt;
User Authentication&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Implemented using session-based authentication to ensure only authorized users can access the platform.&lt;br&gt;
Invoice Management:&lt;/p&gt;

&lt;p&gt;Users can create, edit, and delete invoices.&lt;br&gt;
Invoices are stored in a PostgreSQL database, ensuring efficient and reliable data management.&lt;br&gt;
Customer Management:&lt;/p&gt;

&lt;p&gt;Users can add and manage customer information, allowing easy association with invoices.&lt;br&gt;
Styling&lt;br&gt;
The app's UI is designed using CSS Modules for component-level styling. This ensures:&lt;/p&gt;

&lt;p&gt;Better maintainability.&lt;br&gt;
Scoping of styles to prevent CSS conflicts.&lt;br&gt;
A responsive design, offering optimal performance across devices.&lt;br&gt;
Optimization&lt;br&gt;
Next.js provides automatic optimization techniques:&lt;/p&gt;

&lt;p&gt;Code splitting: Only loading JavaScript required for the current page.&lt;br&gt;
Image optimization: By serving images in formats like WebP.&lt;br&gt;
Pre-rendering: Statically generating pages where possible for faster load times.&lt;br&gt;
Routing&lt;br&gt;
Next.js's file-based routing was leveraged, allowing:&lt;/p&gt;

&lt;p&gt;Clean and simple URL management.&lt;br&gt;
Dynamic routes to handle features like customer and invoice-specific pages (/customer/[id], /invoice/[id]).&lt;br&gt;
Data Fetching&lt;br&gt;
The app uses both client-side and server-side data fetching techniques:&lt;/p&gt;

&lt;p&gt;Client-side for handling real-time updates and user interactions.&lt;br&gt;
Server-side rendering (SSR) for fetching invoice and customer data, ensuring SEO benefits and faster initial page loads.&lt;br&gt;
Error Handling&lt;br&gt;
To enhance user experience:&lt;/p&gt;

&lt;p&gt;Custom error pages were created using Next.js’s built-in error handling (404.js, 500.js).&lt;br&gt;
Try-catch blocks were used in API requests to ensure any errors during data fetching or form submissions are handled gracefully.&lt;br&gt;
Form Validation&lt;br&gt;
Form validation is handled using React Hook Form along with Yup for schema validation:&lt;/p&gt;

&lt;p&gt;Ensures that users fill out forms correctly before submission.&lt;br&gt;
Provides instant feedback on form errors, improving usability.&lt;br&gt;
Authentication&lt;br&gt;
Authentication was implemented using NextAuth.js:&lt;/p&gt;

&lt;p&gt;Secure login with JWT-based session management.&lt;br&gt;
Users are redirected to the login page if not authenticated, protecting private routes.&lt;br&gt;
Meta Data &amp;amp; SEO&lt;br&gt;
Next.js’s Head component was used for setting up meta tags (title, description) dynamically.&lt;br&gt;
Enhanced SEO by utilizing SSR and metadata for better indexing by search engines.&lt;br&gt;
&lt;strong&gt;Project 2: Polling App (Django)&lt;/strong&gt;&lt;br&gt;
Overview&lt;br&gt;
The Polling App is built using Django and consists of:&lt;/p&gt;

&lt;p&gt;A public site for users to view polls and vote.&lt;br&gt;
An admin site for managing polls (adding, editing, and deleting).&lt;br&gt;
Key Features&lt;br&gt;
Public Polls:&lt;/p&gt;

&lt;p&gt;Users can view ongoing polls and cast votes for their preferred choices.&lt;br&gt;
Admin Management:&lt;/p&gt;

&lt;p&gt;Admins have full control to create new polls, update existing ones, and delete outdated polls.&lt;br&gt;
Models:&lt;/p&gt;

&lt;p&gt;Question Model: Contains the poll question and its publication date.&lt;br&gt;
Choice Model: Holds the text of the poll's choices and a vote tally, linked to a specific question.&lt;br&gt;
Styling&lt;br&gt;
The app utilizes Django’s template system to inject CSS for styling. A minimalist approach ensures:&lt;/p&gt;

&lt;p&gt;A clean and user-friendly interface for both public and admin views.&lt;br&gt;
The use of Bootstrap for responsive design and mobile compatibility.&lt;br&gt;
Optimization&lt;br&gt;
Database indexing on frequently queried fields like publication_date for Questions ensures faster query performance.&lt;br&gt;
Django’s caching framework was used to cache frequently accessed poll data, improving speed and reducing database load.&lt;br&gt;
Routing&lt;br&gt;
Django’s URL routing system was implemented to:&lt;/p&gt;

&lt;p&gt;Define clean and meaningful URLs for polls and admin pages (/polls/, /admin/).&lt;br&gt;
Handle both static and dynamic URL routing, especially for voting on specific polls (/polls/[id]).&lt;br&gt;
Data Fetching&lt;br&gt;
Data fetching in Django is handled server-side:&lt;/p&gt;

&lt;p&gt;Polls and choices are fetched from the database and rendered in the views using Django’s ORM.&lt;br&gt;
Query optimizations like select_related and prefetch_related are used to minimize database hits and fetch related data in fewer queries.&lt;br&gt;
Error Handling&lt;br&gt;
Custom error views (e.g., 404.html) were created for a consistent user experience when users encounter missing pages.&lt;br&gt;
Django’s form validation automatically handles errors such as incorrect submissions in both public and admin views.&lt;br&gt;
Form Validation&lt;br&gt;
In the admin panel, Django’s built-in form validation ensures:&lt;/p&gt;

&lt;p&gt;Required fields are filled.&lt;br&gt;
Correct data types are submitted. For the public poll, vote submission is validated to prevent duplicate or invalid votes.&lt;br&gt;
Authentication&lt;br&gt;
Authentication in the admin panel is managed by Django’s AdminAuth system:&lt;/p&gt;

&lt;p&gt;Only authorized users can log in and manage polls.&lt;br&gt;
Secure password management and admin user creation.&lt;br&gt;
Meta Data &amp;amp; SEO&lt;br&gt;
Meta tags and Open Graph tags were added to the poll pages to enhance SEO and ensure better sharing on social platforms.&lt;br&gt;
The app benefits from Django’s SEO-friendly URL structures for better search engine rankings.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
