diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 094625f7998bd737fd69e7012a5790d20f40fe88..d8baf27587ff675b6e331695b0cd834886a0eaa8 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -41,3 +41,14 @@ select { @apply bg-green-100 border-green-300; } } +#flash { + @apply mx-auto flex items-center flex-col gap-1 p-2; + .flash { + @apply bg-slate-50 border-slate-100 border inline-block p-2 rounded-md shadow; + } +} +.main-nav { + a { + @apply underline hover:text-blue-600 hover:border-b hover:border-blue-600; + } +} \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d12ab4dfe301535a973e2607fad4efc9d0d..001ed300f4d3e8bc96c0c2972b8fb37989379994 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,9 @@ class ApplicationController < ActionController::Base + helper_method :current_user + + private + + def current_user + @current_user ||= User.find_by(id: session[:user_id]) if session[:user_id] + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000000000000000000000000000000000000..05b666ecc39287386e045629634491c85892cff4 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,47 @@ +class UsersController < ApplicationController + before_action :require_login, except: [:login] + + def login + @users = User.all + if params[:user_id] + user = User.find(params[:user_id]) + session[:user_id] = user.id + redirect_to conferences_path, notice: "Logged in as #{user.name}" + end + end + + def logout + session[:user_id] = nil + redirect_to login_path, notice: "Logged out" + end + + def profile + @user = current_user + end + + def update_profile + @user = current_user + if @user.update(user_params) + flash.now[:notice] = "Profile updated successfully!" + respond_to do |format| + format.html { redirect_to profile_path, notice: "Profile updated successfully!" } + #format.turbo_stream { render turbo_stream: turbo_stream.replace("flash", partial: "shared/flash") } + end + else + render :edit + end + end + + private + + def user_params + params.require(:user).permit(:name, :email, :avatar_color, :telegram_username) + end + + def require_login + unless current_user + flash[:alert] = "You must be logged in to edit your profile." + redirect_to login_path + end + end +end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index de6be7945c6a59798eb0ace177df38b05e98c2f0..6d16c9aeafa09c87a3e7af019880496cae491e27 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,2 +1,5 @@ module ApplicationHelper + def logged_in? + !session[:user_id].nil? + end end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000000000000000000000000000000000000..2310a240d78bd6361668625f782ada9d71cdd6c5 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/javascript/application.js b/app/javascript/application.js index e239947abfd19eb083fb16ac650b9a49b63ff6e4..84b06ebb56969db99d05c9c284ab917a6f2d6e19 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -1,3 +1,18 @@ // Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails import "controllers" import "@hotwired/turbo-rails" + +document.addEventListener("turbo:load", function() { + console.log('turbo:load'); + const flashMessages = document.querySelectorAll(".flash"); + + flashMessages.forEach(flashMessage => { + flashMessage.querySelector('.close').addEventListener('click', () => { + flashMessage.parentNode.removeChild(flashMessage); + }); + + setTimeout(() => { + flashMessage.parentNode.removeChild(flashMessage); + }, 5000); + }); +}); \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index d8c668001681d5160e73b74dc47df15b8ee6bb3e..c817a0a5c77f1817cb6fa12964c1c59d2843affe 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -12,6 +12,24 @@ </head> <body> + <nav class="main-nav bg-slate-100 border-b border-slate-200"> + <div class="container mx-auto p-5 flex flex-row justify-between"> + <div class="main-nav-left"> + <%= link_to 'Conferences', conferences_path %> + </div> + <div class="main-nav-right"> + <% if logged_in? %> + logged in as: <%= render partial: 'application/user_avatar', locals: { user: current_user } %> + <%= link_to 'Profile', profile_path %> + <%= link_to 'Assignments', user_assignments_path(current_user) %> + <%= link_to 'Logout', logout_path, data: { turbo_method: :post } %> + <% else %> + Not logged in + <% end %> + </div> + </div> + </nav> + <%= render partial: 'shared/flash' %> <main class="container mx-auto mt-8 px-5 flex"> <%= yield %> </main> diff --git a/app/views/shared/_flash.html.erb b/app/views/shared/_flash.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..143f14ff63cd1879f79f0a2a0477d6ea4c0873db --- /dev/null +++ b/app/views/shared/_flash.html.erb @@ -0,0 +1,10 @@ +<div id="flash"> + <% flash.each do |type, message| %> + <div class="flash alert alert-<%= type %>"> + <%= message %> + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> + <span aria-hidden="true">×</span> + </button> + </div> + <% end %> +</div> \ No newline at end of file diff --git a/app/views/users/login.html.erb b/app/views/users/login.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..7c99ca874b99aa6b93dd46f34928f750ed7d2554 --- /dev/null +++ b/app/views/users/login.html.erb @@ -0,0 +1,10 @@ +<div> + <h1 class="font-bold text-4xl mb-8">Choose User</h1> + <ul class="flex flex-wrap gap-2"> + <% @users.each do |user| %> + <li> + <%= button_to user.name, login_path(user_id: user.id), data: { turbo_method: :post }, class: "p-2 border hover:bg-slate-100 hover:shadow" %> + </li> + <% end %> +</ul> +</div> diff --git a/app/views/users/logout.html.erb b/app/views/users/logout.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..00a082014b19442f248051f08f72c7a08d767fd2 --- /dev/null +++ b/app/views/users/logout.html.erb @@ -0,0 +1,4 @@ +<div> + <h1 class="font-bold text-4xl">Users#logout</h1> + <p>Find me in app/views/users/logout.html.erb</p> +</div> diff --git a/app/views/users/profile.html.erb b/app/views/users/profile.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..f655398be3ee0a88389c8d72c01a8406884e782a --- /dev/null +++ b/app/views/users/profile.html.erb @@ -0,0 +1,28 @@ +<div> + <h1 class="font-bold text-4xl">Profile</h1> + <%= form_with(model: @user, url: update_profile_path, local: true) do |form| %> + <div class="field"> + <%= form.label :name %> + <%= form.text_field :name %> + </div> + + <div class="field"> + <%= form.label :email %> + <%= form.text_field :email %> + </div> + + <div class="field"> + <%= form.label :avatar_color %> + <%= form.color_field :avatar_color %> + </div> + + <div class="field"> + <%= form.label :telegram_username %> + <%= form.text_field :telegram_username %> + </div> + + <div class="actions"> + <%= form.submit "Update Profile" %> + </div> + <% end %> +</div> diff --git a/app/views/users/update.html.erb b/app/views/users/update.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..7ead44d26f45fe7623a624b881c824f668cce592 --- /dev/null +++ b/app/views/users/update.html.erb @@ -0,0 +1,4 @@ +<div> + <h1 class="font-bold text-4xl">Users#update</h1> + <p>Find me in app/views/users/update.html.erb</p> +</div> diff --git a/config/routes.rb b/config/routes.rb index 6f22f91e52ef48af5afded9115ea5c0a966d8436..80999f2dfae0b1a57235af8ac99eac132cd1c586 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,10 @@ Rails.application.routes.draw do + get 'login', to: 'users#login', as: :login + post 'login', to: 'users#login' + post 'logout', to: 'users#logout', as: :logout + get 'profile', to: 'users#profile', as: :profile + patch 'profile', to: 'users#update_profile', as: :update_profile + resources :users, only: [:show] # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb new file mode 100644 index 0000000000000000000000000000000000000000..6753bae81db05556a24e7114407c38a79804778e --- /dev/null +++ b/test/controllers/users_controller_test.rb @@ -0,0 +1,23 @@ +require "test_helper" + +class UsersControllerTest < ActionDispatch::IntegrationTest + test "should get login" do + get users_login_url + assert_response :success + end + + test "should get logout" do + get users_logout_url + assert_response :success + end + + test "should get show" do + get users_show_url + assert_response :success + end + + test "should get update" do + get users_update_url + assert_response :success + end +end