From 43bc54fcacd6452bea54e8baf075ea276556e001 Mon Sep 17 00:00:00 2001 From: AFornio Date: Fri, 1 May 2026 16:35:29 -0300 Subject: [PATCH] Feat: add community view with open source projects and gems --- _data/community.yml | 564 +++++++++++++++++++++++++++++++++ _includes/default_header.html | 1 + _includes/project_card.html | 40 +++ _layouts/community.html | 58 ++++ _sass/community.scss | 107 +++++++ _sass/project-card.scss | 124 ++++++++ assets/css/styles.scss | 2 +- assets/images/medal-bronze.svg | 6 + assets/images/medal-gold.svg | 9 + assets/images/medal-silver.svg | 6 + assets/js/community.js | 79 +++++ community.html | 4 + 12 files changed, 999 insertions(+), 1 deletion(-) create mode 100644 _data/community.yml create mode 100644 _includes/project_card.html create mode 100644 _layouts/community.html create mode 100644 _sass/community.scss create mode 100644 _sass/project-card.scss create mode 100644 assets/images/medal-bronze.svg create mode 100644 assets/images/medal-gold.svg create mode 100644 assets/images/medal-silver.svg create mode 100644 assets/js/community.js create mode 100644 community.html diff --git a/_data/community.yml b/_data/community.yml new file mode 100644 index 0000000..d607621 --- /dev/null +++ b/_data/community.yml @@ -0,0 +1,564 @@ +# Community Ruby/Rails open source projects by speakers and contributors from our community. + +last_updated: 2026-05-01 + +projects: + - github_user: guillermoap + name: notion_rails + description: Notion HTML renderer for Rails + url: https://github.com/guillermoap/notion_rails + stars: 0 + topics: [] + + - github_user: guillermoap + name: notion_to_html + description: Notion HTML renderer for Ruby and Rails + url: https://github.com/guillermoap/notion_to_html + stars: 9 + topics: [notion, notion-blog, rails, renderer, ruby, ruby-on-rails] + + - github_user: EmilioCristalli + name: test_db_selector + description: "" + url: https://github.com/EmilioCristalli/test_db_selector + stars: 0 + topics: [] + + - github_user: JulianPasquale + name: fudo-rack + description: Rack app to solve Fudo's challenge + url: https://github.com/JulianPasquale/fudo-rack + stars: 0 + topics: [] + + - github_user: JulianPasquale + name: venmo-api + description: Venmo is a mobile payment service which allows friends to transfer money to each other. + url: https://github.com/JulianPasquale/venmo-api + stars: 0 + topics: [] + + - github_user: jpbalarini + name: rails-starter-docker + description: A Ruby on Rails with docker integration template + url: https://github.com/jpbalarini/rails-starter-docker + stars: 0 + topics: [docker, nginx, rails, ruby, starter, starter-template, template] + + - github_user: jpbalarini + name: twitter_image_downloader + description: A script that allows you to download the images of you Twitter feed + url: https://github.com/jpbalarini/twitter_image_downloader + stars: 0 + topics: [] + + - github_user: jpbalarini + name: uruguayan_exchange_rates + description: Uruguayan exchange rates. Data is taken from Banco Republica + url: https://github.com/jpbalarini/uruguayan_exchange_rates + stars: 4 + topics: [] + + - github_user: juan-apa + name: hyperui-view_component + description: "" + url: https://github.com/juan-apa/hyperui-view_component + stars: 4 + topics: [] + + - github_user: santib + name: ar2dto + description: Convert ActiveRecord objects to DTOs + url: https://github.com/santib/ar2dto + stars: 56 + topics: [] + + - github_user: santib + name: chaotic_order + description: Add random order to queries that do not have a specific order + url: https://github.com/santib/chaotic_order + stars: 18 + topics: [] + + - github_user: santib + name: railsconf2021 + description: Sample app for my RailsConf 2021 talk + url: https://github.com/santib/railsconf2021 + stars: 15 + topics: [] + + - github_user: elcuervo + name: airplay + description: Airplay bindings to Ruby + url: https://github.com/elcuervo/airplay + stars: 1065 + topics: [] + + - github_user: elcuervo + name: cuba-sugar + description: Give cuba some sugar! + url: https://github.com/elcuervo/cuba-sugar + stars: 20 + topics: [] + + - github_user: elcuervo + name: flag + description: Simple feature flags + url: https://github.com/elcuervo/flag + stars: 11 + topics: [] + + - github_user: elcuervo + name: limelight_video + description: Limelight video platform ruby client + url: https://github.com/elcuervo/limelight_video + stars: 5 + topics: [] + + - github_user: elcuervo + name: firma + description: Adds a secure signature to pdf + url: https://github.com/elcuervo/firma + stars: 4 + topics: [] + + - github_user: elcuervo + name: dry-types-json-schema + description: "" + url: https://github.com/elcuervo/dry-types-json-schema + stars: 3 + topics: [] + + - github_user: elcuervo + name: gliner + description: Ruby inference wrapper for the GLiNER2 ONNX model. + url: https://github.com/elcuervo/gliner + stars: 2 + topics: [onnx] + + - github_user: elcuervo + name: cachoo + description: "" + url: https://github.com/elcuervo/cachoo + stars: 2 + topics: [] + + - github_user: MaicolBen + name: twilio_mock + description: Mock Twilio gem for Ruby + url: https://github.com/MaicolBen/twilio_mock + stars: 27 + topics: [hacktoberfest, mocking, test, twilio] + + - github_user: delbetu + name: hexa + description: Hexagonal Ruby Backend + url: https://github.com/delbetu/hexa + stars: 2 + topics: [graphql, hacktoberfest, hexagonal-architecture, ruby, use-cases] + + - github_user: delbetu + name: todo-app + description: Frontend and backend solution for a simple todo app. + url: https://github.com/delbetu/todo-app + stars: 5 + topics: [backbonejs, demo-code, jquery, jwt, rails-api, rspec, underscorejs, webpack] + + - github_user: delbetu + name: ruby_games + description: A set of educative games for kids written in Ruby + url: https://github.com/delbetu/ruby_games + stars: 0 + topics: [] + + - github_user: ignacio-chiazzo + name: ruby_whatsapp_sdk + description: A lightweight, efficient Ruby gem for interacting with Whatsapp Cloud API. + url: https://github.com/ignacio-chiazzo/ruby_whatsapp_sdk + stars: 203 + topics: [bot, chat, chatbots, cloud-api, ruby, ruby-gem, sdk, whatsapp, whatsapp-api] + + - github_user: ignacio-chiazzo + name: ruby_on_rails_whatsapp_example + description: Ruby on Rails example application that communicates with Whatsapp + url: https://github.com/ignacio-chiazzo/ruby_on_rails_whatsapp_example + stars: 15 + topics: [hacktoberfest, whatsapp] + + - github_user: ignacio-chiazzo + name: ruby-minitest-analyzer + description: "Don't run duplicated test in Minitest! Analyzes Ruby Minitest repeated tests health." + url: https://github.com/ignacio-chiazzo/ruby-minitest-analyzer + stars: 6 + topics: [minitest, rails, ruby, testing] + + - github_user: ignacio-chiazzo + name: Cursor-vs-Page-Pagination-in-Shopify + description: Compare Shopify REST Admin API using Relative Cursor vs Page based pagination. + url: https://github.com/ignacio-chiazzo/Cursor-vs-Page-Pagination-in-Shopify + stars: 2 + topics: [pagination, rest-api, shopify] + + - github_user: letiesperon + name: concurrent_execution_queue_poc + description: Quick proof of concept for Ruby Concurrent Execution Queue. + url: https://github.com/letiesperon/concurrent_execution_queue_poc + stars: 4 + topics: [concurrency, queue, ruby] + + - github_user: letiesperon + name: ruby-patterns + description: Ruby Patterns Applied + url: https://github.com/letiesperon/ruby-patterns + stars: 2 + topics: [] + + - github_user: AFornio + name: UruguayAPI + description: Ruby API with Uruguayan public data + url: https://github.com/AFornio/UruguayAPI + stars: 47 + topics: [] + + - github_user: mauricioszabo + name: arel_operators + description: "Operators |, and, - for AREL." + url: https://github.com/mauricioszabo/arel_operators + stars: 7 + topics: [] + + - github_user: mauricioszabo + name: jasper_on_rails + description: Sistema de relatórios - integração do Jasper com Rails + url: https://github.com/mauricioszabo/jasper_on_rails + stars: 9 + topics: [] + + - github_user: oboxodo + name: aprende_a_programar + description: Traducción al español del tutorial de Chris Pine "Learn to Program" + url: https://github.com/oboxodo/aprende_a_programar + stars: 11 + topics: [] + + - github_user: oboxodo + name: acts_as_extensible + description: Delegates columns of a has_one association and creates the proxy methods in the caller + url: https://github.com/oboxodo/acts_as_extensible + stars: 2 + topics: [] + + - github_user: sethhorsley + name: ruby-clsx + description: "" + url: https://github.com/sethhorsley/ruby-clsx + stars: 12 + topics: [] + + - github_user: marcoroth + name: bubbletea-ruby + description: "A powerful TUI framework for Ruby, based on Charm's bubbletea." + url: https://github.com/marcoroth/bubbletea-ruby + stars: 136 + topics: [] + + - github_user: marcoroth + name: gem.sh + description: Beautiful documentation for any Ruby gem. + url: https://github.com/marcoroth/gem.sh + stars: 133 + topics: [doc, docs, documentation, gem, ruby, rubygem] + + - github_user: marcoroth + name: boxdrop + description: Dropbox Clone built with StimulusReflex + url: https://github.com/marcoroth/boxdrop + stars: 85 + topics: [dropbox, rails, ruby, stimulus, stimulus-reflex] + + - github_user: marcoroth + name: difftastic-ruby + description: A Ruby interface and wrapper for the wonderful Difftastic CLI tool. + url: https://github.com/marcoroth/difftastic-ruby + stars: 72 + topics: [diffing, difftastic, ruby] + + - github_user: marcoroth + name: bubbles-ruby + description: "TUI components for Bubble Tea, based on Charm's Bubbles." + url: https://github.com/marcoroth/bubbles-ruby + stars: 67 + topics: [] + + - github_user: marcoroth + name: gum-ruby + description: "Ruby wrapper for Charm's Gum. A tool for glamorous scripts." + url: https://github.com/marcoroth/gum-ruby + stars: 59 + topics: [] + + - github_user: marcoroth + name: huh-ruby + description: "Build Beautiful Terminal forms and prompts in Ruby, based on Charm's Huh." + url: https://github.com/marcoroth/huh-ruby + stars: 45 + topics: [] + + - github_user: marcoroth + name: harmonica-ruby + description: "A simple, physics-based animation library for Ruby, based on Charm's Harmonica." + url: https://github.com/marcoroth/harmonica-ruby + stars: 41 + topics: [] + + - github_user: marcoroth + name: bubblezone-ruby + description: Helper utility for Bubble Tea, allowing easy mouse event tracking in terminal applications. + url: https://github.com/marcoroth/bubblezone-ruby + stars: 37 + topics: [] + + - github_user: marcoroth + name: rubocop-gradual + description: Gradually improve your code with RuboCop + url: https://github.com/skryukov/rubocop-gradual + stars: 38 + topics: [linter, rubocop, ruby] + + - github_user: marcoroth + name: glamour-ruby + description: "Stylesheet-based Markdown Rendering for Ruby, based on Charm's glamour." + url: https://github.com/marcoroth/glamour-ruby + stars: 50 + topics: [] + + - github_user: marcoroth + name: lightpanda-ruby + description: Ruby client for the Lightpanda headless browser via CDP. + url: https://github.com/marcoroth/lightpanda-ruby + stars: 19 + topics: [] + + - github_user: marcoroth + name: easy_enum + description: Turn any Ruby class in an easy to use enum. + url: https://github.com/marcoroth/easy_enum + stars: 14 + topics: [enum, ruby] + + - github_user: marcoroth + name: charm-ruby + description: The full Charm terminal toolkit for Ruby + url: https://github.com/marcoroth/charm-ruby + stars: 6 + topics: [charm, cli, ruby] + + - github_user: marcoroth + name: cable-streams-rails + description: Rails companion gem for the cable-streams NPM package + url: https://github.com/marcoroth/cable-streams-rails + stars: 6 + topics: [hotwire, rails, ruby, turbo] + + - github_user: marcoroth + name: dependabot-bump-together-action + description: GitHub Action to bump multiple dependencies with dependabot in a single pull request + url: https://github.com/marcoroth/dependabot-bump-together-action + stars: 8 + topics: [dependabot, github-action] + + - github_user: skryukov + name: turbo-mount + description: Use React, Vue, Svelte, and other components with Hotwire + url: https://github.com/skryukov/turbo-mount + stars: 472 + topics: [hotwire, rails, react, stimulusjs, svelte, turbo, vue] + + - github_user: skryukov + name: typelizer + description: Define once in Ruby. Generate everywhere in TypeScript. + url: https://github.com/skryukov/typelizer + stars: 231 + topics: [rails, ruby, typescript] + + - github_user: skryukov + name: skooma + description: Skooma is a Ruby library for validating API implementations against OpenAPI documents. + url: https://github.com/skryukov/skooma + stars: 202 + topics: [openapi, rspec, ruby] + + - github_user: skryukov + name: inertia_rails-contrib + description: A collection of extensions and developer tools for Inertia's Rails adapter. + url: https://github.com/skryukov/inertia_rails-contrib + stars: 165 + topics: [inertiajs, rails] + + - github_user: skryukov + name: rubocop-gradual + description: Gradually improve your code with RuboCop + url: https://github.com/skryukov/rubocop-gradual + stars: 38 + topics: [linter, rubocop, ruby] + + - github_user: skryukov + name: alba-inertia + description: Seamless integration between Alba and Inertia Rails. + url: https://github.com/skryukov/alba-inertia + stars: 30 + topics: [inertiajs, rails] + + - github_user: skryukov + name: json_skooma + description: JSONSkooma is a Ruby library for validating JSONs against JSON Schemas. + url: https://github.com/skryukov/json_skooma + stars: 29 + topics: [json-schema, ruby] + + - github_user: skryukov + name: openapi_rspec + description: Test your API against OpenApi v3 documentation + url: https://github.com/skryukov/openapi_rspec + stars: 13 + topics: [api, openapi, rspec, ruby] + + - github_user: skryukov + name: izzy + description: "" + url: https://github.com/skryukov/izzy + stars: 12 + topics: [] + + - github_user: skryukov + name: uri-idna + description: A IDNA2008, UTS46 and Punycode implementation in pure Ruby + url: https://github.com/skryukov/uri-idna + stars: 16 + topics: [ruby] + + - github_user: palkan + name: logidze + description: Database changes log for Rails + url: https://github.com/palkan/logidze + stars: 1681 + topics: [activerecord, postgresql, rails, versioning] + + - github_user: palkan + name: action_policy + description: Authorization framework for Ruby/Rails applications + url: https://github.com/palkan/action_policy + stars: 1556 + topics: [authorization, rails, ruby] + + - github_user: palkan + name: isolator + description: Detect non-atomic interactions within DB transactions + url: https://github.com/palkan/isolator + stars: 1102 + topics: [activerecord, developer-tools, rails, testing-tools] + + - github_user: palkan + name: anyway_config + description: Configuration library for Ruby gems and applications + url: https://github.com/palkan/anyway_config + stars: 886 + topics: [configuration, rails, ruby] + + - github_user: palkan + name: active_delivery + description: Ruby framework for keeping all types of notifications in one place + url: https://github.com/palkan/active_delivery + stars: 653 + topics: [mailers, notifications, rails, ruby] + + - github_user: palkan + name: n_plus_one_control + description: RSpec and Minitest matchers to prevent N+1 queries problem + url: https://github.com/palkan/n_plus_one_control + stars: 577 + topics: [database-testing, minitest, rspec, ruby, testing] + + - github_user: palkan + name: litecable + description: Lightweight Action Cable implementation (Rails-free) + url: https://github.com/palkan/litecable + stars: 303 + topics: [actioncable, sinatra, websockets] + + - github_user: palkan + name: action-cable-testing + description: Action Cable testing utils + url: https://github.com/palkan/action-cable-testing + stars: 213 + topics: [actioncable, minitest, rails, rspec, testing] + + - github_user: palkan + name: acli + description: Action Cable command-line client + url: https://github.com/palkan/acli + stars: 233 + topics: [actioncable, cli, rails, websockets] + + - github_user: palkan + name: active_event_store + description: Rails Event Store in a more Rails way + url: https://github.com/palkan/active_event_store + stars: 204 + topics: [event-sourcing, rails] + + - github_user: palkan + name: action_policy-graphql + description: Action Policy integration for GraphQL + url: https://github.com/palkan/action_policy-graphql + stars: 149 + topics: [authorization, graphql, ruby] + + - github_user: palkan + name: engems + description: Rails component-based architecture on top of engines and gems + url: https://github.com/palkan/engems + stars: 138 + topics: [architecture, engines, rails] + + - github_user: palkan + name: abstract_notifier + description: ActionMailer-like interface for any type of notifications + url: https://github.com/palkan/abstract_notifier + stars: 115 + topics: [notifications, rails, ruby] + + - github_user: palkan + name: influxer + description: InfluxDB ActiveRecord-style + url: https://github.com/palkan/influxer + stars: 117 + topics: [influxdb, rails, ruby] + + - github_user: palkan + name: pgrel + description: ActiveRecord extension for querying hstore and jsonb + url: https://github.com/palkan/pgrel + stars: 93 + topics: [activerecord, hstore, jsonb, postgresql] + + - github_user: palkan + name: downstream + description: Straightforward way to implement communication between Rails Engines using Publish-Subscribe pattern. + url: https://github.com/palkan/downstream + stars: 75 + topics: [event-driven-architecture, rails, rails-engines, ruby] + + - github_user: palkan + name: faqueue + description: Researching background jobs fairness + url: https://github.com/palkan/faqueue + stars: 68 + topics: [] + + - github_user: jmbejar + name: todo-rails-api-backbone-backend + description: Example backend implemented with Rails API to be used with a backbone frontend app + url: https://github.com/jmbejar/todo-rails-api-backbone-backend + stars: 19 + topics: [] diff --git a/_includes/default_header.html b/_includes/default_header.html index 1b405eb..6b584b4 100644 --- a/_includes/default_header.html +++ b/_includes/default_header.html @@ -15,6 +15,7 @@

