Powered by AppSignal & Oban Pro

Learning Progress Dashboard

livebooks/dashboard.livemd

Learning Progress Dashboard

Overview

Track your progress through all 15 phases of Elixir Systems Mastery.

Setup

Mix.install([
  {:jason, "~> 1.4"},
  {:vega_lite, "~> 0.1"},
  {:kino_vega_lite, "~> 0.1"}
])

Progress Data Management

defmodule ProgressTracker do
  @progress_file "livebooks/.progress.json"

  def load_progress do
    case File.read(@progress_file) do
      {:ok, content} ->
        Jason.decode!(content)

      {:error, _} ->
        # Initialize with empty progress
        %{}
    end
  end

  def save_progress(progress) do
    content = Jason.encode!(progress, pretty: true)
    File.write!(@progress_file, content)
  end

  def mark_complete(phase, checkpoint) do
    progress = load_progress()

    phase_progress =
      Map.get(progress, phase, %{})
      |> Map.put(checkpoint, true)

    updated_progress = Map.put(progress, phase, phase_progress)
    save_progress(updated_progress)

    updated_progress
  end

  def get_phase_completion(phase) do
    progress = load_progress()
    phase_data = Map.get(progress, phase, %{})

    completed = phase_data |> Map.values() |> Enum.count(& &1)
    total = phase_checkpoints(phase)

    {completed, total}
  end

  def overall_progress do
    progress = load_progress()

    Enum.map(all_phases(), fn phase ->
      {completed, total} = get_phase_completion(phase)
      percentage = if total > 0, do: completed / total * 100, else: 0

      %{
        phase: phase,
        completed: completed,
        total: total,
        percentage: Float.round(percentage, 1)
      }
    end)
  end

  defp all_phases do
    [
      "phase-01-core",
      "phase-02-processes",
      "phase-03-genserver",
      "phase-04-naming",
      "phase-05-data",
      "phase-06-phoenix",
      "phase-07-jobs",
      "phase-08-caching",
      "phase-09-distribution",
      "phase-10-observability",
      "phase-11-testing",
      "phase-12-delivery",
      "phase-13-capstone",
      "phase-14-cto",
      "phase-15-ai"
    ]
  end

  defp phase_checkpoints("phase-01-core"), do: 7
  defp phase_checkpoints("phase-02-processes"), do: 5
  defp phase_checkpoints("phase-03-genserver"), do: 6
  defp phase_checkpoints("phase-04-naming"), do: 4
  defp phase_checkpoints("phase-05-data"), do: 8
  defp phase_checkpoints("phase-06-phoenix"), do: 10
  defp phase_checkpoints("phase-07-jobs"), do: 6
  defp phase_checkpoints("phase-08-caching"), do: 5
  defp phase_checkpoints("phase-09-distribution"), do: 8
  defp phase_checkpoints("phase-10-observability"), do: 7
  defp phase_checkpoints("phase-11-testing"), do: 6
  defp phase_checkpoints("phase-12-delivery"), do: 5
  defp phase_checkpoints("phase-13-capstone"), do: 10
  defp phase_checkpoints("phase-14-cto"), do: 8
  defp phase_checkpoints("phase-15-ai"), do: 8
end

:ok

Current Progress

progress_data = ProgressTracker.overall_progress()

Kino.Markdown.new("""
## ๐Ÿ“Š Overall Progress

#{Enum.map(progress_data, fn p ->
  bar_width = trunc(p.percentage / 2)
  bar = String.duplicate("โ–ˆ", bar_width) <> String.duplicate("โ–‘", 50 - bar_width)
  "**#{String.replace(p.phase, "-", " ") |> String.upcase()}**  \n`#{bar}` #{p.percentage}% (#{p.completed}/#{p.total})\n"
end)
|> Enum.join("\n")}
""")

Progress Visualization

alias VegaLite, as: Vl

# Create progress chart
Vl.new(width: 600, height: 400, title: "Learning Progress by Phase")
|> Vl.data_from_values(progress_data)
|> Vl.mark(:bar)
|> Vl.encode_field(:x, "phase", type: :nominal, title: "Phase", axis: [label_angle: -45])
|> Vl.encode_field(:y, "percentage", type: :quantitative, title: "Completion %")
|> Vl.encode(:color,
  field: "percentage",
  type: :quantitative,
  scale: [domain: [0, 100], range: ["#ff6b6b", "#51cf66"]]
)
|> Vl.encode(:tooltip, [
  [field: "phase", type: :nominal],
  [field: "completed", type: :quantitative],
  [field: "total", type: :quantitative],
  [field: "percentage", type: :quantitative]
])

Phase Details

Phase 1: Elixir Core

Status: Available Now Duration: 6-9 days Checkpoints: 7

phase1_checkpoints = [
  {"01-pattern-matching.livemd", "Pattern Matching & Guards"},
  {"02-recursion.livemd", "Recursion & Tail-Call Optimization"},
  {"03-enum-stream.livemd", "Enum vs Stream"},
  {"04-error-handling.livemd", "Tagged Tuples & Error Handling"},
  {"05-property-testing.livemd", "Property-Based Testing"},
  {"06-pipe-operator.livemd", "Pipe Operator & Data Structures"},
  {"07-advanced-patterns.livemd", "Advanced Patterns & Final Challenge"}
]

Kino.Markdown.new("""
#### Checkpoints:

#{Enum.with_index(phase1_checkpoints, 1)
|> Enum.map(fn {{file, title}, idx} ->
  "#{idx}. [#{title}](phase-01-core/#{file})"
end)
|> Enum.join("\n")}
""")

Phase 2-15: Coming Soon

