<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://qufeiz.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://qufeiz.github.io/" rel="alternate" type="text/html" /><updated>2024-12-11T18:17:52+00:00</updated><id>https://qufeiz.github.io/feed.xml</id><title type="html">Qufeiii’s Homepage</title><subtitle>Hi</subtitle><author><name>Qufeiii</name><email></email></author><entry><title type="html">Mailing Kiosk Demo</title><link href="https://qufeiz.github.io/posts/2024/09/block-post-5/" rel="alternate" type="text/html" title="Mailing Kiosk Demo" /><published>2024-09-24T00:00:00+00:00</published><updated>2024-09-24T00:00:00+00:00</updated><id>https://qufeiz.github.io/posts/2024/09/mailing-kiosk-post</id><content type="html" xml:base="https://qufeiz.github.io/posts/2024/09/block-post-5/"><![CDATA[<h1 id="building-an-interactive-package-mailing-kiosk-prototype">Building an Interactive Package Mailing Kiosk Prototype</h1>

<p>Kiosks are everywhere, from airports to post offices, making daily tasks quick and easy. As a fun project, I decided to create a <strong>self-service kiosk prototype</strong> for <strong>mailing packages</strong>. This mini-project gave me the opportunity to sharpen my web development skills, focusing on <strong>user experience (UX)</strong> and building a fluid, interactive interface.</p>

<div style="text-align: center;">
  <img src="/images/blog/airport.png" alt="Kiosk Design" style="width: 20%; max-width: 800px;" />
</div>

<p>In this post, I’ll walk through the process of creating the kiosk, the challenges I faced, and the design choices that shaped the final product.</p>

<hr />

<h2 id="project-overview">Project Overview</h2>

<p>The goal of the kiosk prototype is to simulate the process of <strong>mailing a package</strong>. It guides users through these key steps:</p>
<ol>
  <li>Selecting a service (Package or Letter).</li>
  <li>Weighing the package.</li>
  <li>Choosing a mailing option (Overnight, 2-Day, or Ground).</li>
  <li>Entering the recipient’s shipping address.</li>
  <li>Reviewing all the information.</li>
  <li>Simulating the payment process—complete with a fun twist at the end.</li>
</ol>

<p>The project is built using <strong>HTML</strong>, <strong>CSS</strong>, and <strong>JavaScript</strong>, with a focus on <strong>user flow</strong>, <strong>form validation</strong>, and <strong>interactivity</strong>.</p>

<hr />

<h2 id="technologies-used">Technologies Used</h2>

<ul>
  <li><strong>HTML5</strong>: For structuring the layout of the kiosk interface.</li>
  <li><strong>CSS3</strong>: For styling the UI, adding visual cues, and creating a smooth user experience.</li>
  <li><strong>JavaScript (ES6)</strong>: For controlling the flow between screens, validating user inputs, and simulating the payment process.</li>
</ul>

<hr />

<h2 id="step-by-step-walkthrough">Step-by-Step Walkthrough</h2>

<h3 id="1-service-selection-screen">1. Service Selection Screen</h3>

<div style="text-align: center;">
  <img src="/images/blog/pageone.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<p>The first screen allows users to select whether they are mailing a package or a letter. The user’s choice is validated before moving to the next screen.</p>

<p>Here’s the <strong>HTML</strong> for the service selection screen:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Service Selection Screen --&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"screen1"</span> <span class="na">class=</span><span class="s">"screen"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"progress-bar"</span><span class="nt">&gt;</span>Step 1 of 6<span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;h2&gt;</span>Select a Service<span class="nt">&lt;/h2&gt;</span>
  <span class="nt">&lt;form&gt;</span>
    <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"package"</span><span class="nt">&gt;</span>Package<span class="nt">&lt;/label&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"radio"</span> <span class="na">id=</span><span class="s">"package"</span> <span class="na">name=</span><span class="s">"service"</span> <span class="na">value=</span><span class="s">"package"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"letter"</span><span class="nt">&gt;</span>Letter<span class="nt">&lt;/label&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"radio"</span> <span class="na">id=</span><span class="s">"letter"</span> <span class="na">name=</span><span class="s">"service"</span> <span class="na">value=</span><span class="s">"letter"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">id=</span><span class="s">"confirmService"</span><span class="nt">&gt;</span>Confirm<span class="nt">&lt;/button&gt;</span>
  <span class="nt">&lt;/form&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<h3 id="2-weigh-package-and-visual-cues">2. Weigh Package and Visual Cues</h3>
