diff --git a/README.md b/README.md
index c9f198e7..012b3a50 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
+# ⚠️ THIS REPO HAS BEEN MOVED: [NEW LINK](https://github.com/African-Ruby-Community/arc_platform) ⚠️
+
# Africa Ruby Community (ARC) Platform
[](https://github.com/African-Ruby-Community/arc_platform/actions/workflows/ci.yml)
@@ -51,7 +53,7 @@ Access app at `http://localhost:3000`
Install dependencies for compiling Ruby:
* macOS: Install Homebrew
-
+
```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
diff --git a/app/assets/images/auth-community.jpg b/app/assets/images/auth-community.jpg
new file mode 100644
index 00000000..88680d3e
Binary files /dev/null and b/app/assets/images/auth-community.jpg differ
diff --git a/app/assets/images/conference.jpg b/app/assets/images/conference.jpg
index e28a7448..fd3b67f5 100644
Binary files a/app/assets/images/conference.jpg and b/app/assets/images/conference.jpg differ
diff --git a/app/assets/images/hero-community.jpg b/app/assets/images/hero-community.jpg
new file mode 100644
index 00000000..ae16e08d
Binary files /dev/null and b/app/assets/images/hero-community.jpg differ
diff --git a/app/assets/images/meetup.jpg b/app/assets/images/meetup.jpg
new file mode 100644
index 00000000..515bb07c
Binary files /dev/null and b/app/assets/images/meetup.jpg differ
diff --git a/app/assets/images/workshop.jpg b/app/assets/images/workshop.jpg
index 54bc9892..43a7cf76 100644
Binary files a/app/assets/images/workshop.jpg and b/app/assets/images/workshop.jpg differ
diff --git a/app/controllers/landing_controller.rb b/app/controllers/landing_controller.rb
index c5287e7e..f5c8fa42 100644
--- a/app/controllers/landing_controller.rb
+++ b/app/controllers/landing_controller.rb
@@ -2,13 +2,17 @@
class LandingController < ApplicationController
# People should not require authentication for following actions
- skip_before_action :authenticate_user!, only: %i[index about learn]
+ skip_before_action :authenticate_user!, only: %i[index about activities learn]
def index; end
##
# About us page
def about; end
+ ##
+ # Activities page
+ def activities; end
+
##
# Featured learning materials
def learn; end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 537f629c..f54e41b8 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -3,6 +3,7 @@
class ProjectsController < ApplicationController
skip_before_action :authenticate_user!, only: %i[index show]
before_action :set_project, only: %i[show]
+ skip_before_action :authenticate_user!, only: %i[index show]
# GET /projects or /projects.json
def index
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 0e0edb49..950ffe03 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -2,4 +2,24 @@
module ApplicationHelper
include Pagy::Frontend
+
+ SOCIALS = [
+ { alt_key: 'social_media.twitter', link: 'https://twitter.com/ruby_african', image: 'brands_twitter.png',
+ show: true },
+ { alt_key: 'social_media.telegram', link: '#', image: 'brands_telegram.png',
+ show: FeatureFlag.find_by(name: 'telegram')&.enabled },
+ { alt_key: 'social_media.facebook', link: 'https://www.facebook.com/rubycommunity.africa',
+ image: 'brands_facebook.png',
+ show: true },
+ { alt_key: 'social_media.instagram', link: 'https://www.instagram.com/africanruby_community/', image: 'brands_instagram.png', show: true },
+ { alt_key: 'social_media.linkedin', link: 'https://www.linkedin.com/company/african-ruby-community/',
+ image: 'brands_linkedin.png', show: true },
+ { alt_key: 'social_media.github', link: 'https://github.com/nairuby', image: 'brands_github.png', show: true }
+ ].freeze
+
+ def socials
+ SOCIALS.map do |social|
+ social.merge(alt: I18n.t(social[:alt_key]))
+ end
+ end
end
diff --git a/app/helpers/chapters_helper.rb b/app/helpers/chapters_helper.rb
index ffff924a..aff143f8 100644
--- a/app/helpers/chapters_helper.rb
+++ b/app/helpers/chapters_helper.rb
@@ -3,11 +3,36 @@
# rubocop:disable Metrics/ModuleLength
module ChaptersHelper
ACTIVITIES = [
- { image: 'activities_local_meetups.png', title_key: 'activities.meetups' },
- { image: 'activities_local_conferences.png', title_key: 'activities.conferences' },
- { image: 'activities_local_programming.png', title_key: 'activities.programming' },
- { image: 'activities_local_workshops.png', title_key: 'activities.workshops' },
- { image: 'activities_local_hackathons.png', title_key: 'activities.hackathons' }
+ {
+ image: 'activities_local_meetups.png',
+ title: 'Local Meetups',
+ description: 'Monthly gatherings in cities across East Africa where developers share knowledge and network.',
+ svg_paths: ' '
+ },
+ {
+ image: 'activities_local_conferences.png',
+ title: 'Conferences',
+ description: 'RubyConf Africa brings together the best minds in the Ruby ecosystem for talks, workshops, and collaboration.',
+ svg_paths: ' '
+ },
+ {
+ image: 'activities_local_programming.png',
+ title: 'Programming',
+ description: 'Collaborative coding sessions, pair programming, and open-source contributions to the global Ruby ecosystem.',
+ svg_paths: ' '
+ },
+ {
+ image: 'activities_local_workshops.png',
+ title: 'Workshops',
+ description: 'Hands-on workshops for all skill levels, from Ruby fundamentals to advanced Rails development.',
+ svg_paths: ' '
+ },
+ {
+ image: 'activities_local_hackathons.png',
+ title: 'Hackathons',
+ description: 'Competitive hackathons challenging developers to build innovative solutions using Ruby technologies.',
+ svg_paths: ' '
+ }
].freeze
CHAPTERS = [
@@ -53,6 +78,57 @@ module ChaptersHelper
{ image: 'sponsors/previous/andela.png', link: 'https://andela.com/', alt_key: 'sponsors.previous.andela' }
].freeze
+ PROJECTS = [
+ {
+ title: 'Nairuby Website',
+ description: 'The official Nairuby chapter website showcasing events and community resources.',
+ tags: ['Ruby', 'Rails', 'Community'],
+ stars: '240',
+ github_url: 'https://github.com/nairuby',
+ url: '#'
+ },
+ {
+ title: 'ARC Learning Platform',
+ description: 'An open-source platform for sharing Ruby learning resources and tutorials.',
+ tags: ['Ruby', 'Education', 'Open Source'],
+ stars: '189',
+ github_url: 'https://github.com/nairuby',
+ url: '#'
+ },
+ {
+ title: 'Ruby Dev Tools',
+ description: 'A collection of developer tools built by the community to improve Ruby workflows.',
+ tags: ['Ruby', 'Tools', 'Utilities'],
+ stars: '156',
+ github_url: 'https://github.com/nairuby',
+ url: '#'
+ },
+ {
+ title: 'Community Contribution Guide',
+ description: 'Comprehensive guide to contributing to Ruby projects and open source.',
+ tags: ['Documentation', 'Open Source'],
+ stars: '312',
+ github_url: 'https://github.com/nairuby',
+ url: '#'
+ },
+ {
+ title: 'ARC Conference App',
+ description: 'Mobile-first app for our annual Ruby Conference with schedule and networking features.',
+ tags: ['Ruby', 'Rails', 'Events'],
+ stars: '98',
+ github_url: 'https://github.com/nairuby',
+ url: '#'
+ },
+ {
+ title: 'Ruby Best Practices',
+ description: 'A curated collection of Ruby best practices and design patterns from community experts.',
+ tags: ['Ruby', 'Best Practices', 'Guide'],
+ stars: '467',
+ github_url: 'https://github.com/nairuby',
+ url: '#'
+ }
+ ].freeze
+
SOCIALS = [
{ alt_key: 'social_media.twitter', link: 'https://twitter.com/ruby_african', image: 'brands_twitter.png',
show: true },
@@ -68,9 +144,7 @@ module ChaptersHelper
].freeze
def activities
- ACTIVITIES.map do |activity|
- activity.merge(title: I18n.t(activity[:title_key]))
- end
+ ACTIVITIES
end
def chapters
@@ -89,6 +163,10 @@ def previous_sponsors
end
end
+ def static_projects
+ PROJECTS
+ end
+
def socials
SOCIALS.map do |social|
social.merge(alt: I18n.t(social[:alt_key]))
diff --git a/app/javascript/controllers/index.js b/app/javascript/controllers/index.js
index 4edf7a32..3d661ffa 100644
--- a/app/javascript/controllers/index.js
+++ b/app/javascript/controllers/index.js
@@ -13,5 +13,11 @@ application.register("removals", RemovalsController)
import TurboFramesController from "./turbo_frames_controller.js"
application.register("turbo_frames", TurboFramesController)
-import TurnstileController from "./turnstile_controller.js"
-application.register("turnstile", TurnstileController)
+import NavbarController from "./navbar_controller.js"
+application.register("navbar", NavbarController)
+
+import ThemeController from "./theme_controller.js"
+application.register("theme", ThemeController)
+
+import ProjectSearchController from "./project_search_controller.js"
+application.register("project-search", ProjectSearchController)
diff --git a/app/javascript/controllers/navbar_controller.js b/app/javascript/controllers/navbar_controller.js
new file mode 100644
index 00000000..459c6e66
--- /dev/null
+++ b/app/javascript/controllers/navbar_controller.js
@@ -0,0 +1,17 @@
+import { Controller } from "@hotwired/stimulus"
+
+export default class extends Controller {
+ static targets = ["menu", "openIcon", "closeIcon"]
+
+ toggle() {
+ this.menuTarget.classList.toggle("hidden")
+ this.openIconTarget.classList.toggle("hidden")
+ this.closeIconTarget.classList.toggle("hidden")
+ }
+
+ close() {
+ this.menuTarget.classList.add("hidden")
+ this.openIconTarget.classList.remove("hidden")
+ this.closeIconTarget.classList.add("hidden")
+ }
+}
diff --git a/app/javascript/controllers/project_search_controller.js b/app/javascript/controllers/project_search_controller.js
new file mode 100644
index 00000000..96b99b51
--- /dev/null
+++ b/app/javascript/controllers/project_search_controller.js
@@ -0,0 +1,31 @@
+import { Controller } from "@hotwired/stimulus"
+
+export default class extends Controller {
+ static targets = ["input", "card", "empty", "count"]
+
+ filter() {
+ const query = this.inputTarget.value.trim().toLowerCase()
+ let visible = 0
+
+ this.cardTargets.forEach(card => {
+ const text = card.dataset.searchText.toLowerCase()
+ const match = !query || text.includes(query)
+ card.style.display = match ? "" : "none"
+ if (match) visible++
+ })
+
+ if (this.hasEmptyTarget) {
+ this.emptyTarget.style.display = visible === 0 ? "" : "none"
+ }
+
+ if (this.hasCountTarget) {
+ this.countTarget.textContent = `${visible} project${visible === 1 ? "" : "s"}`
+ }
+ }
+
+ clear() {
+ this.inputTarget.value = ""
+ this.filter()
+ this.inputTarget.focus()
+ }
+}
diff --git a/app/javascript/controllers/theme_controller.js b/app/javascript/controllers/theme_controller.js
new file mode 100644
index 00000000..43f0c2fa
--- /dev/null
+++ b/app/javascript/controllers/theme_controller.js
@@ -0,0 +1,8 @@
+import { Controller } from "@hotwired/stimulus"
+
+export default class extends Controller {
+ toggle() {
+ const isDark = document.documentElement.classList.toggle("dark")
+ localStorage.theme = isDark ? "dark" : "light"
+ }
+}
diff --git a/app/views/chapters/index.html.erb b/app/views/chapters/index.html.erb
index 64ea38e5..81a1e1b0 100644
--- a/app/views/chapters/index.html.erb
+++ b/app/views/chapters/index.html.erb
@@ -47,7 +47,28 @@
<%= chapter.name %>
-
+ <% end %>
+
+
+
+
+
+<%# Start a Chapter CTA %>
+
+
+
+ Want to Start a Chapter?
+
+
+ Interested in building the Ruby community in your city? We'd love to help you establish
+ a new ARC chapter. Connect with us to get started.
+
+ <%= link_to new_user_registration_path,
+ class: "inline-flex items-center gap-2 rounded-md bg-red-600 px-8 py-3 text-sm font-semibold text-white hover:bg-red-700 transition-colors" do %>
+ Get in Touch
+
+
+
<% end %>
diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb
index 30ad8b23..89abe627 100644
--- a/app/views/devise/registrations/new.html.erb
+++ b/app/views/devise/registrations/new.html.erb
@@ -1,10 +1,5 @@
-
-
-
- <%= image_tag 'sign_up_karate.png' %>
-
-
-
<%= t('devise.views.registrations.new.title') %>
+<% content_for :title, "Sign Up" %>
+<% content_for :full_width do %><% end %>
@@ -32,7 +27,9 @@
url: registration_path(resource_name),
html: { data: { controller: "bot-detection", bot_detection_target: "form" } }) do |f| %>
- <%#= f.invisible_captcha :nickname %>
+ <%# Left — form %>
+
+
<% oauth_user = session['devise.github_data'].present? %>
@@ -91,8 +88,161 @@
<% end %>
-
- <%= render "devise/shared/links" %>
+ <%# Field helper macro %>
+ <% input_class = "w-full h-11 pl-10 pr-4 rounded-md border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 text-zinc-900 dark:text-white placeholder-zinc-400 dark:placeholder-zinc-500 text-sm focus:outline-none focus:ring-2 focus:ring-red-500/30 focus:border-red-500/50 transition-colors" %>
+
+ <%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
+
+
+ <%# Email — full width %>
+
+ <%= f.label :email, "Email Address", class: "block text-sm font-medium text-zinc-900 dark:text-white" %>
+
+
+
+
+ <%= f.email_field :email, autocomplete: "email", placeholder: "you@example.com", required: true, class: input_class %>
+
+
+
+ <%# Full name + Phone — two columns %>
+
+
+ <%= f.label :name, "Full Name", class: "block text-sm font-medium text-zinc-900 dark:text-white" %>
+
+
+
+
+ <%= f.text_field :name, autocomplete: "name", placeholder: "Your name", required: true, class: input_class %>
+
+
+
+ <%= f.label :phone_number, "Phone Number", class: "block text-sm font-medium text-zinc-900 dark:text-white" %>
+
+
+
+
+ <%= f.telephone_field :phone_number, placeholder: "254xxxxxxxxx", required: true, class: input_class %>
+
+
WhatsApp preferred.
+
+
+
+ <%# Chapter + GitHub — two columns %>
+
+
+ Chapter
+ <%= select_tag :chapter_id,
+ options_from_collection_for_select(Chapter.all, 'id', 'name'),
+ include_blank: "Select chapter",
+ class: "w-full h-11 px-3 rounded-md border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 text-zinc-900 dark:text-white text-sm focus:outline-none focus:ring-2 focus:ring-red-500/30 focus:border-red-500/50 transition-colors" %>
+
+
+ <%= f.label :github_username, "GitHub Username", class: "block text-sm font-medium text-zinc-900 dark:text-white" %>
+
+
+
+
+ <%= f.text_field :github_username, placeholder: "username", required: true, class: input_class %>
+
+
We'll verify your account.
+
+
+
+ <%# Password + Confirm — two columns %>
+
+
+ <%= f.label :password, "Password", class: "block text-sm font-medium text-zinc-900 dark:text-white" %>
+
+
+
+
+ <%= f.password_field :password, autocomplete: "new-password", placeholder: "••••••••", required: true, class: input_class %>
+
+
+
+ <%= f.label :password_confirmation, "Confirm Password", class: "block text-sm font-medium text-zinc-900 dark:text-white" %>
+
+
+
+
+ <%= f.password_field :password_confirmation, autocomplete: "new-password", placeholder: "••••••••", required: true, class: input_class %>
+
+
+
+
+ <%# Submit — full width %>
+ <%= f.submit "Create Account",
+ class: "w-full h-11 mt-2 rounded-md bg-red-600 text-white text-sm font-semibold hover:bg-red-700 active:bg-red-800 transition-colors cursor-pointer shadow-lg shadow-red-500/20" %>
+
+
+ <% end %>
+
+ <%# Divider + OmniAuth %>
+ <% if devise_mapping.omniauthable? %>
+
+ <% resource_class.omniauth_providers.each do |provider| %>
+ <%= link_to omniauth_authorize_path(resource_name, provider), method: :post,
+ class: "flex w-full h-11 items-center justify-center gap-2 rounded-md border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-800/50 text-sm font-medium text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-all mb-3" do %>
+
+
+
+ Sign up with <%= OmniAuth::Utils.camelize(provider) %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+ <%# Sign in link %>
+
+ Already have an account?
+ <%= link_to "Sign in", new_session_path(resource_name),
+ class: "text-red-500 hover:text-red-600 font-medium transition-colors" %>
+
+
+ <%# Footer links %>
+
+
-
\ No newline at end of file
+
+ <%# Right — community image %>
+
+ <%= image_tag 'auth-community.jpg', alt: "Ruby Community",
+ class: "absolute inset-0 w-full h-full object-cover" %>
+
+
+
+
+
+ Welcome to ARC
+
+
+ Join thousands of Ruby developers across Africa. Network, learn, and build amazing things together.
+
+
+
+
+ Meetups & Conferences
+
+
+
+ Mentorship Programs
+
+
+
+ Job Opportunities
+
+
+
+
+
+
+
diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb
index 7c31d527..1f6d2f44 100644
--- a/app/views/devise/sessions/new.html.erb
+++ b/app/views/devise/sessions/new.html.erb
@@ -1,16 +1,42 @@
-
-
-
- <%= image_tag 'sign_up_karate.png' %>
-
-
-
<%= t('devise.views.sessions.new.title') %>
- <% if @turnstile_error %>
-
-
-
+<% content_for :title, "Sign In" %>
+<% content_for :full_width do %><% end %>
+
+
+
+ <%# Left — form %>
+
+
+
+ <%# Logo %>
+
+ <%= link_to root_path, class: "inline-flex items-center gap-2" do %>
+
+
-
<%= @turnstile_error %>
+
ARC
+ <% end %>
+
+
+ <%# Header %>
+
+
+ Welcome Back
+
+
+ Sign in to your ARC account and reconnect with the Ruby community
+
+
+
+ <%# Error messages %>
+ <% if resource.errors.any? %>
+
+
+ <% resource.errors.full_messages.each do |msg| %>
+ <%= msg %>
+ <% end %>
+
<% end %>
@@ -41,28 +67,120 @@
<%= f.input :email, placeholder: t('devise.views.sessions.new.email_placeholder'), label: t('devise.views.sessions.new.email_label'),
input_html: { class: 'input-bordered w-full', autofocus: true, autocomplete: 'email' } %>
- <%= f.input :password, placeholder: t('devise.views.sessions.new.password_placeholder'), label: t('devise.views.sessions.new.password_label'),
- input_html: { class: 'input-bordered w-full' } %>
-
+ <%# Email %>
+
+ <%= f.label :email, "Email Address",
+ class: "block text-sm font-semibold text-zinc-900 dark:text-white" %>
+
+
+
+
+
+ <%= f.email_field :email,
+ autofocus: true, autocomplete: "email",
+ placeholder: "you@example.com",
+ required: true,
+ class: "w-full h-12 pl-10 pr-4 rounded-md border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 text-zinc-900 dark:text-white placeholder-zinc-400 dark:placeholder-zinc-500 text-sm focus:outline-none focus:ring-2 focus:ring-red-500/30 focus:border-red-500/50 transition-colors" %>
+
+
+ <%# Password %>
+
+
+ <%= f.label :password, "Password",
+ class: "block text-sm font-semibold text-zinc-900 dark:text-white" %>
+ <% if devise_mapping.recoverable? %>
+ <%= link_to "Forgot password?", new_password_path(resource_name),
+ class: "text-xs text-red-500 hover:text-red-600 font-medium transition-colors" %>
+ <% end %>
+
+
+
+
+
+
+ <%= f.password_field :password,
+ autocomplete: "current-password",
+ placeholder: "••••••••",
+ required: true,
+ class: "w-full h-12 pl-10 pr-4 rounded-md border border-zinc-200 dark:border-zinc-700 bg-zinc-50 dark:bg-zinc-800/50 text-zinc-900 dark:text-white placeholder-zinc-400 dark:placeholder-zinc-500 text-sm focus:outline-none focus:ring-2 focus:ring-red-500/30 focus:border-red-500/50 transition-colors" %>
+
+
- <%= render "shared/cloudflare_turnstile" %>
+ <%# Remember me %>
+ <% if devise_mapping.rememberable? %>
+
+ <%= f.check_box :remember_me,
+ class: "h-4 w-4 rounded border-zinc-300 dark:border-zinc-600 text-red-500 focus:ring-red-500/30" %>
+ Remember me
+
+ <% end %>
+ <%# Submit %>
+ <%= f.submit "Sign In",
+ class: "w-full h-12 mt-3 rounded-md bg-red-600 text-white text-sm font-semibold hover:bg-red-700 active:bg-red-800 transition-colors cursor-pointer shadow-lg shadow-red-500/20" %>
+
+ <% end %>
-
- <%= f.button :button, t('devise.views.sessions.new.submit_button'),
- class: 'btn btn-primary
- disabled:cursor-not-allowed
- disabled:bg-gray-200
- disabled:text-gray-400
- disabled:border-gray-300
- disabled:shadow-none', disabled: true
- %>
+ <%# Divider %>
+ <% if devise_mapping.omniauthable? %>
+
+ <% resource_class.omniauth_providers.each do |provider| %>
+ <%= link_to omniauth_authorize_path(resource_name, provider), method: :post,
+ class: "flex w-full h-12 items-center justify-center gap-2 rounded-md border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-800/50 text-sm font-medium text-zinc-700 dark:text-zinc-300 hover:bg-zinc-50 dark:hover:bg-zinc-800 hover:border-zinc-300 dark:hover:border-zinc-600 transition-all mb-3" do %>
+
+
+
+ Sign in with <%= OmniAuth::Utils.camelize(provider) %>
+ <% end %>
+ <% end %>
<% end %>
-
- <%= render "devise/shared/links" %>
+ <%# Sign up link %>
+
+ Don't have an account?
+ <%= link_to "Create one", new_registration_path(resource_name),
+ class: "text-red-500 hover:text-red-600 font-medium transition-colors" %>
+
+
+ <%# Footer links %>
+
+
+
+ <%# Right — community image %>
+
+ <%= image_tag 'auth-community.jpg', alt: "Ruby Community",
+ class: "absolute inset-0 w-full h-full object-cover" %>
+
+
+
+
+
+ Join a Vibrant Community
+
+
+ Connect with Ruby developers across Africa, share knowledge, collaborate on projects, and grow together.
+
+
+
+ Active in 4 East African countries
+
+
+
+
+
diff --git a/app/views/landing/_learn_resource.html.erb b/app/views/landing/_learn_resource.html.erb
new file mode 100644
index 00000000..de2c08c8
--- /dev/null
+++ b/app/views/landing/_learn_resource.html.erb
@@ -0,0 +1,20 @@
+
+
+
+ <%= resource[:title] %>
+
+
+
+
+
+ <% if resource[:desc].present? %>
+ <%= resource[:desc] %>
+ <% end %>
+
diff --git a/app/views/landing/about.html.erb b/app/views/landing/about.html.erb
index 37d712e6..4d807a9d 100644
--- a/app/views/landing/about.html.erb
+++ b/app/views/landing/about.html.erb
@@ -1,23 +1,199 @@
-<% content_for(:title, t('landing.about.page_title')) %>
-<% content_for(:description, t('landing.about.page_description')) %>
-
- <%= image_tag('workshop.jpg', alt: t('landing.about.workshop_alt'), class: "pt-20 w-fit h-fit", style: "filter: brightness(40%);") %>
-
+<% content_for(:title, "About Us") %>
+<% content_for(:description, "ARC brings entrepreneurs, developers, Designers, open source contributors together") %>
+<% content_for :full_width do %><% end %>
+
+<%# Hero Section %>
+
+
+ <%= image_tag 'hero-community.jpg', alt: "African Ruby Community",
+ class: "w-full h-full object-cover" %>
+
+
+
+
+
African Ruby Community
+
+
+ Building the future of Ruby programming across Africa through community, innovation, and collaboration.
+
+
+
+
+ <%# Mission / Our Story Section %>
+
+
+
+
+
+
Our Story
+
+ Founded in 2010
+
+
+ African Ruby Community, ARC, is an organization that was started in 2010.
+ The community currently has a reach of over 5,000 members spread across East Africa,
+ made up of developers (engineers), entrepreneurs, designers, and freelancers.
+ In terms of development and demonstrations, the community focuses on Ruby technologies and frameworks,
+ which are all open source and widely used by startups to prototype and carry out proof of concept with a go-to-market strategy.
+
+
+ The community hosts monthly meetups in different cities in East Africa.
+ The community brings you Ruby Conference every year with different themes to fill the gap
+ that exists between school and industry and in return helps spur innovation and growth in
+ contribution to the global economy.
+
+
+ ARC brings entrepreneurs, developers, designers, and open source contributors.
+ Why? We believe in a holistic approach; through entrepreneurship, a "solution approach,"
+ and open source, we can solve so many problems. This in return empowers everyone who
+ attends with technology "tools" and entrepreneurship "methodology" to reach their fullest
+ potential and inspire the rest of the world and their communities.
+
+
+
+
+
+ <%# Target icon %>
+
+
+
+
Our Mission
+
+ To empower developers across Africa with Ruby technologies, fostering innovation, open source contribution, and entrepreneurial growth.
+
+
+
+ <%# Lightbulb icon %>
+
+
+
+
+
Our Vision
+
+ To build a vibrant, inclusive ecosystem where African developers lead innovation and contribute meaningfully to the global Ruby community.
+
+
+
+
+
+
+
-
-
- <%= t('landing.about.title') %>
-
+ <%# Values Section %>
+
+
+
+ Core Values
+
+ What Drives Us
+
+
-
- <%= t('landing.about.description_1') %>
-
+
+ <%# Community First %>
+
+
+
+
+
+
Community First
+
+ We believe in the power of collaboration and building together.
+
+
-
- <%= t('landing.about.description_2') %>
-
+ <%# Global Perspective %>
+
+
+
+
+
+
Global Perspective
+
+ Local impact, international standards and best practices.
+
+
-
- <%= t('landing.about.description_3') %>
-
-
\ No newline at end of file
+ <%# Innovation %>
+
+
+
+
+
+
Innovation
+
+ Fostering creative solutions to real-world problems.
+
+
+
+ <%# Excellence %>
+
+
+
+
+
Excellence
+
+ Committed to the highest standards in everything we do.
+
+
+
+
+
+
+ <%# Impact Section %>
+
+
+
+ Our Impact
+
+ Building Tomorrow, Today
+
+
+
+
+
+
5,000+
+
Active Members
+
+
+
<%= chapters.length %>
+
Regional Chapters
+
+
+
<%= Time.now.year - 2016 %>+
+
Years of Community
+
+
+
+
+
+ <%# CTA Section %>
+
+
+
+ Join the Community
+
+
+ Whether you're a beginner or an experienced developer, there's a place for you in ARC.
+ Connect with fellow developers, learn, grow, and build amazing things together.
+
+ <%= link_to new_user_registration_path,
+ class: "inline-flex items-center gap-2 rounded-md bg-red-600 px-8 py-3 text-sm font-semibold text-white hover:bg-red-700 transition-colors" do %>
+ Get Started Today
+
+
+
+ <% end %>
+
+
+
+
diff --git a/app/views/landing/activities.html.erb b/app/views/landing/activities.html.erb
new file mode 100644
index 00000000..b096e487
--- /dev/null
+++ b/app/views/landing/activities.html.erb
@@ -0,0 +1,70 @@
+<% content_for(:title, "Activities") %>
+<% content_for(:description, "From local meetups to continental conferences — discover how ARC brings the Ruby community together.") %>
+<% content_for :full_width do %><% end %>
+
+
+
+ <%# Hero %>
+
+
+ <%= image_tag 'workshop.jpg', alt: "ARC Workshop",
+ class: "absolute inset-0 w-full h-full object-cover" %>
+
+
+
What we do
+
+
+ From local meetups to continental conferences, we create spaces for
+ developers to learn, grow, and build together.
+
+
+
+
+
+ <%# Activity cards %>
+
+
+ <% activities.each do |activity| %>
+
+
+
+ <%= raw activity[:svg_paths] %>
+
+
+
<%= activity[:title] %>
+
<%= activity[:description] %>
+
+ <% end %>
+
+
+ <%# CTA %>
+
+
+ Ready to get involved?
+
+
+ Join thousands of Ruby developers across East Africa. Attend an event, contribute to
+ open source, or start a chapter in your city.
+
+
+ <%= link_to new_user_registration_path,
+ class: "inline-flex items-center gap-2 rounded-md bg-red-600 px-6 py-3 text-sm font-semibold text-white hover:bg-red-700 transition-colors" do %>
+ Join the Community
+
+
+
+ <% end %>
+ <%= link_to chapters_path,
+ class: "inline-flex items-center gap-2 rounded-md border border-zinc-300 dark:border-zinc-600 px-6 py-3 text-sm font-semibold text-zinc-800 dark:text-zinc-200 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors" do %>
+ Find a Chapter
+ <% end %>
+
+
+
+
+
diff --git a/app/views/landing/home/_activities.html.erb b/app/views/landing/home/_activities.html.erb
index 8830f361..c542d26d 100644
--- a/app/views/landing/home/_activities.html.erb
+++ b/app/views/landing/home/_activities.html.erb
@@ -1,12 +1,50 @@
-
- <%= t('landing.index.activities.title') %>
-
-
-
- <% activities.each do |activity| %>
-
- <%= image_tag activity[:image], alt: activity[:title], class: 'hover:scale-105' %>
-
<%= activity[:title] %>
+
+
+
+ <%# Header %>
+
+
+ What we do
+
+
+ Activities
+
+
+ From local meetups to continental conferences, we create spaces for
+ developers to learn, grow, and build together.
+
+
+
+ <%# Activity cards — driven by the activities helper %>
+
+ <% activities.each do |activity| %>
+
+
+
+ <%= raw activity[:svg_paths] %>
+
+
+
<%= activity[:title] %>
+
<%= activity[:description] %>
+
+ <% end %>
- <% end %>
-
+
+ <%# Bottom banner image %>
+
+
+ <%= image_tag 'workshop.jpg', alt: "Ruby Community workshop in action",
+ class: "absolute inset-0 w-full h-full object-cover" %>
+
+
+
+ Bridging the gap between education and industry.
+
+
+
+
+
+
+
diff --git a/app/views/landing/home/_chapters.html.erb b/app/views/landing/home/_chapters.html.erb
index c037cd83..85d1af8d 100644
--- a/app/views/landing/home/_chapters.html.erb
+++ b/app/views/landing/home/_chapters.html.erb
@@ -1,21 +1,59 @@
-
-
- <%= t('landing.index.chapters.title') %>
-
+
+
-
- <% chapters. each do |chapter| %>
- <%= link_to new_user_registration_path, class: 'place-self-center w-72 md:w-48 card border border-red-600 rounded flex flex-col gap-4 hover:scale-95 p-3' do %>
- <%= image_tag chapter[:image], alt: t(chapter[:alt_key]), class: 'pt-2 place-self-center h-16 md:36' %>
-
<%= t(chapter[:country_key]) %>
-
<%= t('landing.index.chapters.join_community') %>
+ <%# Header %>
+
+
+ Our reach
+
+
+ Chapters
+
+
+ Active Ruby communities across East Africa, hosting local meetups and
+ contributing to the global ecosystem.
+
+
+
+ <%# Chapter cards %>
+
+ <% chapters.each do |chapter| %>
+ <%= link_to new_user_registration_path, target: "_blank",
+ class: "group relative flex flex-col justify-between overflow-hidden rounded-2xl border border-zinc-200/50 dark:border-zinc-700/50 bg-white dark:bg-zinc-900 p-6 transition-all hover:border-red-300/50 dark:hover:border-red-500/30 hover:bg-zinc-50 dark:hover:bg-zinc-800/60" do %>
+
+
+
<%= chapter[:country] %>
+
<%= chapter[:community] %>
+
+
+ <% end %>
<% end %>
- <% end %>
+
+
+ <%# Request new chapter %>
+
-
- <%= image_tag('add.png', alt: t('landing.index.chapters.add_chapter_alt'), class: 'pt-2 place-self-center h-16 md:36') %>
- <%= t('landing.index.chapters.request_new_chapter') %>
-
-
-
+
diff --git a/app/views/landing/home/_featured_sponsors.html.erb b/app/views/landing/home/_featured_sponsors.html.erb
index d7529c57..4dd05ed5 100644
--- a/app/views/landing/home/_featured_sponsors.html.erb
+++ b/app/views/landing/home/_featured_sponsors.html.erb
@@ -1,34 +1,77 @@
-
-
-
-
+
diff --git a/app/views/landing/home/_intro.html.erb b/app/views/landing/home/_intro.html.erb
index 58b115e5..7e04742d 100644
--- a/app/views/landing/home/_intro.html.erb
+++ b/app/views/landing/home/_intro.html.erb
@@ -15,27 +15,44 @@
-
-
-
- <%= t('landing.index.intro.title') %>
-
-
-
- <%= t('landing.index.intro.description') %>
-
-
-
- <%= link_to new_user_registration_path do %>
-
- <%= t('common.actions.join_us') %>
-
-
-
-
+
+
+
+ <%= link_to "https://rubyconf.africa/", target: "_blank",
+ class: "mb-6 inline-flex items-center gap-2 rounded-full border border-red-500/30 bg-red-500/10 px-4 py-1.5 text-sm text-red-500 hover:bg-red-500/20 transition-colors" do %>
+
+
+
+
+ RubyConf Africa <%= Time.now.year %>
<% end %>
+
+
+
+
+ A community of 5,000+ developers, entrepreneurs, and designers across
+ East Africa united by their passion for Ruby and open-source software.
+
+
+
+ <%= link_to new_user_registration_path,
+ class: "inline-flex items-center justify-center gap-2 bg-red-600 text-white text-base px-6 py-3 rounded-md font-semibold hover:bg-red-700 transition-colors" do %>
+ Join the Community
+
+
+
+ <% end %>
+
+ <%= link_to landing_about_path,
+ class: "inline-flex items-center justify-center text-base px-6 py-3 rounded-md font-semibold border border-zinc-300 text-zinc-800 hover:bg-zinc-100 dark:border-zinc-600 dark:text-zinc-200 dark:hover:bg-zinc-800 dark:hover:text-white transition-colors" do %>
+ Learn More
+ <% end %>
+
+
@@ -60,4 +77,3 @@
-
\ No newline at end of file
diff --git a/app/views/landing/home/_previous_sponsors.html.erb b/app/views/landing/home/_previous_sponsors.html.erb
index f6a3daa3..9fbbac25 100644
--- a/app/views/landing/home/_previous_sponsors.html.erb
+++ b/app/views/landing/home/_previous_sponsors.html.erb
@@ -1,32 +1,27 @@
-
-
- <%= t('landing.index.sponsors.previous_title') %>
-
+
+
+
+ Previous Sponsors
+
-
-
- <% previous_sponsors.each do |sponsor| %>
- <%= link_to sponsor[:link], target: '_blank' do %>
-
-
- <%= image_tag sponsor[:image], alt: t(sponsor[:alt_key]) %>
+
+ <% previous_sponsors.each do |sponsor| %>
+ <%= link_to sponsor[:link], target: '_blank' do %>
+
+ <%= image_tag sponsor[:image], alt: sponsor[:alt], class: 'max-h-12 w-auto object-contain' %>
-
+ <% end %>
<% end %>
- <% end %>
-
+
-
-
diff --git a/app/views/landing/home/_stats.html.erb b/app/views/landing/home/_stats.html.erb
new file mode 100644
index 00000000..976a8352
--- /dev/null
+++ b/app/views/landing/home/_stats.html.erb
@@ -0,0 +1,20 @@
+
+
+
+
5,000+
+
Members across East Africa
+
+
+
<%= Time.now.year - 2010 %>+
+
Years of Ruby community
+
+
+
<%= chapters.length %>
+
Active chapters
+
+
+
100+
+
Events organized
+
+
+
diff --git a/app/views/landing/home/_who_we_are.html.erb b/app/views/landing/home/_who_we_are.html.erb
index f2ae14b2..816cd7de 100644
--- a/app/views/landing/home/_who_we_are.html.erb
+++ b/app/views/landing/home/_who_we_are.html.erb
@@ -1,39 +1,51 @@
-
-
-
-
-
-
- <%= t('landing.index.who_we_are.title') %>
-
-
- <%= t('landing.index.who_we_are.subtitle') %>
-
+
+
+
+
+ <%# Left — text content %>
+
+
+ Who we are
+
+
+ Empowering African developers through Ruby
+
+
+ African Ruby Community (ARC) is an organization started in 2010 with an outreach of over
+ 5,000 members spread across East Africa. We are a community of developers, entrepreneurs,
+ designers and freelancers united by Ruby technologies and open-source frameworks.
+
+
+ Our community focuses on Ruby technologies and frameworks that are widely used by startups
+ to prototype and carry out proof of concept with a go-to-market strategy. We bridge the gap
+ between education and industry, spurring innovation and growth in contribution to the global
+ economy.
+
+
+
+
+
Monthly
+
Meetups in cities across East Africa
+
+
+
Annual
+
RubyConf Africa conference
+
-
-
-
- <%= t('landing.index.who_we_are.description_1') %>
-
-
- <%= t('landing.index.who_we_are.description_2') %>
-
-
-
- <%= link_to landing_about_path do %>
-
- <%= t('common.actions.read_more') %>
-
-
-
-
- <% end %>
+ <%# Right — stacked images %>
+
+
+ <%= image_tag 'conference.jpg', alt: "Ruby Conference Africa",
+ class: "w-full h-full object-cover" %>
+
+
+ <%= image_tag 'workshop.jpg', alt: "Ruby Community meetup",
+ class: "w-full h-full object-cover" %>
+
-
+
diff --git a/app/views/landing/index.html.erb b/app/views/landing/index.html.erb
index 221554d7..aa361185 100644
--- a/app/views/landing/index.html.erb
+++ b/app/views/landing/index.html.erb
@@ -1,4 +1,5 @@
<%= render 'landing/home/intro' %>
+<%= render 'landing/home/stats' %>
<%# if FeatureFlag.find_by(name: 'events').try(:enabled) %>
<%#= render 'landing/home/coming_up_events' %>
@@ -11,5 +12,3 @@
<%= render 'landing/home/chapters' %>
<%= render 'landing/home/featured_sponsors' %>
-
-<%= render 'landing/home/previous_sponsors' %>
diff --git a/app/views/landing/learn.html.erb b/app/views/landing/learn.html.erb
index 4743dcb7..c64f1db9 100644
--- a/app/views/landing/learn.html.erb
+++ b/app/views/landing/learn.html.erb
@@ -1,158 +1,182 @@
-<% content_for(:title,"Learning Materials") %>
-<% content_for(:description,"A list of ruby and ruby on rails learning resources compiled by the ARC community") %>
-
-
- Featured learning materials
-
+<% content_for(:title, "Learning Materials") %>
+<% content_for(:description, "A curated list of Ruby and Rails learning resources compiled by the ARC community.") %>
+<% content_for :full_width do %><% end %>
-
- Take a look at our list of resources that can help you get up to speed with the Ruby programming
- language from the basic building blocks upto to the various frameworks and tools in the Ruby
- ecosystem. If you want to add your own resources, fork this repo and send in a pull request.
-
+<%# Hero %>
+
+
+ <%= image_tag 'developers.jpg', alt: "Learning Ruby",
+ class: "w-full h-full object-cover" %>
+
+
+
+
+
+
+ Community Curated
+
+
+
+ Resources to help you get up to speed with Ruby — from beginner basics to advanced
+ frameworks. Curated by the ARC community.
+
+
+
+
-
- Ruby
-
+<%# Intro banner %>
+
+
+<%# Resources sections %>
+
+
+
+ <%# ── Ruby ── %>
+
+
+
+
+
Ruby
+
Core language resources and books
+
+
-
+
+ <% [
+ { title: "Little Book of Ruby", url: "http://bedford-computing.co.uk/learning/wp-content/uploads/2015/12/LittleBookOfRuby.pdf", desc: "The fastest, easiest way to learn Ruby from the ground up." },
+ { title: "Ruby Core API Documentation", url: "https://www.ruby-doc.org/core", desc: "Official Ruby core API reference and documentation." },
+ { title: "Download and Install Ruby", url: "https://www.ruby-lang.org", desc: "Get Ruby set up on your machine from ruby-lang.org." },
+ { title: "The Pickaxe Book", url: "http://ruby-doc.com/docs/ProgrammingRuby/", desc: "Programming Ruby — the definitive reference for Ruby." },
+ { title: "Try Ruby in Your Browser", url: "http://tryruby.org/", desc: "Interactive Ruby tutorial — no installation needed." },
+ { title: "The Odin Project — Ruby", url: "https://www.theodinproject.com/paths/full-stack-ruby-on-rails/courses/ruby", desc: "Project-based Ruby learning for serious beginners." },
+ { title: "The Well-Grounded Rubyist", url: "https://www.manning.com/books/the-well-grounded-rubyist-third-edition", desc: "Thorough guide to mastering Ruby's core features." },
+ { title: "CodeAcademy Ruby Track", url: "https://www.codecademy.com/learn/learn-ruby", desc: "Learn to code Ruby interactively in your browser." },
+ { title: "Ruby Koans", url: "http://rubykoans.com/", desc: "Learn Ruby through a series of small exercises." },
+ { title: "Ruby Warrior", url: "https://www.bloc.io/ruby-warrior/", desc: "Game-based learning inspired by Ryan Bates' CLI version." },
+ { title: "Learn To Program", url: "https://pine.fm/LearnToProgram/", desc: "Ground-level programming tutorial by Chris Pine." },
+ { title: "Ruby Monk", url: "https://rubymonk.com/", desc: "Free interactive Ruby programming tutorials." },
+ { title: "Developing Games With Ruby", url: "https://leanpub.com/developing-games-with-ruby/read", desc: "Build games using Ruby — free to read online." },
+ { title: "Why's Poignant Guide to Ruby", url: "https://poignant.guide/", desc: "The legendary quirky intro to Ruby by _why." },
+ { title: "Ruby Community Resources", url: "https://www.ruby-lang.org/en/community/", desc: "The official listing of Ruby community resources." }
+ ].each do |r| %>
+ <%= render partial: 'landing/learn_resource', locals: { resource: r } %>
+ <% end %>
+
+
-
- Ruby Tools
-
+ <%# ── Ruby Tools ── %>
+
+
+
+
+
Ruby Tools
+
Utilities and developer tools for Ruby
+
+
-
-
- Rubular - Interactive Ruby regular
- expression editor
-
-
+
+ <% [
+ { title: "Rubular", url: "http://rubular.com/", desc: "Interactive Ruby regular expression editor — test regexes in real time." }
+ ].each do |r| %>
+ <%= render partial: 'landing/learn_resource', locals: { resource: r } %>
+ <% end %>
+
+
-
- Frameworks
-
+ <%# ── Frameworks ── %>
+
+
+
+
+
Frameworks
+
Jekyll, Rails and more
+
+
-
- Jekyll
-
-
- Rails
-
-
- ◦
- What is
- Ruby and Ruby on Rails?
-
-
- ◦
- Installing
- Rails on Mac OS X
-
-
- ◦
- Installing
- Rails on Ubuntu
-
-
- ◦ Getting
- Started with Rails from
- the official Rails
- guides
-
-
- ◦
- Ruby on Rails Tutorials
- by Michael Hartl
-
-
- ◦ Rails for Zombies -
- Learn Rails the Zombie way
-
-
- ◦ The Odin Project - Full stack Ruby on Rails
+ <%# Jekyll %>
+ Jekyll
+
+ <% [
+ { title: "Jekyll Official Documentation", url: "http://jekyllrb.com", desc: "The official Jekyll static site generator documentation." },
+ { title: "Jekyll with GitHub Pages", url: "https://help.github.com/articles/using-jekyll-with-pages", desc: "Deploy Jekyll sites effortlessly with GitHub Pages." }
+ ].each do |r| %>
+ <%= render partial: 'landing/learn_resource', locals: { resource: r } %>
+ <% end %>
+
+
+ <%# Rails %>
+ Ruby on Rails
+
+ <% [
+ { title: "What is Ruby on Rails?", url: "http://railsapps.github.io/what-is-ruby-rails.html", desc: "A clear explanation of Ruby on Rails for beginners." },
+ { title: "Installing Rails on Mac OS X", url: "http://www.createdbypete.com/articles/ruby-on-rails-development-setup-for-mac-osx/", desc: "Step-by-step setup guide for Mac developers." },
+ { title: "Installing Rails on Ubuntu", url: "http://railsapps.github.io/installrubyonrails-ubuntu.html", desc: "Step-by-step setup guide for Ubuntu developers." },
+ { title: "Getting Started with Rails", url: "http://guides.rubyonrails.org/getting_started.html", desc: "The official Rails getting started guide." },
+ { title: "Ruby on Rails Tutorial", url: "http://ruby.railstutorial.org/", desc: "Comprehensive tutorial by Michael Hartl." },
+ { title: "Rails for Zombies", url: "http://railsforzombies.org/", desc: "Learn Rails the Zombie way — fun and interactive." },
+ { title: "The Odin Project — Full Stack", url: "http://railsforzombies.org/", desc: "Full stack Ruby on Rails curriculum." },
+ { title: "Agile Web Development with Rails", url: "http://pragprog.com/titles/rails4/agile-web-development-with-rails", desc: "The pragmatic programmer's guide to Rails." },
+ { title: "RubyMine IDE", url: "http://www.jetbrains.com/ruby/", desc: "The smart Ruby on Rails IDE by JetBrains." },
+ { title: "Railscasts", url: "http://railscasts.com/", desc: "Screencasts covering a wide range of Rails topics." },
+ { title: "GoRails", url: "https://gorails.com/", desc: "More Rails screencasts — from beginner to advanced." },
+ { title: "Rails Books on Amazon", url: "http://www.amazon.com/", desc: "Browse Ruby on Rails books available on Amazon." }
+ ].each do |r| %>
+ <%= render partial: 'landing/learn_resource', locals: { resource: r } %>
+ <% end %>
+
+
+
+
+
-
-
- ◦
- Agile
- Web Development with Rails
-
-
- ◦ RubyMine -
- Ruby on Rails IDE
-
-
- ◦ Others
- Ruby on Rails books on Amazon
-
-
- ◦ Railscasts
-
-
- ◦ Go Rails -
- More Rails Screencasts
-
-
-
-
+<%# CTA %>
+
+
+
+ Know a great resource?
+
+
+ Help the community grow. Fork the repo and submit a pull request to add your favourite
+ Ruby learning materials.
+
+
+
+
+
+ Submit a Resource
+
+
diff --git a/app/views/layouts/_flash_messages.html.erb b/app/views/layouts/_flash_messages.html.erb
index 3dfddd61..99b4b091 100644
--- a/app/views/layouts/_flash_messages.html.erb
+++ b/app/views/layouts/_flash_messages.html.erb
@@ -1,25 +1,45 @@
-
- <% if notice || alert %>
- <%= content_tag :div,
- class: "alert #{ alert ? 'alert-error' : 'alert-success'} alert_custom_class",
- data: { controller: 'removals',
- action: 'animationend->removals#remove click->removals#remove_on_click' } do %>
+<% if notice || alert %>
+
+
-
- <% if notice %>
-
-
- <% elsif alert %>
-
-
+ <%# Icon %>
+ <% if alert %>
+
+
+
+
+ <% else %>
+
+
+
<% end %>
- <%= content_tag :span, notice || alert %>
- <% end %>
- <% end %>
-
+ <%# Message %>
+
+
<%= notice || alert %>
+
+
+ <%# Dismiss button %>
+
+
+
+
+
+
+
+
+<% end %>
diff --git a/app/views/layouts/_footer.html.erb b/app/views/layouts/_footer.html.erb
index fa0def54..f1fbfbac 100644
--- a/app/views/layouts/_footer.html.erb
+++ b/app/views/layouts/_footer.html.erb
@@ -1,27 +1,19 @@
-
-
- <%= link_to root_path, class: "flex justify-center md:justify-end md:pr-20" do %>
- <%= image_tag('arc_logo_coloured.png', alt: "Community Logo", class: 'w-32 md:w-48') %>
- <% end %>
-
-
- <%= link_to t('footer.home'), root_path %>
- <% if FeatureFlag.find_by(name: 'events').try(:enabled) %>
- <%= link_to t('footer.events'), '#' %>
- <% end %>
+
- <%= t('footer.copyright', year: Date.today.year) %>
+ <%# Bottom bar %>
+
+
+ © <%= Date.today.year %> African Ruby Community. All rights reserved.
+
+
+ Built with Ruby, powered by community.
+
+
+
+
diff --git a/app/views/layouts/_navbar.html.erb b/app/views/layouts/_navbar.html.erb
index 488bd430..cc228e42 100644
--- a/app/views/layouts/_navbar.html.erb
+++ b/app/views/layouts/_navbar.html.erb
@@ -1,42 +1,11 @@
-
-
-
-
-
-
-
-
-
-
- <%= link_to t('navigation.home'), root_path %>
- <%= link_to t('navigation.about_arc'), landing_about_path %>
-
- <% if FeatureFlag.find_by(name: 'events').try(:enabled) %>
- <%= link_to t('navigation.events'), events_path %>
- <% end %>
-
- <%# Conferences removed from project %>
-
- <%= link_to t('navigation.chapters'), chapters_path %>
-
- <% if FeatureFlag.find_by(name: 'projects')&.enabled %>
- <%= link_to t('navigation.projects'), projects_path %>
- <% end %>
-
- <% if FeatureFlag.find_by(name: 'learning_materials')&.enabled %>
- <%= link_to t('navigation.learning_materials'), learning_materials_path %>
- <% end %>
-
- <% if user_signed_in? %>
- <%= button_to t('navigation.sign_out'), destroy_user_session_path, method: :delete %>
- <% else %>
- <%= link_to t('navigation.sign_up'), new_user_registration_path %>
- <%= link_to t('navigation.sign_in'), new_user_session_path %>
- <% end %>
-
-
+
+
+
<%= link_to root_path do %>
<%= t('navigation.community_name') %>
@@ -69,73 +38,103 @@
<% end %>
<% if user_signed_in? %>
-
-
- <% if current_user.organization_admin? %>
-
-
-
-
-
-
-
-
-
-
-
-
<%= t('navigation.settings') %>
-
-
-
-
- <%= link_to t('navigation.countries'), countries_path %>
-
-
- <%= link_to t('navigation.chapters'), chapters_path %>
-
-
-
- <% end %>
-
-
-
-
-
-
-
+ <% if current_user.organization_admin? %>
+
+
+ Settings
-
-
- <%= link_to t('navigation.update_profile'), edit_user_registration_path %>
-
+
+ <%= link_to 'Countries', countries_path, class: "text-sm text-zinc-700 dark:text-zinc-300 hover:text-red-600" %>
+ <%= link_to 'Chapters', chapters_path, class: "text-sm text-zinc-700 dark:text-zinc-300 hover:text-red-600" %>
-
- <%= button_to t('navigation.sign_out'), destroy_user_session_path, method: :delete, class: "whitespace-nowrap text-sm font-small text-gray-500
- hover:text-red-700 ml-8" %>
+ <% end %>
+
+
+ Account
+
+
+ <%= link_to 'Update profile', edit_user_registration_path, class: "text-sm text-zinc-700 dark:text-zinc-300 hover:text-red-600" %>
+
+ <%= button_to "Sign out", destroy_user_session_path, method: :delete,
+ class: "rounded-md px-3 py-1.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-white" %>
<% else %>
-
- <%= link_to new_user_session_path do %>
- <%= t('navigation.sign_in') %>
- <% end %>
-
+ <%= link_to "Sign in", new_user_session_path,
+ class: "rounded-md px-3 py-1.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800 dark:hover:text-white" %>
+ <%= link_to "Join Us", new_user_registration_path,
+ class: "rounded-md bg-red-600 px-3 py-1.5 text-sm font-medium text-white transition-colors hover:bg-red-700" %>
<% end %>
+
+ <%# Theme toggle + hamburger (mobile) %>
+
+ <%# Theme toggle - visible on all screen sizes (sun/moon icon) %>
+
+
+
+
+
+
+
+
+
+
+ <%# Hamburger (mobile only) %>
+
+
+
+
+
+
+
+
+
+
+
+
+ <%# Mobile menu panel %>
+
+
+ <%= link_to 'Home', root_path,
+ class: "rounded-lg px-3 py-2.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/60 dark:hover:text-white",
+ data: { action: "click->navbar#close" } %>
+ <%= link_to 'About', landing_about_path,
+ class: "rounded-lg px-3 py-2.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/60 dark:hover:text-white",
+ data: { action: "click->navbar#close" } %>
+ <%= link_to 'Projects', projects_path,
+ class: "rounded-lg px-3 py-2.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/60 dark:hover:text-white",
+ data: { action: "click->navbar#close" } %>
+ <%= link_to 'Chapters', chapters_path,
+ class: "rounded-lg px-3 py-2.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/60 dark:hover:text-white",
+ data: { action: "click->navbar#close" } %>
+ <%= link_to 'Learning Materials', landing_learn_path,
+ class: "rounded-lg px-3 py-2.5 text-sm font-medium text-zinc-600 transition-colors hover:bg-zinc-100 hover:text-zinc-900 dark:text-zinc-400 dark:hover:bg-zinc-800/60 dark:hover:text-white",
+ data: { action: "click->navbar#close" } %>
+
+
+ <% if user_signed_in? %>
+ <%= button_to "Sign out", destroy_user_session_path, method: :delete,
+ class: "w-full rounded-md border border-zinc-200 dark:border-zinc-700 px-3 py-2 text-sm font-medium text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors" %>
+ <% else %>
+ <%= link_to "Sign in", new_user_session_path,
+ class: "rounded-md border border-zinc-200 dark:border-zinc-700 px-3 py-2 text-sm font-medium text-center text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 transition-colors" %>
+ <%= link_to "Join Us", new_user_registration_path,
+ class: "rounded-md bg-red-600 px-3 py-2 text-sm font-medium text-center text-white hover:bg-red-700 transition-colors" %>
+ <% end %>
+
+
-
\ No newline at end of file
+
+
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index dee18a8d..e3784fb8 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -17,14 +17,13 @@
<%= Sentry.get_trace_propagation_meta.html_safe %>
-
-
+
+
+ <%= render 'layouts/navbar' %>
- <%= render 'layouts/navbar' %>
-
-
- <%= yield %>
-
+
+ <%= yield %>
+
<%= render 'layouts/flash_messages' %>
<%= render 'layouts/footer' %>
diff --git a/app/views/layouts/projects.html.erb b/app/views/layouts/projects.html.erb
deleted file mode 100644
index 9b871c45..00000000
--- a/app/views/layouts/projects.html.erb
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
-
Projects - African Ruby Community
-
- <%= csrf_meta_tags %>
- <%= csp_meta_tag %>
- <%= favicon_link_tag 'favicon.ico' %>
-
-
- <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
- <%= javascript_include_tag "https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit", "data-turbo-track": "reload", defer: true %>
- <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
- <%= Sentry.get_trace_propagation_meta.html_safe %>
-
-
-
-
- <%= render 'layouts/navbar' %>
-
-
- <%= yield %>
-
-
- <%= render 'layouts/flash_messages' %>
- <%= render 'layouts/footer' %>
-
-
-
diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.erb
index 0c436dd2..ef2c7342 100644
--- a/app/views/projects/index.html.erb
+++ b/app/views/projects/index.html.erb
@@ -19,18 +19,39 @@
<% end %>
-
-
-
-
-
- <%= render 'featured_project', featured_project: @featured_project %>
-
-
- <%= render 'projects', projects: @projects, pagy: @pagy %>
-
-
-
+ <%# Empty state — shown by JS when no results match %>
+
+
+
+
+
No projects match your search.
+
Try a different keyword or clear the search.
+
+
<%# end content div %>
+<%# end hero+grid section %>
+<%# Contribute CTA %>
+
+
+
+ Have a Project to Share?
+
+
+ Built something awesome? We'd love to showcase your Ruby project to the community.
+ Submit your project and connect with other developers.
+
+ <%= link_to new_user_registration_path,
+ class: "inline-flex items-center gap-2 rounded-md bg-red-600 px-8 py-3 text-sm font-semibold text-white hover:bg-red-700 transition-colors" do %>
+ Submit Your Project
+
+
+
+ <% end %>
+
+
diff --git a/config/routes.rb b/config/routes.rb
index dd8dd669..7c279b1a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -21,6 +21,7 @@
# Defines the root path route ("/")
root 'landing#index'
- get 'about_us', to: 'landing#about', as: :landing_about
- get 'learn', to: 'landing#learn', as: :landing_learn
+ get 'about_us', to: 'landing#about', as: :landing_about
+ get 'activities', to: 'landing#activities', as: :landing_activities
+ get 'learn', to: 'landing#learn', as: :landing_learn
end
diff --git a/db/schema.rb b/db/schema.rb
index 7c9b49d3..1ddfcc7f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -53,6 +53,16 @@
t.index ["name"], name: "index_chapters_on_name", unique: true
end
+ create_table "conferences", force: :cascade do |t|
+ t.datetime "created_at", null: false
+ t.datetime "end_date"
+ t.string "location"
+ t.datetime "start_date"
+ t.integer "status", default: 0
+ t.string "title", null: false
+ t.datetime "updated_at", null: false
+ end
+
create_table "countries", force: :cascade do |t|
t.datetime "created_at", null: false
t.string "name"
@@ -93,11 +103,12 @@
create_table "learning_materials", force: :cascade do |t|
t.datetime "created_at", null: false
- t.boolean "featured"
- t.integer "level"
- t.string "link"
+ t.text "description"
+ t.boolean "featured", default: false, null: false
+ t.integer "level", default: 0, null: false
+ t.string "link", null: false
t.string "thumbnail"
- t.string "title"
+ t.string "title", null: false
t.datetime "updated_at", null: false
t.index ["featured"], name: "index_learning_materials_on_featured"
t.index ["level"], name: "index_learning_materials_on_level"
diff --git a/tailwind.config.js b/tailwind.config.js
index 8079a356..f512734d 100644
--- a/tailwind.config.js
+++ b/tailwind.config.js
@@ -1,4 +1,5 @@
module.exports = {
+ darkMode: 'class',
content: [
'./app/views/**/*.html.erb',
'./app/helpers/**/*.rb',