← Astra Home   /   A–Z Academy

A–Z Professional Practice · Batch 7

6 complete guided project lessons · explanation, setup, code, step-by-step practice, output, troubleshooting and self-check.

Existing lessons and design remain unchanged. These are new optional lessons.

Contents

  1. HTML, CSS & JavaScript: Responsive interactive portfolio
  2. Flutter & Dart: Multi-screen task app
  3. Google Apps Script: Approval tracker automation
  4. GitHub Actions: Static site quality gate
  5. Digital Marketing & SEO: Campaign landing page measurement
  6. Online Earning & Client Delivery: Freelance website project handover
LESSON 01 · Intermediate

HTML, CSS & JavaScript — Responsive interactive portfolio

Objective: Create a portfolio with a responsive grid and a working project filter.

Theory: HTML sections define meaning; CSS Grid adapts card width; JavaScript filters visible cards by their data-category attribute.

Setup: index.html and styles.css in a local project folder

Guided practical — 18 steps

  1. Step 1: Plan the audience and goal. Check: confirm this action before continuing.
  2. Step 2: Create a new project folder. Check: confirm this action before continuing.
  3. Step 3: Create index.html with HTML5 boilerplate. Check: confirm this action before continuing.
  4. Step 4: Set viewport for mobile scaling. Check: confirm this action before continuing.
  5. Step 5: Add semantic main and section elements. Check: confirm this action before continuing.
  6. Step 6: Create three project article cards. Check: confirm this action before continuing.
  7. Step 7: Add data-category attributes. Check: confirm this action before continuing.
  8. Step 8: Add filter buttons with data-filter. Check: confirm this action before continuing.
  9. Step 9: Style body and readable typography. Check: confirm this action before continuing.
  10. Step 10: Build responsive CSS Grid. Check: confirm this action before continuing.
  11. Step 11: Add visible keyboard focus style. Check: confirm this action before continuing.
  12. Step 12: Select filter buttons with querySelectorAll. Check: confirm this action before continuing.
  13. Step 13: Attach click handlers. Check: confirm this action before continuing.
  14. Step 14: Compare selected category to card dataset. Check: confirm this action before continuing.
  15. Step 15: Toggle hidden property. Check: confirm this action before continuing.
  16. Step 16: Open the page in a browser. Check: confirm this action before continuing.
  17. Step 17: Test at 360px and desktop width. Check: confirm this action before continuing.
  18. Step 18: Verify All/Web/Apps filters and keyboard access. Check: confirm this action before continuing.