<p>The weigh your package screen includes an interactive visual cue in the form of a CSS right-pointing arrow, helping users place their package in the basket.</p>

<div style="text-align: center;">
  <img src="/images/blog/pagetwo.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Weigh Your Package Screen --&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"screen2"</span> <span class="na">class=</span><span class="s">"screen"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"progress-bar"</span><span class="nt">&gt;</span>Step 2 of 6<span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;h2&gt;</span>Place Your Package<span class="nt">&lt;/h2&gt;</span>
  <span class="nt">&lt;p&gt;</span>Total: 3.00 kg<span class="nt">&lt;/p&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"arrow-container"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;span&gt;</span>Place your package in the basket<span class="nt">&lt;/span&gt;</span>
    <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"right-arrow"</span><span class="nt">&gt;&lt;/div&gt;</span> <span class="c">&lt;!-- Right arrow using CSS --&gt;</span>
  <span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">id=</span><span class="s">"confirmPackage"</span><span class="nt">&gt;</span>Confirm<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>Here’s the CSS for the right arrow:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/* Right Arrow Styling */</span>
<span class="nc">.right-arrow</span> <span class="p">{</span>
  <span class="nl">width</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="m">0</span><span class="p">;</span>
  <span class="nl">border-top</span><span class="p">:</span> <span class="m">20px</span> <span class="nb">solid</span> <span class="nb">transparent</span><span class="p">;</span>
  <span class="nl">border-bottom</span><span class="p">:</span> <span class="m">20px</span> <span class="nb">solid</span> <span class="nb">transparent</span><span class="p">;</span>
  <span class="nl">border-left</span><span class="p">:</span> <span class="m">30px</span> <span class="nb">solid</span> <span class="m">#4CAF50</span><span class="p">;</span> <span class="c">/* Green Arrow */</span>
  <span class="nl">margin-left</span><span class="p">:</span> <span class="m">10px</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="3-entering-the-shipping-address">3. Entering the Shipping Address</h3>

<div style="text-align: center;">
  <img src="/images/blog/page3.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<p>Once the user selects the mailing option and places their package, they proceed to the address input screen, where they must enter the recipient’s address and zip code. Proper form validation ensures the inputs are correct.</p>

<div style="text-align: center;">
  <img src="/images/blog/page4.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Enter Address Screen --&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"screen4"</span> <span class="na">class=</span><span class="s">"screen"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"progress-bar"</span><span class="nt">&gt;</span>Step 4 of 6<span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;h2&gt;</span>Enter Address<span class="nt">&lt;/h2&gt;</span>
  <span class="nt">&lt;form&gt;</span>
    <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"address"</span><span class="nt">&gt;</span>Address:<span class="nt">&lt;/label&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"address"</span> <span class="na">placeholder=</span><span class="s">"100 Main St"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"zip"</span><span class="nt">&gt;</span>Zip Code:<span class="nt">&lt;/label&gt;</span>
    <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"text"</span> <span class="na">id=</span><span class="s">"zip"</span> <span class="na">placeholder=</span><span class="s">"15213"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">id=</span><span class="s">"confirmAddress"</span><span class="nt">&gt;</span>Confirm<span class="nt">&lt;/button&gt;</span>
  <span class="nt">&lt;/form&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>JavaScript Validation ensures that the address and zip code fields are filled correctly before allowing the user to proceed.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Address Validation</span>
<span class="nx">confirmAddressBtn</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">address</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">address</span><span class="dl">'</span><span class="p">).</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
  <span class="kd">const</span> <span class="nx">zip</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">zip</span><span class="dl">'</span><span class="p">).</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
  
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">address</span> <span class="o">||</span> <span class="o">!</span><span class="nx">zip</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">alert</span><span class="p">(</span><span class="dl">"</span><span class="s2">Please enter both address and zip code.</span><span class="dl">"</span><span class="p">);</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="sr">/^</span><span class="se">\d{5}</span><span class="sr">$/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">zip</span><span class="p">))</span> <span class="p">{</span>
    <span class="nx">alert</span><span class="p">(</span><span class="dl">"</span><span class="s2">Please enter a valid 5-digit zip code.</span><span class="dl">"</span><span class="p">);</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="c1">// Proceed to the next screen after validation</span>
  <span class="nx">showScreen</span><span class="p">(</span><span class="nx">screen5</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>

<h3 id="4-review-screen">4. Review Screen</h3>
<div style="text-align: center;">
  <img src="/images/blog/page5.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>
<p>Before making a payment, the user reviews their selections, including the service type, mailing option, and address.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- Review Information Screen --&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"screen5"</span> <span class="na">class=</span><span class="s">"screen"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"progress-bar"</span><span class="nt">&gt;</span>Step 5 of 6<span class="nt">&lt;/div&gt;</span>
  <span class="nt">&lt;h2&gt;</span>Review Your Information<span class="nt">&lt;/h2&gt;</span>
  <span class="nt">&lt;p&gt;&lt;strong&gt;</span>Service:<span class="nt">&lt;/strong&gt;</span> <span class="nt">&lt;span</span> <span class="na">id=</span><span class="s">"reviewService"</span><span class="nt">&gt;&lt;/span&gt;&lt;/p&gt;</span>
  <span class="nt">&lt;p&gt;&lt;strong&gt;</span>Mailing Option:<span class="nt">&lt;/strong&gt;</span> <span class="nt">&lt;span</span> <span class="na">id=</span><span class="s">"reviewMailing"</span><span class="nt">&gt;&lt;/span&gt;&lt;/p&gt;</span>
  <span class="nt">&lt;p&gt;&lt;strong&gt;</span>Address:<span class="nt">&lt;/strong&gt;</span> <span class="nt">&lt;span</span> <span class="na">id=</span><span class="s">"reviewAddress"</span><span class="nt">&gt;&lt;/span&gt;&lt;/p&gt;</span>
  <span class="nt">&lt;p&gt;&lt;strong&gt;</span>Zip Code:<span class="nt">&lt;/strong&gt;</span> <span class="nt">&lt;span</span> <span class="na">id=</span><span class="s">"reviewZip"</span><span class="nt">&gt;&lt;/span&gt;&lt;/p&gt;</span>
  <span class="nt">&lt;button</span> <span class="na">type=</span><span class="s">"button"</span> <span class="na">id=</span><span class="s">"confirmReview"</span><span class="nt">&gt;</span>Confirm and Proceed to Payment<span class="nt">&lt;/button&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<h3 id="5-simulating-the-payment-process-with-a-twist">5. Simulating the Payment Process (with a Twist!)</h3>
<div style="text-align: center;">
  <img src="/images/blog/page6.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<p>Once the payment is confirmed, the user is taken to a loading screen that simulates payment processing. After a 3-second delay, they are greeted with a fun “insufficient funds” message.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Simulating Payment Process with a Twist</span>
<span class="nx">confirmPaymentBtn</span><span class="p">.</span><span class="nx">addEventListener</span><span class="p">(</span><span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">cardNumber</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">card</span><span class="dl">'</span><span class="p">).</span><span class="nx">value</span><span class="p">.</span><span class="nx">trim</span><span class="p">();</span>
  
  <span class="c1">// Validate the card number (basic check)</span>
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="sr">/^</span><span class="se">\d{12,19}</span><span class="sr">$/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">cardNumber</span><span class="p">))</span> <span class="p">{</span>
    <span class="nx">alert</span><span class="p">(</span><span class="dl">"</span><span class="s2">Please enter a valid credit card number.</span><span class="dl">"</span><span class="p">);</span>
    <span class="k">return</span><span class="p">;</span>
  <span class="p">}</span>

  <span class="c1">// Show the loading screen</span>
  <span class="nx">showScreen</span><span class="p">(</span><span class="nx">screen7</span><span class="p">);</span>

  <span class="c1">// After 3 seconds, show the insufficient funds message</span>
  <span class="nx">setTimeout</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">showScreen</span><span class="p">(</span><span class="nx">screen8</span><span class="p">);</span>  <span class="c1">// Move to the insufficient funds screen</span>
  <span class="p">},</span> <span class="mi">3000</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>

<p>The loading screen includes a CSS spinner:</p>
<div style="text-align: center;">
  <img src="/images/blog/page7.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">/* Loading Spinner */</span>
<span class="nc">.loader</span> <span class="p">{</span>
  <span class="nl">border</span><span class="p">:</span> <span class="m">16px</span> <span class="nb">solid</span> <span class="m">#f3f3f3</span><span class="p">;</span>
  <span class="nl">border-top</span><span class="p">:</span> <span class="m">16px</span> <span class="nb">solid</span> <span class="m">#4CAF50</span><span class="p">;</span>
  <span class="nl">border-radius</span><span class="p">:</span> <span class="m">50%</span><span class="p">;</span>
  <span class="nl">width</span><span class="p">:</span> <span class="m">60px</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span> <span class="m">60px</span><span class="p">;</span>
  <span class="nl">animation</span><span class="p">:</span> <span class="n">spin</span> <span class="m">2s</span> <span class="n">linear</span> <span class="n">infinite</span><span class="p">;</span>
<span class="p">}</span>

<span class="k">@keyframes</span> <span class="n">spin</span> <span class="p">{</span>
  <span class="err">0</span><span class="o">%</span> <span class="p">{</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">rotate</span><span class="p">(</span><span class="m">0deg</span><span class="p">);</span> <span class="p">}</span>
  <span class="err">100</span><span class="o">%</span> <span class="p">{</span> <span class="nl">transform</span><span class="p">:</span> <span class="n">rotate</span><span class="p">(</span><span class="m">360deg</span><span class="p">);</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div style="text-align: center;">
  <img src="/images/blog/page8.png" alt="Kiosk Design" style="width: 100%; max-width: 800px;" />
</div>

<h3 id="challenges-and-solutions">Challenges and Solutions</h3>
<p>Managing State Across Multiple Screens
Each screen in the kiosk involves multiple user inputs that must persist across steps. I used JavaScript to store the user’s data in variables and passed it along to the review and payment screens.</p>

<h3 id="form-validation">Form Validation</h3>
<p>Proper form validation was key to ensuring a smooth user experience. I added real-time validation to fields like the zip code and card number to avoid common input errors.</p>

<h3 id="conclusion">Conclusion</h3>
<p>This mini project was a fun way to explore building a self-service kiosk. It pushed me to think about the user experience, especially the need for clear instructions, form validation, and playful touches like the humorous payment twist. By working through this project, I gained a deeper understanding of managing state between multiple screens and handling user inputs effectively.</p>

<p>If you’d like to try it yourself or check out the code, visit the links below!</p>

<p><a href="https://github.com/qufeiz/Mailing-Kiosk-UI">Mailing Kiosk UI</a></p>]]></content><author><name>Qufeiii</name></author><category term="HTML" /><category term="CSS" /><category term="JavaScript" /><category term="UX" /><summary type="html"><![CDATA[A deep dive into the process of building a package mailing kiosk with HTML, CSS, and JavaScript, featuring a fun twist on the payment process!]]></summary></entry></feed>