<?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: KUNDAN SOLANKI</title>
    <description>The latest articles on DEV Community by KUNDAN SOLANKI (@kundan1334).</description>
    <link>https://dev.to/kundan1334</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1702064%2F612491f1-d1f6-4a63-b443-6ab939d6d450.png</url>
      <title>DEV Community: KUNDAN SOLANKI</title>
      <link>https://dev.to/kundan1334</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kundan1334"/>
    <language>en</language>
    <item>
      <title>GoodFirst : I built my friend a way into open source.</title>
      <dc:creator>KUNDAN SOLANKI</dc:creator>
      <pubDate>Sat, 03 Oct 2026 13:05:36 +0000</pubDate>
      <link>https://dev.to/kundan1334/goodfirst-i-built-my-friend-a-way-into-open-source-1i0h</link>
      <guid>https://dev.to/kundan1334/goodfirst-i-built-my-friend-a-way-into-open-source-1i0h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;My friend Shivin wanted to get into open source this October. He could code. What stopped him was everything around the code. He'd open a real project, see a long README and a hundred open issues, and the questions piled up before he wrote a single line:&lt;/p&gt;

&lt;p&gt;Which of these files actually matter?&lt;br&gt;
How do I even run this?&lt;br&gt;
Which issue is small enough for a first try?&lt;br&gt;
Which programs exist for beginners like me, and when do they open?&lt;/p&gt;

&lt;p&gt;So I built him &lt;strong&gt;GoodFirst&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Paste a GitHub repo and ask a question in your own words ("I know some JavaScript, how do I run this locally?"). A local Gemma model answers from the project's own docs, maps out the files that matter, and picks three good first issues, each with a reason it fits and a place to start. A second page lists open source programs (GSoC, Outreachy, LFX Mentorship and more) with official dates, and shows which ones are open, live or not announced yet.&lt;/p&gt;

&lt;p&gt;Two rules shaped all of it:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It runs on a laptop like Shivin's&lt;/strong&gt;. Windows, 8 GB of RAM, no GPU. No API key, no account, no bill.&lt;br&gt;
&lt;strong&gt;It never pretends&lt;/strong&gt;. A small model gets things wrong. Anything GoodFirst can't verify against GitHub gets crossed out, right there on the screen.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/K6L3NiIvW6Y" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Paste a repo and an optional question.&lt;/li&gt;
&lt;li&gt;A live timeline shows each step as it happens: reading the repo on GitHub, Gemma reading the docs, choosing issues, checking every claim.&lt;/li&gt;
&lt;li&gt;You get the answer, a short summary, setup steps, the important files and three issues.&lt;/li&gt;
&lt;li&gt;Next to it sits the &lt;strong&gt;evidence panel&lt;/strong&gt;: every claim the model made, where it came from, and whether it was verified, flagged or removed.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/KUNDAN1334" rel="noopener noreferrer"&gt;
        KUNDAN1334
      &lt;/a&gt; / &lt;a href="https://github.com/KUNDAN1334/GoodFirst" rel="noopener noreferrer"&gt;
        GoodFirst
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;a rel="noopener noreferrer" href="https://private-user-images.githubusercontent.com/116949800/664644831-f07b9a75-2c85-479a-974d-00803da5fccc.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3OTE1MTg5MDYsIm5iZiI6MTc5MTUxODYwNiwicGF0aCI6Ii8xMTY5NDk4MDAvNjY0NjQ0ODMxLWYwN2I5YTc1LTJjODUtNDc5YS05NzRkLTAwODAzZGE1ZmNjYy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYxMDA5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MTAwOVQwNDAzMjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT03MjI1NWVkNzgxNzA5YWVkODYxNzc0M2YyZjE2NWVlY2MwNjcyZjdlYjhhNjU4Zjk5NDBkMzc2ZDQ5NzdkNDU5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.L6wKZyUFsnZnYGRD6TmhozwRq2wwSl2D54Xw1Jf77aM"&gt;&lt;img width="1478" height="861" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fprivate-user-images.githubusercontent.com%2F116949800%2F664644831-f07b9a75-2c85-479a-974d-00803da5fccc.png%3Fjwt%3DeyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3OTE1MTg5MDYsIm5iZiI6MTc5MTUxODYwNiwicGF0aCI6Ii8xMTY5NDk4MDAvNjY0NjQ0ODMxLWYwN2I5YTc1LTJjODUtNDc5YS05NzRkLTAwODAzZGE1ZmNjYy5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjYxMDA5JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI2MTAwOVQwNDAzMjZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT03MjI1NWVkNzgxNzA5YWVkODYxNzc0M2YyZjE2NWVlY2MwNjcyZjdlYjhhNjU4Zjk5NDBkMzc2ZDQ5NzdkNDU5JlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZyZXNwb25zZS1jb250ZW50LXR5cGU9aW1hZ2UlMkZwbmcifQ.L6wKZyUFsnZnYGRD6TmhozwRq2wwSl2D54Xw1Jf77aM" class="js-gh-image-fallback"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;GoodFirst&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Your first green square starts here.&lt;/strong&gt; GoodFirst helps beginners make their first open source
contribution. Paste a GitHub repo and (optionally) a question. GoodFirst answers the question from
the repo's own docs, maps out the files that matter, picks three good first issues, and shows the
evidence for every claim it makes. Anything it can't back up with what GitHub returned gets
crossed out. When your pull request's checks go red, it reads the failed log and explains what
broke.&lt;/p&gt;
&lt;p&gt;The AI is &lt;strong&gt;Gemma, an open-weight model, running on your own computer through Ollama&lt;/strong&gt;. There
are no API keys and no hosted LLM calls, and GitHub is only ever read, never written to.&lt;/p&gt;
&lt;p&gt;Built for the DEV Hacktoberfest 2026 Weekend Challenge, &lt;strong&gt;"Build for a Friend"&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Why I built this: Shivin&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;My friend Shivin wanted to make his first open source contribution. He had picked a project
&lt;a href="https://github.com/AOSSIE-Org/DebateAI" rel="noopener noreferrer"&gt;AOSSIE-Org/DebateAI&lt;/a&gt;…&lt;/p&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/KUNDAN1334/GoodFirst" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Stack:&lt;/strong&gt; Gemma 3 4B on Ollama · LangGraph · FastAPI with streaming · Next.js + Tailwind · GitHub REST API (read-only, never writes)&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The model doesn't drive
&lt;/h3&gt;

