<?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: Sara</title>
    <description>The latest articles on DEV Community by Sara (@saradomincroft).</description>
    <link>https://dev.to/saradomincroft</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%2F1227486%2Fc091a88f-b367-4a3d-abd1-e85130b4ced8.jpeg</url>
      <title>DEV Community: Sara</title>
      <link>https://dev.to/saradomincroft</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/saradomincroft"/>
    <language>en</language>
    <item>
      <title>Building a Professional DJ Website</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Tue, 15 Apr 2025 10:32:53 +0000</pubDate>
      <link>https://dev.to/saradomincroft/building-stackpackers-website-dnb-dj-and-production-duo-5dfm</link>
      <guid>https://dev.to/saradomincroft/building-stackpackers-website-dnb-dj-and-production-duo-5dfm</guid>
      <description>&lt;h2&gt;
  
  
  Intro:
&lt;/h2&gt;

&lt;p&gt;As a DJ duo in the world of bass music, having a strong online presence is key to reaching and engaging with fans and for potential bookings. For Stackpackers, I decided to create a website that not only represents our style but also provides a smooth user experience, showcasing our music, shows, and contact details. In this post, I'll walk you through how I built it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://stackpackers.com/" rel="noopener noreferrer"&gt;Live Website&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/saradomincroft/stackpackers-website" rel="noopener noreferrer"&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Framework: Next.js
&lt;/h2&gt;

&lt;p&gt;I chose Next.js for a few reasons — mainly because I wanted to get more hands-on experience with it, but also because of built-in features like server-side rendering (SSR). I’ve read that SSR is great for search engine optimisation (SEO), which made it feel like a good fit for a music project where visibility online matters.&lt;/p&gt;

&lt;p&gt;To be honest, I’m still learning about how SSR and SEO really tie together in practice, but I figured my DJ website would be the perfect space to experiment and explore that.&lt;/p&gt;

&lt;p&gt;One issue I ran into, though, was with the next/image component. For some reason, it completely broke the navigation between sections on my site, the Navbar wasn't registering where the page was. I spent hours debugging it — even had to step away and come back the next day. Eventually, I swapped out Image for regular img tags, and that fixed everything. I'm still not entirely sure why it caused the problem in the first place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Styling: Tailwind CSS (with some regular CSS sprinkled in)
&lt;/h2&gt;

&lt;p&gt;I went with Tailwind CSS for styling because it just makes life easier. It was my first big project using Tailwind, I'm already used to Bootstrap so it wasn't too hard to switch. The utility classes let me build and tweak things super fast without writing a ton of CSS from scratch. It’s also great for making stuff responsive without having to overthink it — perfect for a project like this where I wanted everything to feel clean on mobile and desktop. I still used some classic CSS too. A couple of components needed more specific styles, or just things that were easier to handle in a .module.css file — like layering, custom animations, or fine-tuning certain layouts.&lt;/p&gt;

&lt;h2&gt;
  
  
  SEO &amp;amp; Metadata
&lt;/h2&gt;

&lt;p&gt;As a DJ duo looking to connect with fans, SEO is important. I added Open Graph and JSON-LD structured data to ensure that Stackpackers' website would rank well and display properly on social media platforms like Facebook and TikTok. Additionally, I set up Meta tags and added TikTok/Meta Pixels for tracking user interactions.&lt;/p&gt;

&lt;p&gt;One thing I struggled with in an older version of the site was the favicon not showing up consistently — especially in places like Google search results or browser tabs across different devices. This time, I used realfavicongenerator.net to generate all the proper favicon sizes and meta tags. Super helpful and made sure the icon shows up everywhere it should. Luckily I have experience using photoshop, so I was able to quickly design the favicon, and OG image to match our branding (the OG image was actually taken from a previous mix we did, featuring a stunning shot of Melbourne inner city).&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 Key Features of the Stackpackers Website
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Animated Gradient Background
&lt;/h3&gt;

&lt;p&gt;The animated gradient background that flows smoothly across the page. It really complements the electric yellow colour scheme and gives off this kind of glowing blue-sky energy — a nice match for the chaotic energy in Stackpackers’ music. This animation is achieved using CSS transitions and keyframes.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Dynamic Visual Overlays: Particles + Lightning
&lt;/h3&gt;

&lt;p&gt;To add more visual flair, I implemented two interactive overlays:&lt;/p&gt;