Sé parte_

{{ service[0] }} {% endfor %} + Community diff --git a/_includes/project_card.html b/_includes/project_card.html new file mode 100644 index 0000000..9bb09ae --- /dev/null +++ b/_includes/project_card.html @@ -0,0 +1,40 @@ +
+ + {% if medal_name != "" %} +
+ Rank {{ project_rank }} +
+ {% endif %} + +
+
+

+ {{ project.name }} +

+ ★ {{ project.stars }} +
+ + {% if project.description != "" %} +

{{ project.description }}

+ {% endif %} + +
+ {% if person.github %} + {{ person.name }} + {% endif %} + {{ person.name | default: project.github_user }} + + {% if project.topics.size > 0 %} +
+ {% for topic in project.topics limit: 4 %} + {{ topic }} + {% endfor %} +
+ {% endif %} +
+
+
diff --git a/_layouts/community.html b/_layouts/community.html new file mode 100644 index 0000000..9fac6f0 --- /dev/null +++ b/_layouts/community.html @@ -0,0 +1,58 @@ + + + {% include head.html %} + + + {% include nav.html %} + +
+
+
+

Community

+

Ruby & Rails open source projects built by our community

+ +
+ + +
+ + + +
+
+ +

Last updated: {{ site.data.community.last_updated | date: "%B %-d, %Y" }}