&lt;p&gt;I didn't build an agent that decides what to fetch. Code fetches the README, the contributing guide, the file tree and the beginner-labelled issues, cleans them up and trims them to fit an 8K context. Gemma gets one narrow job per step, in a fixed graph:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;fetch → explain → pick_issues → honesty_check&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Every answer must match a JSON schema, passed straight to Ollama's structured outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;SystemMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;system&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nc"&gt;HumanMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json_schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Ollama forces exactly these keys
&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Broken JSON gets one retry, then an honest "couldn't get a usable answer." No made-up fallback. It sounds limiting, but with a 4B model on a CPU, this is what made the output trustworthy enough to hand to a friend.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The honesty layer
&lt;/h3&gt;

&lt;p&gt;After Gemma answers, plain Python checks every claim it can against what GitHub actually returned:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gemma says&lt;/th&gt;
&lt;th&gt;Checked against&lt;/th&gt;
&lt;th&gt;If it fails&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Look at this file"&lt;/td&gt;
&lt;td&gt;The repo's file tree&lt;/td&gt;
&lt;td&gt;Removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Run this command"&lt;/td&gt;
&lt;td&gt;The README and contributing guide&lt;/td&gt;
&lt;td&gt;Flagged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Try issue #123"&lt;/td&gt;
&lt;td&gt;The fetched issue list&lt;/td&gt;
&lt;td&gt;Removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Here's your answer"&lt;/td&gt;
&lt;td&gt;Same file and command checks&lt;/td&gt;
&lt;td&gt;Docs don't cover it? A question for the maintainers instead&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Issue titles, links and labels always come from GitHub, never from the model. Each invented file or issue costs 10% confidence. Below 60%, GoodFirst stops sounding sure and writes a polite question you can paste to the maintainers instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. What a small model taught me
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Asking for "JSON" isn't enough.&lt;/strong&gt; Gemma returned valid JSON with keys missing. A real schema fixed it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Pick three" sometimes got one.&lt;/strong&gt; &lt;code&gt;minItems: 3&lt;/code&gt; in the schema fixed that too.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hinglish took three tries.&lt;/strong&gt; I added an English/Hinglish toggle because that's how a lot of us talk. Gemma ignored it, then copied my example word for word. A neutral example plus a reminder at the very end of the prompt finally worked, and GoodFirst warns you when the answer still comes back in English.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Being helpful backfired.&lt;/strong&gt; When Gemma gave fewer than three valid picks, my code topped up the list from its own ranking, and once that added a bad issue. Now it only tops up with issues that score well. Fewer picks beat a bad suggestion.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Is it fast?
&lt;/h3&gt;