More phases will be available as you progress through the curriculum.

upcoming_phases = [
  {"Phase 2", "Processes & Mailboxes", "5-7 days"},
  {"Phase 3", "GenServer + Supervision", "6-8 days"},
  {"Phase 4", "Naming & Fleets", "6-8 days"},
  {"Phase 5", "Data & Ecto", "8-10 days"},
  {"Phase 6", "Phoenix Web", "10-12 days"},
  {"Phase 7", "Jobs & Ingestion", "8-10 days"},
  {"Phase 8", "Caching & ETS", "6-8 days"},
  {"Phase 9", "Distribution", "10-14 days"},
  {"Phase 10", "Observability & SLOs", "8-12 days"},
  {"Phase 11", "Testing Strategy", "6-8 days"},
  {"Phase 12", "Delivery & Ops", "5-7 days"},
  {"Phase 13", "Capstone Integration", "10-14 days"},
  {"Phase 14", "CTO Track", "8-10 days"},
  {"Phase 15", "AI/ML Integration", "8-12 days"}
]

Kino.Markdown.new("""
#### Upcoming Phases:

#{Enum.map(upcoming_phases, fn {phase, title, duration} ->
  "**#{phase}:** #{title} _(#{duration})_"
end)
|> Enum.join("\n\n")}
""")

Mark Checkpoint Complete

Use this form to mark checkpoints as complete:

phase_options =
  [
    {"Phase 1: Elixir Core", "phase-01-core"},
    {"Phase 2: Processes", "phase-02-processes"},
    {"Phase 3: GenServer", "phase-03-genserver"},
    {"Phase 4: Naming", "phase-04-naming"},
    {"Phase 5: Data", "phase-05-data"},
    {"Phase 6: Phoenix", "phase-06-phoenix"},
    {"Phase 7: Jobs", "phase-07-jobs"},
    {"Phase 8: Caching", "phase-08-caching"},
    {"Phase 9: Distribution", "phase-09-distribution"},
    {"Phase 10: Observability", "phase-10-observability"},
    {"Phase 11: Testing", "phase-11-testing"},
    {"Phase 12: Delivery", "phase-12-delivery"},
    {"Phase 13: Capstone", "phase-13-capstone"},
    {"Phase 14: CTO", "phase-14-cto"},
    {"Phase 15: AI", "phase-15-ai"}
  ]

form = Kino.Control.form(
  [
    phase: {:select, "Select Phase", phase_options},
    checkpoint: {:text, "Checkpoint (e.g., 'checkpoint-01')"}
  ],
  submit: "Mark Complete"
)

Kino.render(form)

Kino.listen(form, fn %{data: data} ->
  if data.checkpoint != "" do
    updated = ProgressTracker.mark_complete(data.phase, data.checkpoint)

    Kino.Markdown.new("""
    โœ… **Marked as complete!**

    Phase: `#{data.phase}`
    Checkpoint: `#{data.checkpoint}`

    _Refresh this page to see updated progress chart._
    """)
    |> Kino.render()
  else
    Kino.Markdown.new("โš ๏ธ Please enter a checkpoint name") |> Kino.render()
  end
end)

Quick Navigation

Kino.Markdown.new("""
### ๐Ÿš€ Quick Links

* [Setup Guide](setup.livemd) - Getting started with Livebook
* [Phase 1: Checkpoint 1](phase-01-core/01-pattern-matching.livemd) - Start learning!

### ๐Ÿ“š Additional Resources

* [Repository README](../README.md)
* [Curriculum Map](../docs/curriculum-map.md)
* [Lesson Planning System](../docs/LESSON-PLANNING-SYSTEM.md)

### ๐ŸŽฏ Your Learning Path

1. Complete all 7 checkpoints in Phase 1
2. Build the statistics calculator (final challenge)
3. Move on to Phase 2: Processes & Mailboxes
4. Continue through all 15 phases
5. Complete the capstone project in Phase 13

**Current Focus:** #{if Enum.at(progress_data, 0).percentage < 100, do: "Phase 1 - Elixir Core", else: "Phase 2 - Processes & Mailboxes"}
""")

Learning Tips

Kino.Markdown.new("""
### ๐Ÿ’ก Tips for Success

1. **Practice Every Day**
   - Even 30 minutes daily is better than marathon sessions
   - Consistency builds muscle memory

2. **Experiment Freely**
   - Modify all code examples
   - Break things to understand them
   - Ask "what if...?" questions

3. **Build Projects**
   - Apply concepts to real problems
   - Start small, iterate, and expand
   - Share your work with the community

4. **Use the REPL**
   - Test ideas immediately in Livebook cells
   - Pattern matching works interactively
   - See results instantly

5. **Review and Reflect**
   - Revisit earlier checkpoints
   - Teach concepts to others (best way to learn!)
   - Keep a learning journal

6. **Join the Community**
   - Elixir Forum: https://elixirforum.com
   - Elixir Slack: https://elixir-slackin.herokuapp.com
   - Local Elixir meetups

### ๐ŸŽ“ When You're Stuck

1. Re-read the concept section
2. Try simpler examples first
3. Check the property tests for hints
4. Review previous checkpoints
5. Ask for help in the community
6. Take a break and come back fresh

### ๐Ÿ“ˆ Track Your Progress

- Use this dashboard regularly
- Complete self-assessments honestly
- Build the final challenges
- Maintain >90% test coverage
- Pass all Dialyzer checks

**Remember:** Everyone learns at their own pace. Focus on understanding, not speed! ๐ŸŒŸ
""")

Happy learning! Return to Setup Guide to start or continue your journey.