&lt;p&gt;Particle Overlay: Floating particles behind the content create an ethereal effect, keeping things visually engaging as users scroll.&lt;/p&gt;

&lt;p&gt;Lightning Overlay: Inspired by the high-energy, electric feel of drum and bass, this overlay adds flashing lightning effects across the screen.&lt;/p&gt;

&lt;p&gt;Both of these components are built using React and styled with CSS.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Embedded Music Platforms
&lt;/h3&gt;

&lt;p&gt;The website allows users to easily listen to Stackpackers' latest tracks and mixes, by embedding SoundCloud, and Spotify directly into the site. This makes it simple for fans to access the music without leaving the page.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Shows &amp;amp; Music Sections
&lt;/h3&gt;

&lt;p&gt;The Shows section is there to keep fans in the loop with upcoming gigs (or past ones if I’ve been too slow to update it 😂). It’s a pretty simple layout — just event artwork in a clean 4:5 ratio, fading in smoothly as you scroll down. Each image links directly to the ticket page. Down the line, I might add more info directly on the site, or maybe even build something that auto-moves older shows into a past events section.&lt;br&gt;
The music section behaves similarly, however these are 1:1 ratio - to match album cover artwork, and link to either Spotify or Soundcloud.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Contact Form
&lt;/h3&gt;

&lt;p&gt;Right now, I’ve just embedded a Google Form because it was quick and easy to set up. It does the job for now, even though customising the styling (especially the colours) is super limited. I might switch it out in the future for a more flexible, styled form that blends in better with the site’s look.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Interactive Navigation &amp;amp; Smooth Scroll
&lt;/h3&gt;

&lt;p&gt;For navigation, I used smooth scroll to make the user experience feel fluid and natural. The interactive navbar allows users to easily jump between sections of the site without jarring transitions. It’s a small touch, but it adds a professional polish to the user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌐 Hosting &amp;amp; Deployment
&lt;/h2&gt;

&lt;p&gt;The site is hosted on &lt;a href="https://www.hostpapa.com/" rel="noopener noreferrer"&gt;HostPapa&lt;/a&gt;, and I’ve been really happy with their service so far. The customer support team has been awesome — quick responses, and super helpful (even when I ask dumb questions 😂).&lt;/p&gt;

&lt;h2&gt;
  
  
  📱 Performance &amp;amp; Responsiveness - Mobile-First Approach
&lt;/h2&gt;

&lt;p&gt;I took a mobile-first approach to design, ensuring the site looks and runs smoothly on both desktop and mobile. Since most users will be coming through from social media on their phones, it was important to prioritise mobile responsiveness. Tailwind’s responsive classes made it easy to adapt layouts and spacing, and I tested it across different screen sizes to ensure everything stayed sharp and easy to navigate.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Lessons Learned
&lt;/h2&gt;

&lt;p&gt;This project taught me a lot — from working with metadata and favicons (which I had tried to implement before but missed some important details), to diving deeper into what Next.js can do. Debugging the image scroll bug was frustrating but satisfying once I found a workaround. It’s always such a great feeling when you go from thinking you're a terrible coder to realising, "Hey, I’m not that bad!" I also realised how much little visual touches, like particles and smooth scrolling, can really elevate how polished a site feels.&lt;/p&gt;

&lt;p&gt;This is definitely a step up from the last site I built (which you can check out the repo &lt;a href="https://github.com/saradomincroft/stackpackers-website-old" rel="noopener noreferrer"&gt;here&lt;/a&gt;). I did a lot of research into other inspiring sites and realised ours was lacking that fresh, animated vibe. I’m already thinking about improvements — like a more customisable contact form, a proper gallery section instead of just a few images, or even an event archive that updates automatically. But for now, I’m really happy with where it’s at and proud of how it reflects both our music and my skills as a developer. &lt;/p&gt;

&lt;p&gt;If you have any suggestions or feedback, feel free to reach out!&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>tailwindcss</category>
      <category>webdev</category>
      <category>seo</category>
    </item>
    <item>
      <title>DJ Databass</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Tue, 10 Sep 2024 10:23:57 +0000</pubDate>
      <link>https://dev.to/saradomincroft/dj-databass-51d0</link>
      <guid>https://dev.to/saradomincroft/dj-databass-51d0</guid>
      <description>&lt;p&gt;Repo: &lt;a href="https://github.com/saradomincroft/dj-databass" rel="noopener noreferrer"&gt;https://github.com/saradomincroft/dj-databass&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementing User Authentication in a React App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When building a React application, adding user authentication is a crucial step to ensure security and a personalized user experience. In this blog post, we’ll explore how to implement authentication in a React app, covering the essentials of login and signup functionalities, token management, and session handling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Overview&lt;/strong&gt;&lt;br&gt;