Copyable project code / working template
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Portfolio</title><style>body{font:16px system-ui;margin:2rem;background:#f4f7fc;color:#123}main{max-width:900px;margin:auto}.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:1rem}article{background:white;padding:1rem;border-radius:12px;border:1px solid #ddd}button{padding:.7rem;margin:.25rem;cursor:pointer}button:focus-visible{outline:3px solid orange}</style><main><h1>My Projects</h1><div role="group" aria-label="Filter projects"><button data-filter="all">All</button><button data-filter="web">Web</button><button data-filter="app">Apps</button></div><section class="grid" id="projects"><article data-category="web"><h2>Business Website</h2><p>HTML and CSS</p></article><article data-category="app"><h2>Task App</h2><p>JavaScript app</p></article><article data-category="web"><h2>Portfolio</h2><p>Responsive layout</p></article></section></main><script>document.querySelectorAll('[data-filter]').forEach(button=>button.addEventListener('click',()=>{const selected=button.dataset.filter;document.querySelectorAll('#projects article').forEach(card=>card.hidden=selected!=='all'&&card.dataset.category!==selected); }));</script></html>

Live output preview

Expected output

A mobile-friendly portfolio with project filtering and keyboard-accessible buttons.

Errors & solutions
  • Buttons do nothing: check console for a JavaScript syntax error and confirm script runs after HTML
  • Cards stay visible: check data-category values match data-filter
  • Mobile overflow: confirm viewport meta tag and minmax grid rule
Practice assignment & self-check

Assignment: Extend the example with one realistic feature, test it, and record the result. Do not use production credentials or real client data.

Knowledge check: Explain the purpose of the main concept, demonstrate the expected output, and identify one likely failure and fix.

LESSON 02 · Advanced

Flutter & Dart — Multi-screen task app

Objective: Build a Flutter task list with navigation and local in-memory state.

Theory: StatefulWidget holds mutable task data; Navigator opens another screen; setState rebuilds the visible list.

Setup: Flutter SDK, Android Studio or VS Code, flutter doctor passing

Guided practical — 19 steps

  1. Step 1: Install Flutter SDK from official instructions. Check: confirm this action before continuing.
  2. Step 2: Run flutter doctor and resolve blockers. Check: confirm this action before continuing.
  3. Step 3: Create project with flutter create task_lab. Check: confirm this action before continuing.
  4. Step 4: Open lib/main.dart. Check: confirm this action before continuing.
  5. Step 5: Replace starter code with provided code. Check: confirm this action before continuing.
  6. Step 6: Understand main and MaterialApp. Check: confirm this action before continuing.
  7. Step 7: Create StatefulWidget for mutable task list. Check: confirm this action before continuing.
  8. Step 8: Declare tasks list and TextEditingController. Check: confirm this action before continuing.
  9. Step 9: Build Scaffold and AppBar. Check: confirm this action before continuing.
  10. Step 10: Build text input with label. Check: confirm this action before continuing.
  11. Step 11: Validate trimmed task input. Check: confirm this action before continuing.
  12. Step 12: Use setState to add a task. Check: confirm this action before continuing.
  13. Step 13: Clear input after adding. Check: confirm this action before continuing.
  14. Step 14: Render list with ListView.builder. Check: confirm this action before continuing.
  15. Step 15: Add second screen with Navigator.push. Check: confirm this action before continuing.
  16. Step 16: Dispose controller to avoid leaks. Check: confirm this action before continuing.
  17. Step 17: Run flutter run on emulator or device. Check: confirm this action before continuing.
  18. Step 18: Add three tasks and navigate back. Check: confirm this action before continuing.
  19. Step 19: Restart app and observe in-memory reset. Check: confirm this action before continuing.
Copyable project code / working template
import 'package:flutter/material.dart';
void main()=>runApp(const MaterialApp(home:TaskHome()));
class TaskHome extends StatefulWidget{const TaskHome({super.key});@override State<TaskHome> createState()=>_TaskHomeState();}
class _TaskHomeState extends State<TaskHome>{final tasks=<String>[];final controller=TextEditingController();@override void dispose(){controller.dispose();super.dispose();}
@override Widget build(BuildContext context)=>Scaffold(appBar:AppBar(title:const Text('Task Lab')),body:Column(children:[Padding(padding:const EdgeInsets.all(12),child:TextField(controller:controller,decoration:const InputDecoration(labelText:'New task'))),ElevatedButton(onPressed:(){final t=controller.text.trim();if(t.isNotEmpty){setState(()=>tasks.add(t));controller.clear();}},child:const Text('Add task')),Expanded(child:ListView.builder(itemCount:tasks.length,itemBuilder:(context,i)=>ListTile(title:Text(tasks[i]))))]),floatingActionButton:FloatingActionButton(onPressed:()=>Navigator.push(context,MaterialPageRoute(builder:(_)=>const AboutScreen())),child:const Icon(Icons.info)));}
class AboutScreen extends StatelessWidget{const AboutScreen({super.key});@override Widget build(BuildContext context)=>Scaffold(appBar:AppBar(title:const Text('About')),body:const Center(child:Text('Practice project — no cloud sync')));}

Expected output

Two screens; add tasks; tasks display in a list until app is restarted.

Errors & solutions
  • flutter command not found: fix SDK PATH
  • No devices: start emulator or connect USB debugging
  • State resets on restart: expected; persistence requires local database
Practice assignment & self-check

Assignment: Extend the example with one realistic feature, test it, and record the result. Do not use production credentials or real client data.

Knowledge check: Explain the purpose of the main concept, demonstrate the expected output, and identify one likely failure and fix.

LESSON 03 · Advanced

Google Apps Script — Approval tracker automation

Objective: Create a safe, manual-run approval tracker in Google Sheets.

Theory: Apps Script can read spreadsheet rows in batches and update cells; manual runs avoid unexpected automated side effects.

Setup: Google account, a spreadsheet with Requests sheet

Guided practical — 19 steps

  1. Step 1: Create a new Google Sheet. Check: confirm this action before continuing.
  2. Step 2: Rename first tab Requests. Check: confirm this action before continuing.
  3. Step 3: Add Request ID and Status headers. Check: confirm this action before continuing.
  4. Step 4: Enter three fictional request IDs. Check: confirm this action before continuing.
  5. Step 5: Leave one Status cell empty. Check: confirm this action before continuing.
  6. Step 6: Open Extensions → Apps Script. Check: confirm this action before continuing.
  7. Step 7: Paste provided function. Check: confirm this action before continuing.
  8. Step 8: Save project. Check: confirm this action before continuing.
  9. Step 9: Read getActiveSpreadsheet usage. Check: confirm this action before continuing.
  10. Step 10: Understand getDataRange and getValues. Check: confirm this action before continuing.
  11. Step 11: Locate header indices. Check: confirm this action before continuing.
  12. Step 12: Check missing headers handling. Check: confirm this action before continuing.
  13. Step 13: Check empty request ID handling. Check: confirm this action before continuing.
  14. Step 14: Write Pending review only to blank statuses. Check: confirm this action before continuing.
  15. Step 15: Run function manually. Check: confirm this action before continuing.
  16. Step 16: Review permission dialog and scope. Check: confirm this action before continuing.
  17. Step 17: Verify only expected cells changed. Check: confirm this action before continuing.
  18. Step 18: Run again to check idempotency. Check: confirm this action before continuing.
  19. Step 19: Record changes and plan audit log for production. Check: confirm this action before continuing.
Copyable project code / working template
function updateRequestStatuses() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Requests');
  if (!sheet) throw new Error('Create a sheet named Requests');
  const rows = sheet.getDataRange().getValues();
  if (rows.length < 2) return;
  const headers = rows[0];
  const id = headers.indexOf('Request ID');
  const status = headers.indexOf('Status');
  if (id < 0 || status < 0) throw new Error('Headers required: Request ID, Status');
  for (let r = 1; r < rows.length; r++) {
    if (String(rows[r][id]).trim() && !String(rows[r][status]).trim()) {
      sheet.getRange(r + 1, status + 1).setValue('Pending review');
    }
  }
}

