From f40ff47c81502491bf7880b29ca5060e11bbba40 Mon Sep 17 00:00:00 2001 From: riggraz Date: Thu, 9 Jan 2025 11:54:18 +0100 Subject: [PATCH] Add button to remove user avatar --- app/controllers/registrations_controller.rb | 7 +++ .../UserProfile/DeleteAvatarButton.tsx | 54 +++++++++++++++++++ app/views/devise/registrations/edit.html.erb | 11 ++++ config/routes.rb | 3 +- 4 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 app/javascript/components/UserProfile/DeleteAvatarButton.tsx diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 17963bf3..48d1ed25 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -77,6 +77,13 @@ class RegistrationsController < Devise::RegistrationsController respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) } end + def delete_avatar + user = User.find(current_user.id) + user.avatar.purge + + render json: { success: true }, status: :ok + end + def send_set_password_instructions user = User.find_by_email(params[:email]) diff --git a/app/javascript/components/UserProfile/DeleteAvatarButton.tsx b/app/javascript/components/UserProfile/DeleteAvatarButton.tsx new file mode 100644 index 00000000..ee9314ce --- /dev/null +++ b/app/javascript/components/UserProfile/DeleteAvatarButton.tsx @@ -0,0 +1,54 @@ +import * as React from 'react'; +import I18n from 'i18n-js'; + +import ActionLink from '../common/ActionLink'; +import { DeleteIcon } from '../common/Icons'; +import buildRequestHeaders from '../../helpers/buildRequestHeaders'; +import Spinner from '../common/Spinner'; + +interface Props { + deleteAvatarEndpoint: string; + authenticityToken: string; +} + +const DeleteAvatarButton = ({ deleteAvatarEndpoint, authenticityToken }: Props) => { + const [isDeleting, setIsDeleting] = React.useState(false); + const [error, setError] = React.useState(''); + + return ( + <> + } + onClick={async () => { + setIsDeleting(true); + + try { + const response = await fetch(deleteAvatarEndpoint, { + method: 'DELETE', + headers: buildRequestHeaders(authenticityToken), + }); + + if (response.ok) { + location.reload(); + } else { + throw new Error(); + } + } catch { + setError(I18n.t('common.errors.unknown')); + } + + setIsDeleting(false); + if (error) { + alert(error); + } + } + }> + { I18n.t('common.buttons.delete') } + + + { isDeleting && } + + ); +} + +export default DeleteAvatarButton; \ No newline at end of file diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 2c9f1515..8935ebf2 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -33,6 +33,17 @@

<% if resource.avatar.attached? %> <%= image_tag url_for(resource.avatar), class: 'avatar', size: 48 %> + + <%= + react_component( + 'UserProfile/DeleteAvatarButton', + { + deleteAvatarEndpoint: delete_avatar_path, + authenticityToken: form_authenticity_token + } + ) + %> + <% else %> <%= image_tag current_user.gravatar_url, class: 'avatar', size: 48 %> <% end %> diff --git a/config/routes.rb b/config/routes.rb index b2c8a3a9..2c6a370d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -43,9 +43,10 @@ Rails.application.routes.draw do :sessions => 'sessions', :passwords => 'passwords' } - + devise_scope :user do get '/users/send_set_password_instructions', to: 'registrations#send_set_password_instructions', as: :send_set_password_instructions + delete '/users/delete_avatar', to: 'registrations#delete_avatar', as: :delete_avatar end resources :tenants, only: [:show, :update]