The primary goal of user authentication is to manage and verify user identities, allowing only authenticated users to access certain parts of the application. Here’s how we’ll achieve this in a React app:&lt;/p&gt;

&lt;p&gt;Authentication Flow Management&lt;br&gt;
Login and Signup Components&lt;br&gt;
Token Management&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authentication Flow Management
The first step in implementing authentication is to manage the authentication flow within your application. This involves:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;State Management: Use state variables to keep track of whether a user is authenticated. In our case, we use a state variable to check if the user is logged in and conditionally render different routes based on this state.&lt;/p&gt;

&lt;p&gt;Conditional Routing: Based on the authentication status, we redirect users to different pages. For instance, unauthenticated users are directed to the login or signup page, while authenticated users are granted access to restricted areas of the application.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Login and Signup Components
To allow users to access your application, you need to create login and signup functionalities. Here’s what each component does:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Login Component: This component collects user credentials (username and password), sends them to the server for verification, and handles the response. If the credentials are valid, a token is stored, and the user is redirected to the home page. Errors during login are displayed to inform users of any issues.&lt;/p&gt;

&lt;p&gt;Signup Component: The signup component allows new users to create an account. It includes fields for username, password, and an optional admin checkbox. After collecting the necessary information, it sends a request to the server to register the new user. Upon successful registration, the user is automatically logged in and redirected to the home page.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Token Management
Authentication tokens are crucial for managing user sessions and ensuring secure communication between the client and server. Here’s how we handle tokens:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Storing Tokens: When a user logs in or signs up, the server responds with an authentication token. This token is stored in localStorage to keep the user logged in even after refreshing the page.&lt;/p&gt;

&lt;p&gt;Removing Tokens: When a user logs out, the token is removed from localStorage, effectively ending the session and requiring the user to log in again to access restricted pages.&lt;br&gt;
Creating an Intuitive DJ Management Page with React&lt;br&gt;
In today’s music industry, managing DJ profiles efficiently can be crucial for event organizers and music enthusiasts alike. Recently, I embarked on a project to develop a user-friendly page for adding DJs to a system. The result is a dynamic React component that simplifies the process of inputting DJ details, ensuring an intuitive user experience while maintaining robust functionality. Here’s an overview of how I achieved this with my AddDjPage component.&lt;/p&gt;

&lt;p&gt;Overview of the Project&lt;br&gt;
The AddDjPage component is designed to allow users to add new DJs to a database with a range of details, including their name, production status, genres, subgenres, venues, and city. The goal was to create a comprehensive yet straightforward interface for inputting these details while also validating the form to ensure the data’s integrity.&lt;/p&gt;

&lt;p&gt;Key Features&lt;br&gt;
Dynamic Form Handling: The component utilizes React hooks (useState and useEffect) to manage state and side effects effectively. From handling user inputs to managing the submission status, the form dynamically responds to user interactions and data changes.&lt;/p&gt;

&lt;p&gt;Validation and Error Handling: One of the standout features is the real-time validation of DJ names. Using the useEffect hook, the component checks if the entered DJ name already exists in the database, providing immediate feedback to the user. The form also includes error and success messages that disappear after a few seconds, enhancing user experience.&lt;/p&gt;

&lt;p&gt;Genre and Subgenre Management: Adding and managing genres and subgenres is streamlined through the component. Users can add genres and corresponding subgenres, with validation ensuring that each genre has at least one subgenre before form submission. The ability to remove genres and subgenres dynamically makes the form flexible and user-friendly.&lt;/p&gt;

&lt;p&gt;Venue Management: Users can add multiple venues and remove them as needed. This feature is managed similarly to genres, providing a list of added venues with options to remove them individually.&lt;/p&gt;

&lt;p&gt;Form Submission: On form submission, the data is sent to the backend via an axios POST request. The component handles success and error responses gracefully, clearing the form and displaying appropriate messages based on the outcome.&lt;/p&gt;

