-
Notifications
You must be signed in to change notification settings - Fork 40
Resources page #436
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
fatmahussein
wants to merge
37
commits into
main
Choose a base branch
from
53-suggested-resources-page
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Resources page #436
Changes from 22 commits
Commits
Show all changes
37 commits
Select commit
Hold shift + click to select a range
c4a968b
add resources table migration
fatmahussein edd68a7
add resources page endpoint
fatmahussein f2655ff
implement resources management
fatmahussein 68d2ac0
add public API for listing and creating resources
fatmahussein 8af5864
Add Resource model logic and validations
fatmahussein 398bd57
restrict resource actions to admin users
fatmahussein a5c1a70
add client methods for listing and submitting resources
fatmahussein 9ed5cae
add form for creating and editing resources
fatmahussein 9647fd2
Add edit resource view
fatmahussein 39e7622
add resources index view with management table
fatmahussein 63cfbf6
add new resource view
fatmahussein dd5259c
add JS and CSS packs for resources page
fatmahussein 986f089
Add resources link to admin navigation
fatmahussein 7527caf
add reusable Modal component
fatmahussein 63b6ee2
add resources link to footer navigation
fatmahussein 5095d11
Add resources link to header navigation
fatmahussein 63d4423
implement full resources page with listing and submission
fatmahussein 30c7b14
Add resources page entry point
fatmahussein f4d7e38
adjust navbar spacing
fatmahussein b78bed1
Update loading dot color to match website theme
fatmahussein 9d247a7
add modal component styles
fatmahussein 625c756
Add resources page styles
fatmahussein 0669aae
replace null_session with exception CSRF strategy
fatmahussein 1d9a296
add FactoryBot resource factory
fatmahussein c35171d
add Resource model test coverage
fatmahussein 2fc2c0d
Add system tests for admin resource management
fatmahussein 2732291
Extend site page system specs to cover new resources feature
fatmahussein b550077
fix rubocop offenses
fatmahussein 4b1a4f7
fix eslint offenses
fatmahussein c9bb479
email resource suggestions instead of saving them
fatmahussein 2c3f7ea
use GMAIL_USERNAME as default mailer sender
fatmahussein c0ce048
add ResourceMailer for resource suggestions
fatmahussein 7050e54
add HTML template for resource suggestion emails
fatmahussein 741b69a
require submitter name for resource suggestions
fatmahussein 01f1143
use organizers email for job posting inquiries
fatmahussein acad715
fix eslint offenses
fatmahussein f936ab3
fix eslint offense
fatmahussein File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Admin | ||
| class ResourcesController < AdminController | ||
| include Pagy::Backend | ||
|
|
||
| before_action :authorize_resource | ||
| before_action :set_resource, only: %w[edit update destroy] | ||
|
|
||
| def index | ||
| @pagy, @resources = pagy(Resource.recent, items: 15) | ||
| end | ||
|
|
||
| def new | ||
| @resource = Resource.new | ||
| end | ||
|
|
||
| def create | ||
| @resource = Resource.new(resource_params) | ||
|
|
||
| if @resource.save | ||
| redirect_to admin_resources_path, notice: "Resource created successfully." | ||
| else | ||
| render :new, status: :unprocessable_content | ||
| end | ||
| end | ||
|
|
||
| def edit; end | ||
|
|
||
| def update | ||
| if @resource.update(resource_params) | ||
| redirect_to admin_resources_path, notice: "Resource updated successfully." | ||
| else | ||
| render :edit, status: :unprocessable_content | ||
| end | ||
| end | ||
|
|
||
| def destroy | ||
| @resource.destroy | ||
| redirect_to admin_resources_path, notice: "Resource deleted." | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def authorize_resource | ||
| authorize Resource | ||
| end | ||
|
|
||
| def set_resource | ||
| @resource = Resource.find(params[:id]) | ||
| end | ||
|
|
||
| def resource_params | ||
| params.require(:resource).permit(:title, :url, :description, :category, :submitted_by) | ||
| end | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Api | ||
| class ResourcesController < ApplicationController | ||
| protect_from_forgery with: :null_session | ||
Check failureCode scanning / CodeQL CSRF protection weakened or disabled High
Potential CSRF vulnerability due to forgery protection being disabled or weakened.
|
||
|
|
||
| def index | ||
| resources = Resource.recent | ||
| resources = resources.by_category(params[:category]) if params[:category].present? | ||
| render json: { data: resources.map(&:as_json) } | ||
| end | ||
|
|
||
| def create | ||
| resource = Resource.new(resource_params) | ||
|
|
||
| if resource.save | ||
| render json: { message: "Resource submitted successfully!" }, status: :created | ||
| else | ||
| render json: { errors: resource.errors.full_messages }, status: :unprocessable_entity | ||
| end | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def resource_params | ||
| params.permit(:title, :url, :description, :category, :submitted_by) | ||
| end | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,4 +16,6 @@ def past_meetup; end | |
| def sponsor_us; end | ||
|
|
||
| def community; end | ||
|
|
||
| def resources; end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| import React, { useEffect, useCallback } from 'react'; | ||
| import PropTypes from 'prop-types'; | ||
|
|
||
| import '../stylesheets/modal'; | ||
|
|
||
| const Modal = ({ isOpen, onClose, children }) => { | ||
| const handleKeyDown = useCallback( | ||
| (e) => { | ||
| if (e.key === 'Escape') onClose(); | ||
| }, | ||
| [onClose], | ||
| ); | ||
|
|
||
| useEffect(() => { | ||
| if (isOpen) { | ||
| document.addEventListener('keydown', handleKeyDown); | ||
| document.body.style.overflow = 'hidden'; | ||
| } | ||
| return () => { | ||
| document.removeEventListener('keydown', handleKeyDown); | ||
| document.body.style.overflow = ''; | ||
| }; | ||
| }, [isOpen, handleKeyDown]); | ||
|
|
||
| if (!isOpen) return null; | ||
|
|
||
| return ( | ||
| <div className="modal-overlay" onClick={onClose}> | ||
| <div className="modal-content" onClick={(e) => e.stopPropagation()}> | ||
| <button className="modal-close" type="button" onClick={onClose} aria-label="Close"> | ||
| × | ||
| </button> | ||
| {children} | ||
| </div> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| Modal.propTypes = { | ||
| isOpen: PropTypes.bool.isRequired, | ||
| onClose: PropTypes.func.isRequired, | ||
| children: PropTypes.node, | ||
| }; | ||
|
|
||
| export default Modal; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.