+
+ +
+ {% assign projects_sorted = site.data.community.projects | sort: "stars" | reverse %} + {% assign medals = "medal-gold,medal-silver,medal-bronze" | split: "," %} + + {% for project in projects_sorted %} + {% assign person = nil %} + {% for p in site.data.people %} + {% if p[1].github == project.github_user %} + {% assign person = p[1] %} + {% endif %} + {% endfor %} + + {% capture search_text %}{{ project.name }} {{ project.description }} {{ project.github_user }} {{ person.name }} {{ project.topics | join: ' ' }}{% endcapture %} + + {% assign medal_name = "" %} + {% assign medal_class = "" %} + {% if forloop.index <= 3 %} + {% assign medal_name = medals[forloop.index0] %} + {% assign medal_class = "project--medal project--" | append: medal_name %} + {% endif %} + + {% assign project_rank = forloop.index %} + {% include project_card.html %} + {% endfor %} +
+
+
+ + {% include footer.html %} + + + diff --git a/_sass/community.scss b/_sass/community.scss new file mode 100644 index 0000000..6d0d8e2 --- /dev/null +++ b/_sass/community.scss @@ -0,0 +1,107 @@ +#view-community { + h2 { + overflow-wrap: break-word; + + @media (max-width: 480px) { + font-size: 1.75rem; + } + } + + .community-subtitle { + color: #2E2E2E; + margin-bottom: 1.5rem; + opacity: 0.7; + } + + .community-controls { + display: flex; + flex-direction: column; + gap: 1rem; + } + + .community-search { + background-color: #F6EEEC; + border: 3px solid #2E2E2E; + box-shadow: 6px 6px 0 #3967D1; + color: #3967D1; + font: 700 1rem 'Syncopate', sans-serif; + letter-spacing: 0.05em; + padding: 1rem 1.25rem; + text-transform: uppercase; + transition: box-shadow 0.15s ease, transform 0.15s ease; + width: 100%; + + &::placeholder { + color: #3967D1; + opacity: 0.5; + } + + &:focus { + box-shadow: 6px 6px 0 #FFC24D; + outline: none; + transform: translate(-2px, -2px); + } + } + + .community-sort { + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + + .sort-btn { + background-color: transparent; + border: 3px solid #2E2E2E; + box-shadow: 4px 4px 0 #2E2E2E; + cursor: pointer; + font: 700 0.75rem 'Syncopate', sans-serif; + letter-spacing: 0.05em; + padding: 0.5rem 1rem; + text-transform: uppercase; + transition: box-shadow 0.15s ease, transform 0.15s ease; + white-space: nowrap; + + @media (max-width: 480px) { + font-size: 0.65rem; + letter-spacing: 0.02em; + padding: 0.5rem 0.75rem; + } + + &:hover { + transform: translate(-2px, -2px); + box-shadow: 6px 6px 0 #2E2E2E; + } + + &.active { + background-color: #3967D1; + border-color: #3967D1; + box-shadow: 4px 4px 0 #2E2E2E; + color: #fff; + } + } + } + + .community-updated { + color: #2E2E2E; + font-size: 0.8rem; + font-weight: bold; + letter-spacing: 0.05em; + margin-top: 1rem; + opacity: 0.6; + text-transform: uppercase; + } + + .community-user-group { + border-bottom: 2px solid #3967D1; + color: #3967D1; + font-size: 1.5rem; + font-weight: bold; + margin: 2rem 0 1rem; + padding-bottom: 0.5rem; + } + + &.sort-by-user { + .project-medal-wrap { display: none; } + + [class*="project--medal-"] { box-shadow: 4px 4px 0 #2E2E2E; } + } +} diff --git a/_sass/project-card.scss b/_sass/project-card.scss new file mode 100644 index 0000000..21c29f8 --- /dev/null +++ b/_sass/project-card.scss @@ -0,0 +1,124 @@ +#view-community { + .project { + align-items: stretch; + border: 3px solid #2E2E2E; + box-shadow: 4px 4px 0 #2E2E2E; + display: flex; + margin: 1rem 0; + position: relative; + transition: box-shadow 0.15s ease, transform 0.15s ease; + + &[hidden] { display: none; } + + &:hover { + box-shadow: 6px 6px 0 #3967D1; + transform: translate(-2px, -2px); + } + + &.project--medal-gold { box-shadow: 6px 6px 0 #FFC24D; } + &.project--medal-silver { box-shadow: 6px 6px 0 #C0C0C0; } + &.project--medal-bronze { box-shadow: 6px 6px 0 #CD7F32; } + + .project-header h4 a::after { + content: ""; + inset: 0; + position: absolute; + } + } + + .project-medal-wrap { + align-items: center; + background-color: #F6EEEC; + border-right: 3px solid #2E2E2E; + display: flex; + justify-content: center; + padding: 0 1rem; + min-width: 4.5rem; + + @media (max-width: 480px) { + min-width: 2.75rem; + padding: 0 0.4rem; + } + } + + .project-medal { + height: 2.5rem; + width: 2.5rem; + + @media (max-width: 480px) { + height: 1.75rem; + width: 1.75rem; + } + } + + .project-body { + flex: 1; + min-width: 0; + padding: 1.25rem; + } + + .project-header { + align-items: center; + display: flex; + justify-content: space-between; + gap: 1rem; + + h4 { + min-width: 0; + overflow-wrap: break-word; + + a { + color: #2E2E2E; + text-decoration: none; + + &:hover { color: #3967D1; } + } + } + } + + .project-stars { + background-color: #FFC24D; + border: 2px solid #2E2E2E; + color: #2E2E2E; + font: 700 0.9rem 'Syncopate', sans-serif; + padding: 0.2rem 0.6rem; + white-space: nowrap; + } + + .project-description { + color: #2E2E2E; + margin: 0.5rem 0; + opacity: 0.8; + overflow-wrap: break-word; + } + + .project-meta { + align-items: center; + display: flex; + flex-wrap: wrap; + gap: 0.5rem; + margin-top: 0.75rem; + } + + .project-author { + color: #2E2E2E; + font-size: 0.85rem; + opacity: 0.7; + } + + .project-topics { + display: flex; + flex-wrap: wrap; + gap: 0.35rem; + margin-left: 0.5rem; + } + + .project-topic { + background-color: #F6EEEC; + border: 2px solid #2E2E2E; + font-size: 0.7rem; + letter-spacing: 0.03em; + padding: 0.15rem 0.4rem; + text-transform: uppercase; + } +} diff --git a/assets/css/styles.scss b/assets/css/styles.scss index 719fcfc..4e641b6 100644 --- a/assets/css/styles.scss +++ b/assets/css/styles.scss @@ -1,3 +1,3 @@ --- --- -@import 'reset', 'application', 'header', 'nav', 'next_meetup', 'view', 'meetups', 'sponsors', 'footer', 'talks'; +@import 'reset', 'application', 'header', 'nav', 'next_meetup', 'view', 'meetups', 'sponsors', 'footer', 'talks', 'community', 'project-card'; diff --git a/assets/images/medal-bronze.svg b/assets/images/medal-bronze.svg new file mode 100644 index 0000000..944c242 --- /dev/null +++ b/assets/images/medal-bronze.svg @@ -0,0 +1,6 @@ + + + + + 3 + diff --git a/assets/images/medal-gold.svg b/assets/images/medal-gold.svg new file mode 100644 index 0000000..140a6e5 --- /dev/null +++ b/assets/images/medal-gold.svg @@ -0,0 +1,9 @@ + + + + + + + + 1 + diff --git a/assets/images/medal-silver.svg b/assets/images/medal-silver.svg new file mode 100644 index 0000000..539733b --- /dev/null +++ b/assets/images/medal-silver.svg @@ -0,0 +1,6 @@ + + + + + 2 + diff --git a/assets/js/community.js b/assets/js/community.js new file mode 100644 index 0000000..dae6c0c --- /dev/null +++ b/assets/js/community.js @@ -0,0 +1,79 @@ +document.addEventListener("DOMContentLoaded", () => { + const list = document.querySelector("#community-list"); + const input = document.querySelector("#community-search"); + const view = document.querySelector("#view-community"); + const sortButtons = document.querySelectorAll(".sort-btn"); + + if (!input || !list) return; + + const projectNodes = [...list.querySelectorAll(".project")]; + + const SORTS = { + stars: { + compare: (a, b) => (b.dataset.stars || 0) - (a.dataset.stars || 0), + groupByUser: false, + }, + user: { + compare: (a, b) => (a.dataset.user || "").localeCompare(b.dataset.user || ""), + groupByUser: true, + }, + name: { + compare: (a, b) => (a.dataset.name || "").localeCompare(b.dataset.name || ""), + groupByUser: false, + }, + }; + + let state = { + query: "", + currentSort: "stars" + }; + + const render = () => { + const { compare, groupByUser } = SORTS[state.currentSort]; + const fragment = document.createDocumentFragment(); + let lastUser = null; + + const oldHeaders = list.getElementsByClassName("community-user-group"); + while (oldHeaders[0]) oldHeaders[0].parentNode.removeChild(oldHeaders[0]); + + projectNodes + .sort(compare) + .forEach((project) => { + const matches = !state.query || project.dataset.search?.toLowerCase().includes(state.query); + + project.hidden = !matches; + + if (matches) { + if (groupByUser && project.dataset.user !== lastUser) { + lastUser = project.dataset.user; + const header = document.createElement("h3"); + header.className = "community-user-group"; + header.textContent = lastUser; + fragment.appendChild(header); + } + fragment.appendChild(project); + } + }); + + view.classList.toggle("sort-by-user", state.currentSort !== "stars"); + list.appendChild(fragment); + }; + + input.addEventListener("input", (e) => { + state.query = e.target.value.trim().toLowerCase(); + render(); + }); + + sortButtons.forEach((btn) => { + btn.addEventListener("click", () => { + const activeBtn = document.querySelector(".sort-btn.active"); + if (activeBtn) activeBtn.classList.remove("active"); + btn.classList.add("active"); + + state.currentSort = btn.dataset.sort; + render(); + }); + }); + + render(); +}); \ No newline at end of file diff --git a/community.html b/community.html new file mode 100644 index 0000000..fcb6cad --- /dev/null +++ b/community.html @@ -0,0 +1,4 @@ +--- +layout: community +permalink: /community/ +---