&lt;p&gt;User Experience Enhancements: The component is styled using Bootstrap and custom CSS, providing a clean and responsive design. The use of icons from react-icons for removing genres and venues adds a touch of interactivity and clarity.&lt;/p&gt;

&lt;p&gt;Technical Implementation&lt;br&gt;
State Management: Managed various state variables for form inputs, validation messages, and submission status.&lt;br&gt;
Effect Hooks: Used useEffect to fetch existing DJs and validate name uniqueness in real-time.&lt;/p&gt;

&lt;p&gt;Dynamic Input Handling: Implemented dynamic addition and removal of genres, subgenres, and venues with corresponding state updates.&lt;br&gt;
Form Submission: Incorporated asynchronous data submission with error handling and feedback mechanisms.&lt;br&gt;
Challenges and Solutions&lt;/p&gt;

&lt;p&gt;Real-Time Validation: Ensuring real-time feedback for the DJ name involved careful handling of state and effect hooks to avoid performance issues.&lt;/p&gt;

&lt;p&gt;Dynamic Inputs: Managing dynamic lists of genres and subgenres required careful state management to prevent unwanted data mutations and ensure data integrity.&lt;br&gt;
Conclusion&lt;/p&gt;

&lt;p&gt;The AddDjPage component exemplifies how React can be leveraged to create a powerful and user-friendly interface for managing DJ profiles. By focusing on real-time validation, dynamic input management, and user experience, the component provides a seamless way for users to add DJs to a database while ensuring data accuracy and integrity. This project has been an exciting journey into enhancing form handling and user interactions in React, and I look forward to applying these techniques to future projects.&lt;/p&gt;

</description>
      <category>react</category>
      <category>flask</category>
      <category>python</category>
      <category>sql</category>
    </item>
    <item>
      <title>DJ Databass</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Thu, 01 Aug 2024 13:10:40 +0000</pubDate>
      <link>https://dev.to/saradomincroft/dj-databass-5962</link>
      <guid>https://dev.to/saradomincroft/dj-databass-5962</guid>
      <description>&lt;p&gt;Coming soon...&lt;/p&gt;

</description>
      <category>flask</category>
      <category>react</category>
      <category>python</category>
      <category>api</category>
    </item>
    <item>
      <title>Python &amp; SQL DJ Database</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Mon, 24 Jun 2024 08:25:41 +0000</pubDate>
      <link>https://dev.to/saradomincroft/python-sql-dj-database-4p99</link>
      <guid>https://dev.to/saradomincroft/python-sql-dj-database-4p99</guid>
      <description>&lt;p&gt;For our phase 3 projects at Academy Xi we were tasked with building a CLI which features many-to-many databases using SQLAlchemy. For my project I decided to keep it relevant to my hobbies and create a DJ 'Databass' which tracks Melbourne DJs. You can add their DJ name, the genres and subgenres of those genres they play, their music production status, and what venues they have played at. In addition to this you can update, delete, search and view all of this info. Here is a link to the GitHub Repo: &lt;a href="https://github.com/saradomincroft/mlb-djs" rel="noopener noreferrer"&gt;https://github.com/saradomincroft/mlb-djs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Models:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zhcxixttx61fy58pdq0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zhcxixttx61fy58pdq0.png" alt="Image description" width="800" height="664"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pcow0t58gh6onblc252.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9pcow0t58gh6onblc252.png" alt="Image description" width="800" height="723"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;DJ Model: This is the main model for the database, each DJ has a primary key id, a name and a boolean to define whether or not the DJ is also a music producer or not. In addition to this, using SQLAlchemy's relationship and association proxy, connecting the genres and their subgenres, and the venues to the DJs.&lt;/p&gt;

&lt;p&gt;Genre Model: This model represents different genres of music. Each genre can have multiple subgenres and can be associated with multiple DJs through the DjGenre association.&lt;/p&gt;

&lt;p&gt;DjGenre Model: The DjGenre model is an association table that links DJs to genres, establishing a many-to-many relationship between them.&lt;/p&gt;

&lt;p&gt;Subgenre Model: The Subgenre model represents subgenres, which are linked to a parent genre and can also be associated with multiple DJs.&lt;/p&gt;

&lt;p&gt;DjSubgenre Model: Similar to DjGenre, DjSubgenre is an association table that links DJs to subgenres.&lt;/p&gt;