Expected output

Script fills a Status column for valid pending requests; does not email or approve externally.

Errors & solutions
  • Sheet not found: rename tab Requests exactly
  • Missing headers: check spaces and capitalization
  • Authorization required: review requested permissions before approving
Practice assignment & self-check

Assignment: Extend the example with one realistic feature, test it, and record the result. Do not use production credentials or real client data.

Knowledge check: Explain the purpose of the main concept, demonstrate the expected output, and identify one likely failure and fix.

LESSON 04 · Full Advanced

GitHub Actions — Static site quality gate

Objective: Run a lightweight HTML check on every push and pull request.

Theory: CI runs repeatable checks on isolated runners; a quality gate catches missing assets before deployment.

Setup: GitHub repository containing index.html

Guided practical — 19 steps

  1. Step 1: Create a repository with index.html. Check: confirm this action before continuing.
  2. Step 2: Commit a valid title element. Check: confirm this action before continuing.
  3. Step 3: Create .github/workflows folder. Check: confirm this action before continuing.
  4. Step 4: Create html-check.yml. Check: confirm this action before continuing.
  5. Step 5: Paste YAML sample. Check: confirm this action before continuing.
  6. Step 6: Understand push and pull_request triggers. Check: confirm this action before continuing.
  7. Step 7: Limit token permissions to contents read. Check: confirm this action before continuing.
  8. Step 8: Understand hosted runner. Check: confirm this action before continuing.
  9. Step 9: Use actions/checkout to retrieve code. Check: confirm this action before continuing.
  10. Step 10: Run file existence check. Check: confirm this action before continuing.
  11. Step 11: Run title check. Check: confirm this action before continuing.
  12. Step 12: Commit workflow file. Check: confirm this action before continuing.
  13. Step 13: Open Actions tab. Check: confirm this action before continuing.
  14. Step 14: Inspect job logs. Check: confirm this action before continuing.
  15. Step 15: Create test branch. Check: confirm this action before continuing.
  16. Step 16: Remove title in branch to see failure. Check: confirm this action before continuing.
  17. Step 17: Restore title and push. Check: confirm this action before continuing.
  18. Step 18: Verify passing result. Check: confirm this action before continuing.
  19. Step 19: Explain why linting and browser tests are future improvements. Check: confirm this action before continuing.