&lt;p&gt;No. On my 8 GB laptop, with the model already loaded, explaining a repo takes about 75–85 seconds and picking issues about 30–37. That's the trade: two minutes of waiting in exchange for free, private and offline. The live timeline helps, because you can see exactly what it's doing while you wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  The hand-over
&lt;/h2&gt;

&lt;p&gt;Shivin used it and opened his first pull request.&lt;/p&gt;

&lt;p&gt;Then the checks went red. The CI log was about 2,500 lines long, and somewhere in there was the one line that mattered. He had no idea which one. That's a brutal moment for a beginner: the hardest part is done, the PR is finally open, and a wall of red text says you broke something.&lt;/p&gt;

&lt;p&gt;I'd built GoodFirst to get him &lt;em&gt;to&lt;/em&gt; his first PR, and hadn't thought about what comes right after. His very first real use found the gap. So I added &lt;strong&gt;CI help&lt;/strong&gt;: paste the pull request, and GoodFirst pulls the failed checks and their logs, cuts the log down to the part around the error, and explains in plain words what failed, why, and how to fix it.&lt;/p&gt;

&lt;p&gt;The same rules apply. Every log line it quotes must exist in the real log, or it's removed. Every file it names must exist. And for the question every beginner asks, &lt;em&gt;"was it my change?"&lt;/em&gt;, GoodFirst doesn't just trust the model. It checks in code whether the error mentions a file the PR changed.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4xbqrrbg0kp93frpcd42.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4xbqrrbg0kp93frpcd42.png" alt="GoodFirst logo" width="617" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's free.&lt;/strong&gt; A beginner shouldn't need a credit card or an API key to get help reading a README.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It runs on what he already has.&lt;/strong&gt; 8 GB of RAM, no GPU, and it works offline once a repo is cached.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's private.&lt;/strong&gt; The "dumb" questions beginners are scared to ask in public never leave the laptop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I control the whole pipeline.&lt;/strong&gt; I can pin Gemma to a schema, swap 4B for 1B with one setting, and wrap it in checks I can read and change. With a closed API you work around the model. Here I could build around it.
A frontier model would write nicer paragraphs. It would also cost money, need an account, send everything to a server, and sound just as confident when it's wrong. For a first-timer, a small model that proves its claims beats a big one that doesn't.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;p&gt;Best Use of Gemma.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Coca-Cola Animated Page</title>
      <dc:creator>KUNDAN SOLANKI</dc:creator>
      <pubDate>Mon, 17 Feb 2025 14:25:26 +0000</pubDate>
      <link>https://dev.to/kundan1334/coca-cola-animated-page-2okn</link>
      <guid>https://dev.to/kundan1334/coca-cola-animated-page-2okn</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/challenges/frontend-2025-02-12"&gt;Frontend Challenge - February Edition, CSS Art: February&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inspiration
&lt;/h2&gt;

&lt;p&gt;For this challenge, I wanted to explore the beauty of pure CSS art and push my creativity. Inspired by the elegance of minimalism and the versatility of CSS, I created this artwork to showcase how simple shapes and colors can bring an idea to life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;You can view my CSS Art live here: &lt;a href="https://665f638cf1ccec2f53672412--elaborate-fenglisu-ec5400.netlify.app/" rel="noopener noreferrer"&gt;https://665f638cf1ccec2f53672412--elaborate-fenglisu-ec5400.netlify.app/&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Here’s a preview of the artwork:&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%2Fniw7y75ob6jakplpo5js.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%2Fniw7y75ob6jakplpo5js.png" alt=" " width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Code: &lt;a href="https://github.com/KUNDAN1334/Practice_Projects/tree/main/Landing_Page" rel="noopener noreferrer"&gt;https://github.com/KUNDAN1334/Practice_Projects/tree/main/Landing_Page&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;p&gt;Working on this CSS Art challenge was both fun and insightful. I experimented with different CSS properties like clip-path, box-shadow, gradients, and animations to achieve the desired visual effect. Some key takeaways from this project:&lt;/p&gt;