&lt;p&gt;Venue Model: The Venue model represents venues where DJs perform. Each venue can have multiple DJs, managed through the DjVenue association.&lt;/p&gt;

&lt;p&gt;DjVenue Model: Finally, DjVenue is the association table that links DJs to venues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Run.py
&lt;/h2&gt;

&lt;p&gt;This is the main file, the main application loop, managed by the start function, provides a user-friendly menu to perform CRUD operations, enabling users to add, update, delete, and view information. I have included some of the more simple functions in this file, the rest of the functions are in a components folder which enabled me to organise the code more efficiently. The clear() function isn't working as planned, I'm still not sure why and have tried troubleshooting this with no success. I also used the fire library so that the menu and start function could be combined into one. I have also made a separate file with some styling using colorama which I have imported throughout the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdby1ixa3s97h71pbfcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmdby1ixa3s97h71pbfcw.png" alt="Image description" width="800" height="815"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clear function imported (not working properly)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftsl5w927huf71qvxibi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fftsl5w927huf71qvxibi.png" alt="Image description" width="800" height="626"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41nx2m814m115xenq6gv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41nx2m814m115xenq6gv.png" alt="Image description" width="800" height="704"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Add DJ function
&lt;/h2&gt;

&lt;p&gt;This function uses SQLAlchemy to add a new DJ to the database, handling user input to ensure data accuracy and prevent duplicates. The process begins by prompting the user for the DJ's name, ensuring the name is not blank and doesn't already exist in the database. The function then captures whether the DJ produces music and maps genres to titles which have multiple ways of writing them to avoid duplicates. Users can add multiple genres and subgenres, ensuring each entry is valid and not already in the database. Additionally, the function allows users to enter venues where the DJ has performed, again checking for existing entries. Throughout, the check_quit function enables users to exit the process, and error and success messages guide the user. Finally, the new DJ's information is committed to the database, reflecting all the gathered details.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprwy3kok1asf4b27mh31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fprwy3kok1asf4b27mh31.png" alt="Image description" width="800" height="778"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xvdgc0g89d9wp262kl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0xvdgc0g89d9wp262kl1.png" alt="Image description" width="800" height="793"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5lglsbvv1wi4e0hsxovi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5lglsbvv1wi4e0hsxovi.png" alt="Image description" width="800" height="782"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>sql</category>
      <category>cli</category>
      <category>database</category>
    </item>
    <item>
      <title>Simple Budget Tracker App Using React &amp; Bootstrap</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Sat, 30 Mar 2024 06:42:29 +0000</pubDate>
      <link>https://dev.to/saradomincroft/simple-budget-tracker-app-using-react-bootstrap-2ce8</link>
      <guid>https://dev.to/saradomincroft/simple-budget-tracker-app-using-react-bootstrap-2ce8</guid>
      <description>&lt;p&gt;My second project for Academy Xi, a simple budget tracker app using React JS &amp;amp; React-Bootstrap for styling. This project is a simple web application which shows the users total income, expenses and balance on the home page. The user is able to navigate to the Income and Expenses tab and add/ delete incomes and expenses. The tracker calculates the total, the incomes and expenses are currently stored on a json file.&lt;/p&gt;