Copyable project code / working template
name: HTML quality gate
on: [push, pull_request]
permissions:
  contents: read
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Validate landing page
        shell: bash
        run: |
          test -f index.html
          grep -qi '<title>' index.html
          echo 'Basic HTML check passed'

Expected output

Workflow passes when index.html exists and includes a title; fails when it does not.

Errors & solutions
  • Workflow not visible: check path .github/workflows/*.yml
  • YAML parse error: check indentation
  • Check fails: ensure index.html is in repository root
Practice assignment & self-check

Assignment: Extend the example with one realistic feature, test it, and record the result. Do not use production credentials or real client data.

Knowledge check: Explain the purpose of the main concept, demonstrate the expected output, and identify one likely failure and fix.

LESSON 05 · Intermediate

Digital Marketing & SEO — Campaign landing page measurement

Objective: Plan a campaign and measure visits without claiming guaranteed conversions.

Theory: Campaign objectives should map to one conversion; UTM parameters identify source, medium and campaign, but tracking requires analytics setup.

Setup: A landing page, analytics property if available, fictional campaign brief

Guided practical — 19 steps

  1. Step 1: Define the target audience. Check: confirm this action before continuing.
  2. Step 2: Write one clear campaign objective. Check: confirm this action before continuing.
  3. Step 3: Choose a relevant offer. Check: confirm this action before continuing.
  4. Step 4: Create a single landing-page headline. Check: confirm this action before continuing.
  5. Step 5: Write benefits not unsupported claims. Check: confirm this action before continuing.
  6. Step 6: Add a clear call to action. Check: confirm this action before continuing.
  7. Step 7: Define form submission as conversion. Check: confirm this action before continuing.
  8. Step 8: Create privacy notice before collecting data. Check: confirm this action before continuing.
  9. Step 9: Select UTM source. Check: confirm this action before continuing.
  10. Step 10: Select UTM medium. Check: confirm this action before continuing.
  11. Step 11: Select UTM campaign. Check: confirm this action before continuing.
  12. Step 12: Generate tagged URL with sample code. Check: confirm this action before continuing.
  13. Step 13: Open URL and inspect parameters. Check: confirm this action before continuing.
  14. Step 14: Set up analytics with consent where required. Check: confirm this action before continuing.
  15. Step 15: Verify events using debug tools. Check: confirm this action before continuing.
  16. Step 16: Record baseline visits and conversions. Check: confirm this action before continuing.
  17. Step 17: Calculate conversion rate from real counts. Check: confirm this action before continuing.
  18. Step 18: Compare creative variations fairly. Check: confirm this action before continuing.
  19. Step 19: Document results and next test. Check: confirm this action before continuing.
Copyable project code / working template
const landingUrl = new URL('https://example.com/offer');
landingUrl.searchParams.set('utm_source','newsletter');
landingUrl.searchParams.set('utm_medium','email');
landingUrl.searchParams.set('utm_campaign','november_launch');
console.log(landingUrl.toString());

Expected output

A written campaign plan with a UTM-tagged link and measurable conversion event definition.

Errors & solutions
  • No analytics events: verify tag installation and consent state
  • UTM lost: check redirects preserve query parameters
  • Conversions show zero: test the actual event rather than assuming clicks are conversions
Practice assignment & self-check

Assignment: Extend the example with one realistic feature, test it, and record the result. Do not use production credentials or real client data.

Knowledge check: Explain the purpose of the main concept, demonstrate the expected output, and identify one likely failure and fix.

LESSON 06 · Full Advanced

Online Earning & Client Delivery — Freelance website project handover

Objective: Prepare a scoped, testable client delivery pack with professional acceptance criteria.

Theory: A client project is complete when agreed deliverables and acceptance tests pass, not merely when files are uploaded.

Setup: Fictional client brief and sample website

Guided practical — 20 steps

  1. Step 1: Interview fictional client about goals. Check: confirm this action before continuing.
  2. Step 2: List target users and required pages. Check: confirm this action before continuing.
  3. Step 3: Document in-scope deliverables. Check: confirm this action before continuing.
  4. Step 4: Document exclusions. Check: confirm this action before continuing.
  5. Step 5: Agree measurable acceptance criteria. Check: confirm this action before continuing.
  6. Step 6: Create milestone plan. Check: confirm this action before continuing.
  7. Step 7: Define who supplies content and images. Check: confirm this action before continuing.
  8. Step 8: Choose accessible responsive layout. Check: confirm this action before continuing.
  9. Step 9: Build and test navigation. Check: confirm this action before continuing.
  10. Step 10: Test contact form with approved backend or label demo. Check: confirm this action before continuing.
  11. Step 11: Audit internal links. Check: confirm this action before continuing.
  12. Step 12: Check images and copyright permissions. Check: confirm this action before continuing.
  13. Step 13: Test mobile widths. Check: confirm this action before continuing.
  14. Step 14: Review privacy and consent requirements. Check: confirm this action before continuing.
  15. Step 15: Prepare client review checklist. Check: confirm this action before continuing.
  16. Step 16: Collect written feedback. Check: confirm this action before continuing.
  17. Step 17: Fix defects and rerun tests. Check: confirm this action before continuing.
  18. Step 18: Package source and documentation. Check: confirm this action before continuing.
  19. Step 19: Transfer account ownership securely. Check: confirm this action before continuing.
  20. Step 20: Obtain acceptance and agree support terms. Check: confirm this action before continuing.
Copyable project code / working template
PROJECT: Local Business Website
Scope: 5 responsive pages; contact form integration subject to client-approved backend
Milestones: 1) Brief and wireframe 2) Build 3) QA and review 4) Handover
Acceptance: mobile layout; working navigation; accessible forms; no broken internal links
Handover: source ZIP, deployment instructions, account ownership list, maintenance guide
Excluded: paid ads, ongoing hosting fees, unapproved integrations

Expected output

A written scope, milestone plan, QA checklist and handover inventory.

Errors & solutions
  • Scope creep: log change requests and agree price/timeline before work
  • Missing access: use a handover inventory with account owners
  • Broken links: run automated link audit and manually inspect critical paths
Practice assignment & self-check

Assignment: Extend the example with one realistic feature, test it, and record the result. Do not use production credentials or real client data.

Knowledge check: Explain the purpose of the main concept, demonstrate the expected output, and identify one likely failure and fix.

Media learning options

Video, audio and PDF files are not pre-recorded for these six lessons. Use the existing Video / Audio / PDF Tutorials section for your own recordings. No fake play buttons are shown here.

Open Video / Audio / PDF Tutorials