&lt;p&gt;Learned how to create complex shapes using clip-path and border-radius.&lt;br&gt;
Explored the use of CSS gradients to add depth and dimension.&lt;br&gt;
Enhanced my understanding of CSS animations to make the artwork dynamic.&lt;br&gt;
I am particularly proud of how everything came together smoothly, and I hope to explore more intricate designs in future challenges&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;In upcoming projects, I plan to:&lt;/p&gt;

&lt;p&gt;Try more interactive CSS Art using hover effects and animations.&lt;br&gt;
Explore SVGs combined with CSS for even more detailed artworks.&lt;br&gt;
Participate in future frontend challenges to refine my CSS skills further.&lt;br&gt;
If you liked my work, feel free to leave feedback and connect with me! 🚀&lt;/p&gt;

</description>
      <category>frontendchallenge</category>
      <category>devchallenge</category>
      <category>css</category>
      <category>html</category>
    </item>
    <item>
      <title>pinata-whiteBoard</title>
      <dc:creator>KUNDAN SOLANKI</dc:creator>
      <pubDate>Sat, 12 Oct 2024 18:41:31 +0000</pubDate>
      <link>https://dev.to/kundan1334/pinata-whiteboard-1h77</link>
      <guid>https://dev.to/kundan1334/pinata-whiteboard-1h77</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pinata"&gt;The Pinata Challenge &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built a collaborative whiteboard application called "Pinata Whiteboard" using React and Pinata IPFS services. This application allows users to draw, upload images, save their whiteboards to IPFS, and even mint their creations as NFTs&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&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%2Fo8dpgt0bjw299atm9z3i.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%2Fo8dpgt0bjw299atm9z3i.png" alt=" " width="800" height="366"&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%2Fva82mh714ovihk264vcp.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%2Fva82mh714ovihk264vcp.png" alt=" " width="799" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Code
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/KUNDAN1334/pinata-whiteboard" rel="noopener noreferrer"&gt;https://github.com/KUNDAN1334/pinata-whiteboard&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More Details
&lt;/h2&gt;

&lt;p&gt;Here are clear examples of how I used Pinata in my project:&lt;/p&gt;

&lt;p&gt;1.Image Upload: When a user uploads an image to the whiteboard, it's stored on IPFS using Pinata's pinning service.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleImageUpload = async (file) =&amp;gt; {
  const cid = await uploadFile(file);
  const url = getFileUrl(cid);
  canvasRef.current.addImage(url, 0, 0, width, height);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Saving Whiteboards: Users can save their whiteboards to IPFS, storing the entire whiteboard state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleSave = async () =&amp;gt; {
  const whiteboardData = canvasRef.current.getWhiteboardData();
  const cid = await saveWhiteboard(whiteboardData);
  alert(`Whiteboard saved! CID: ${cid}`);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Loading Whiteboards: Users can load previously saved whiteboards from IPFS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleLoad = async (cid) =&amp;gt; {
  const whiteboardData = await loadWhiteboard(cid);
  canvasRef.current.loadWhiteboardData(whiteboardData);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Listing Saved Whiteboards: The application fetches and displays a list of saved whiteboards using Pinata's Pin List API.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const listWhiteboards = async () =&amp;gt; {
  const response = await axios.get(
    'https://api.pinata.cloud/data/pinList?status=pinned',
    {
      headers: {
        pinata_api_key: PINATA_API_KEY,
        pinata_secret_api_key: PINATA_SECRET_API_KEY,
      },
    }
  );
  return response.data.rows.filter(pin =&amp;gt; pin.metadata.name === 'Whiteboard');
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5.NFT Minting: Users can mint their whiteboards as NFTs, storing both the image and metadata on IPFS using Pinata.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleMint = async (e) =&amp;gt; {
  e.preventDefault();
  const imageBlob = await getWhiteboardImage();
  const imageCID = await uploadFile(new File([imageBlob], 'whiteboard.png'));
  const metadata = {
    name,
    description,
    image: `ipfs://${imageCID}`,
  };
  const metadataCID = await mintNFTMetadata(metadata);
  alert(`NFT minted successfully! Metadata CID: ${metadataCID}`);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>devchallenge</category>
      <category>pinatachallenge</category>
      <category>webdev</category>
      <category>api</category>
    </item>
  </channel>
</rss>