&lt;p&gt;Here is the link to the project: &lt;a href="https://github.com/saradomincroft/budget-tracker" rel="noopener noreferrer"&gt;https://github.com/saradomincroft/budget-tracker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5teo9djlqr1750oswp3o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5teo9djlqr1750oswp3o.png" alt="Image description" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8h6oz2935plv2kmhy38.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg8h6oz2935plv2kmhy38.png" alt="Image description" width="522" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The incomes tab is a bit more simple than the expenses tab, the user is given the option to go to 'add new income' which takes them to a form. The user fills out the title of the expense, description and amount. The app checks to make sure that the fields aren't empty and that a $ value is entered in the amount input. Once the user has satisfied the requirements the user can submit (or go back if they choose). The income is automatically displayed as a card on the IncomesIndex page which also displays the income total at the top (a sum of all the added incomes). The user is able to delete incomes and it will adjust the total accordingly).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xj9gv03q8o3i4bfd4db.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6xj9gv03q8o3i4bfd4db.png" alt="Image description" width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjtqf6nhxvzr05n5i60n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcjtqf6nhxvzr05n5i60n.png" alt="Image description" width="800" height="592"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qk7rcj4ydf4d1wkkt3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qk7rcj4ydf4d1wkkt3b.png" alt="Image description" width="605" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwalr29uutrzzwit6jxlw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwalr29uutrzzwit6jxlw.png" alt="Image description" width="638" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4fo4t32d5iwojdg7j3u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi4fo4t32d5iwojdg7j3u.png" alt="Image description" width="800" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9si90srrqall8t1k2mr9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9si90srrqall8t1k2mr9.png" alt="Image description" width="515" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The expenses side works similarly to the incomes, however there is the option to mark the expenses as paid/ outstanding. The user is able to filter through 'all, paid, and outstanding' expenses, which are displayed on the expenses tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqidbvigimny5apt0gkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvqidbvigimny5apt0gkf.png" alt="Image description" width="800" height="274"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw0djs1z6ogf33awcv7z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdw0djs1z6ogf33awcv7z.png" alt="Image description" width="800" height="331"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd7iflzrzqpkop5jwfpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqd7iflzrzqpkop5jwfpw.png" alt="Image description" width="800" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The calculations are made on a separate JS file and then there is a DifferenceIndex, structured similarly to the Expenses and Incomes index which displays the incomes minus the expenses and is displayed on the home page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojo637r2v866z8nzm1dy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fojo637r2v866z8nzm1dy.png" alt="Image description" width="800" height="352"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdhuix0fq8w317s6d1ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjdhuix0fq8w317s6d1ew.png" alt="Image description" width="785" height="569"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is currently quite simple, I would like to develop this in the future to incorporate a login function, notification messages when an income/ expense has been added, and would also like to do something with the filtered expenses, possibly do another calculation for this so the user is able to see how much they have paid and how much is outstanding totalled up.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>react</category>
      <category>bootstrap</category>
      <category>javascript</category>
      <category>beginners</category>
    </item>
    <item>
      <title>🧪A Pokédex Built with JavaScript</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Fri, 09 Feb 2024 09:40:30 +0000</pubDate>
      <link>https://dev.to/saradomincroft/pokedex-project-using-pokeapi-29ab</link>
      <guid>https://dev.to/saradomincroft/pokedex-project-using-pokeapi-29ab</guid>
      <description>&lt;p&gt;As part of the Software Engineering Transform course at Academy Xi, I built a Pokédex web app as my Phase-1 project. The app fetches data from the PokeAPI and displays the original 151 Pokémon, complete with images, types, and descriptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔗 &lt;a href="https://github.com/saradomincroft/pokedex" rel="noopener noreferrer"&gt;View the project on GitHub&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  🌐 &lt;a href="https://pokedex-mu-bay.vercel.app/" rel="noopener noreferrer"&gt;Have a go!&lt;/a&gt;
&lt;/h3&gt;

&lt;h2&gt;
  
  
  🎥 Getting Started
&lt;/h2&gt;

&lt;p&gt;I followed a great tutorial by Kenny Yip Coding &lt;a href="https://www.youtube.com/watch?v=dVtnFH4m_fE" rel="noopener noreferrer"&gt;(YouTube link)&lt;/a&gt; to help set up the initial structure. From there, I built on it using what I’ve learned in the course—adding functionality like search, filtering, and a favourites system.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠 Tech &amp;amp; Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ⚙️ HTML + CSS + JavaScript
&lt;/h3&gt;

&lt;p&gt;The app is built using vanilla JS. It loads all 151 OG Pokémon at once, with Bulbasaur displayed by default. Clicking on a Pokémon updates the main view with its image, name, type, and a short description.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Search by Name or Number
&lt;/h2&gt;

&lt;p&gt;Users can search for a Pokémon using either its name or Pokédex number. If no match is found, an error message appears and the input clears.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Filter by Type
&lt;/h2&gt;

&lt;p&gt;A dropdown lets users filter Pokémon by their type (e.g., Grass, Fire, Water). &lt;/p&gt;

&lt;h2&gt;
  
  
  ❤️ Favourites (Add/Remove)
&lt;/h2&gt;

&lt;p&gt;Each Pokémon has a heart icon beside its name. Clicking it adds or removes the Pokémon from a favourites list displayed on the page. Favourites are saved using localStorage so they persist between sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  😎 Styling Touches
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Added hover effects to make the UI feel more dynamic&lt;/li&gt;
&lt;li&gt;Applied colour-coded badges based on Pokémon type&lt;/li&gt;
&lt;li&gt;Highlighted the selected Pokémon in both the main list and favourites for better UX&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I learned heaps during this project—especially how to structure an app, interact with APIs, and manage DOM updates. It’s been really rewarding to see the features come together, and I’m excited to keep building on this foundation in future projects.&lt;/p&gt;

&lt;p&gt;Thanks for reading! I’d love any feedback, especially around improving the code or refining features.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>api</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>My Coding Adventure: Balancing a full-time job, evening classes, and a Drum &amp; Bass events and DJing side hustle</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Fri, 09 Feb 2024 06:07:59 +0000</pubDate>
      <link>https://dev.to/saradomincroft/my-coding-adventure-balancing-a-full-time-job-evening-classes-and-a-drum-bass-events-and-djing-side-hustle-4i0</link>
      <guid>https://dev.to/saradomincroft/my-coding-adventure-balancing-a-full-time-job-evening-classes-and-a-drum-bass-events-and-djing-side-hustle-4i0</guid>
      <description>&lt;p&gt;I started my coding adventure in 2020 (although I did have a bit of HTML &amp;amp; CSS experience prior). I had been travelling Australia and Asia for a few years, and decided it was time to start kicking some career goals. &lt;/p&gt;

&lt;p&gt;I enrolled onto a Cert IV in Programming which also allowed me to stay in Australia on a student visa in Melbourne, little did I know that the whole world was about to go to sh*t. After about a month of being enrolled, lockdowns started, and being a student who had invested all my money into coming back to Australia and study, this left me in a pretty difficult situation. I decided that if I wanted to stay and continue my studies, I had to take action, which let to me and my partner put the remaining money we had into a car (a 1990 Holden Commodore who we named Michael). We hit the roads, became essential workers, and went to do farm work. As we had both previously done a lot of farm work on Working Holiday Visas (WHVs), we were well accustomed to this already and already had a bunch of good farm connections. Looking back on it, I'm quite glad this is what we did, although it was hard, we had a lot of fun and managed to avoid the lockdowns.&lt;/p&gt;

&lt;p&gt;Our first stop was Renmark, SA, where we picked oranges. We lived on a free camp in our car and I kept my studies up during this time. It was very difficult as I was working long hours doing very physical work, nothing was open, so I had to charge my laptop in the shopping malls, and work on my projects whilst living in a car. Even with all this happening, I was able to successfully complete my course. It got better as the year went on, we moved from oranges to blueberries in Tabulam, NSW where we rented a room, and establishments were open.&lt;/p&gt;

&lt;p&gt;Once I had completed my Cert IV, I put a pause on my studies temporarily and focused on work. I also run Drum &amp;amp; Bass events and DJ in Melbourne so my time was taken up by all of these things, however I would often work on little projects during my spare time, such as my DJ website.&lt;/p&gt;

&lt;p&gt;Fast forward to November 2023, I decided to continue my Software Engineering studies, and signed up to Academy XI's Software Engineering transform program. I am loving it so far but it is very full on. I'm currently trying to balance my full-time job as an E-Commerce Coordinator, my event business and DJing (which is a lot of work, especially on the social media front), and my course. The first couple of months was quite smooth sailing, I'm already very familiar with a lot of the HTML &amp;amp; CSS basics, so I was able to breeze through that part.&lt;/p&gt;

&lt;p&gt;Now it's getting a bit more intensive, although I already had some JS knowledge from my Cert IV, it barely scratched the surface on what we are learning now. Balancing everything has been tricky, I unfortunately have quite a large-scale event planned for the same weekend as my first JavaScript project is due in 😮‍💨. It has not been an easy week, and I've made the decision to downscale my events temporarily (although I wont stop DJing), until my course is completed later in the year.&lt;/p&gt;

&lt;p&gt;Part of the requirements for each project is to write a blog post, so I thought it would be cool to write a bit of an intro post first, over the next few months I'll be writing posts which talk about the projects I'm doing with Academy XI.&lt;/p&gt;

&lt;p&gt;I think I now understand why everyone talks about how they hate JavaScript so much, it's very overwhelming and I've always found languages like Java and Python a little easier to grasp, however I'm looking forward to improving my skills and getting out of the "Valley of Despair".&lt;/p&gt;

&lt;p&gt;Wish me luck!&lt;br&gt;
&lt;a href="https://github.com/saradomincroft" rel="noopener noreferrer"&gt;Github Profile&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
