diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c871b63..813aa2e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,15 +1,15 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-06-25 17:50:29 UTC using RuboCop version 1.64.1. +# on 2024-07-03 21:53:32 UTC using RuboCop version 1.64.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 3 +# Offense count: 4 # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. Metrics/AbcSize: - Max: 24 + Max: 45 # Offense count: 8 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. @@ -17,22 +17,27 @@ Metrics/AbcSize: Metrics/BlockLength: Max: 66 +# Offense count: 1 +# Configuration parameters: CountComments, CountAsOne. +Metrics/ClassLength: + Max: 134 + # Offense count: 1 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/CyclomaticComplexity: Max: 9 -# Offense count: 6 +# Offense count: 8 # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. Metrics/MethodLength: - Max: 16 + Max: 30 # Offense count: 1 # Configuration parameters: AllowedMethods, AllowedPatterns. Metrics/PerceivedComplexity: Max: 9 -# Offense count: 28 +# Offense count: 27 # Configuration parameters: AllowedConstants. Style/Documentation: Enabled: false diff --git a/Gemfile b/Gemfile index d1ccbab..ffcf3b9 100644 --- a/Gemfile +++ b/Gemfile @@ -102,7 +102,8 @@ group :test do # Adds support for Capybara system testing and selenium driver gem 'selenium-webdriver', '>= 4.17.0.rc1' # Easy installation and use of web drivers to run system tests with browsers - gem 'webdrivers' + gem 'webdrivers', '~> 5.0' + # Adds support to make API calls gem 'webmock' end diff --git a/Gemfile.lock b/Gemfile.lock index e15e5db..e2629fe 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -452,7 +452,7 @@ DEPENDENCIES turbo-rails tzinfo-data web-console (>= 4.2.1) - webdrivers + webdrivers (~> 5.0) webmock RUBY VERSION diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 15b06f0..f2b0e60 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -1,4 +1,7 @@ # frozen_string_literal: true module ApplicationHelper + def wallet_connected? + current_user.wallet.present? + end end diff --git a/app/javascript/application.js b/app/javascript/application.js index 48f17d4..d55cd4f 100644 --- a/app/javascript/application.js +++ b/app/javascript/application.js @@ -2,3 +2,14 @@ import "@hotwired/turbo-rails" import "./controllers" import "../assets/stylesheets/application.tailwind.css"; + + +document.addEventListener('DOMContentLoaded', () => { + const alertElement = document.querySelector('.alert'); + if (alertElement) { + const alertMessage = alertElement.getAttribute('data-alert-message'); + if (alertMessage) { + alert(alertMessage); + } + } +}); \ No newline at end of file diff --git a/app/javascript/controllers/wallet_controller.js b/app/javascript/controllers/wallet_controller.js index aa08c7d..93fb114 100644 --- a/app/javascript/controllers/wallet_controller.js +++ b/app/javascript/controllers/wallet_controller.js @@ -4,25 +4,30 @@ import { mainnet, arbitrum } from "viem/chains"; import { getAccount, reconnect } from "@wagmi/core"; export default class extends Controller { - static targets = ["openModal"]; + static targets = ["openModal", 'createCampaignButton', 'tooltipText']; + static targets = ["openModal", "createCampaignButton", "tooltipText"]; static values = { projectId: String, userId: Number, walletIdValue: Number, csrfToken: String, + walletConnected: Boolean, }; connect() { this.isDeleting = false; this.disconnectRequested = false; + this.walletConnectedValue = this.walletConnectedValue || false; + + this.updateButtonState(); const projectId = this.projectIdValue; const chains = [mainnet, arbitrum]; const metadata = { - name: 'Web3Modal', - description: 'Web3Modal Example', - url: 'http://localhost:3000', - icons: ['https://avatars.githubusercontent.com/u/37784886'], + name: "Web3Modal", + description: "Web3Modal Example", + url: "http://localhost:3000", + icons: ["https://avatars.githubusercontent.com/u/37784886"], }; this.config = defaultWagmiConfig({ @@ -36,6 +41,14 @@ export default class extends Controller { }); reconnect(this.config); + this.account = getAccount(this.config); + if (this.account && this.account.isConnected) { + this.walletConnectedValue = true; + } else { + this.walletConnectedValue = false; + } + this.updateButtonState(); + this.modal = createWeb3Modal({ wagmiConfig: this.config, projectId: this.projectIdValue, @@ -45,20 +58,29 @@ export default class extends Controller { this.modal.subscribeEvents((event) => { this.account = getAccount(this.config); - if (event.data.event === 'CONNECT_SUCCESS') { + if (event.data.event === "CONNECT_SUCCESS") { this.addWalletToDatabase(this.account); - this.openModalTarget.textContent = 'Disconnect Wallet'; - } else if (event.data.event === 'MODAL_CLOSE' && this.disconnectRequested && !event.data.properties.connected) { + this.openModalTarget.textContent = "Disconnect Wallet"; + this.walletConnectedValue = true; + this.updateButtonState(); + } else if ( + event.data.event === "MODAL_CLOSE" && + this.disconnectRequested && + !event.data.properties.connected + ) { this.removeWalletFromDatabase(this.account); - this.openModalTarget.textContent = 'Connect Wallet'; + this.openModalTarget.textContent = "Connect Wallet"; + this.walletConnectedValue = false; + this.updateButtonState(); } else { - console.log('Modal closed without disconnection'); + console.log("Modal closed without disconnection"); } }); } openModal() { - const isDisconnect = this.openModalTarget.textContent === 'Disconnect Wallet'; + const isDisconnect = + this.openModalTarget.textContent === "Disconnect Wallet"; this.disconnectRequested = isDisconnect; this.modal.open(); } @@ -72,10 +94,10 @@ export default class extends Controller { try { const response = await fetch(`/users/${this.userIdValue}/wallet`, { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': this.csrfTokenValue, + "Content-Type": "application/json", + "X-CSRF-Token": this.csrfTokenValue, }, body: JSON.stringify(walletData), }); @@ -85,25 +107,25 @@ export default class extends Controller { } const responseData = await response.json(); - console.log('Successfully created wallet in database:', responseData); + console.log("Successfully created wallet in database:", responseData); } catch (error) { - console.error('Error creating wallet in database:', error); + console.error("Error creating wallet in database:", error); } } async removeWalletFromDatabase() { if (this.isDeleting) { - console.log('Already deleting wallet, aborting.'); + console.log("Already deleting wallet, aborting."); return; } this.isDeleting = true; try { const response = await fetch(`/users/${this.userIdValue}/wallet`, { - method: 'DELETE', + method: "DELETE", headers: { - 'Content-Type': 'application/json', - 'X-CSRF-Token': this.csrfTokenValue, + "Content-Type": "application/json", + "X-CSRF-Token": this.csrfTokenValue, }, }); @@ -112,13 +134,34 @@ export default class extends Controller { } const responseData = await response.json(); - console.log('Successfully removed from database:', responseData); - this.openModalTarget.textContent = 'Connect Wallet'; + console.log("Successfully removed from database:", responseData); + this.openModalTarget.textContent = "Connect Wallet"; } catch (error) { - console.error('Error removing wallet from database:', error); + console.error("Error removing wallet from database:", error); } finally { this.isDeleting = false; this.disconnectRequested = false; } } + + updateButtonState() { + this.createCampaignButtonTargets.forEach((button, index) => { + const tooltip = this.tooltipTextTargets[index]; + if (this.walletConnectedValue) { + button.disabled = false; + button.classList.remove("bg-gray-500", "cursor-not-allowed"); + button.classList.add("bg-blue-500", "hover:bg-blue-700"); + + tooltip.classList.add("hidden"); + tooltip.classList.remove("block"); + } else { + button.disabled = true; + button.classList.remove("bg-blue-500", "hover:bg-blue-700"); + button.classList.add("bg-gray-500", "cursor-not-allowed"); + + tooltip.classList.remove("hidden"); + tooltip.classList.add("block"); + } + }); + } } diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb index b304585..b77b668 100644 --- a/app/views/home/index.html.erb +++ b/app/views/home/index.html.erb @@ -1,27 +1,24 @@ -
+
+ <% wallet_connected = current_user.wallet.present? %>
<%= image_tag 'logo.jpg', alt: "Logo", class: 'my-6' %> <%= image_tag @avatar, alt: "Avatar", class: 'w-24 h-24 rounded-full' %> <%= button_to "logout", destroy_user_session_path, method: :delete %>

- <%= "Hello, #{current_user.nickname}, welcome to Line - The Developers Marketplace " %> + <%= "Hello, #{current_user.nickname}, welcome to Line - The Developers Marketplace" %>

- <% wallet_connected = current_user.wallet.present? %> -
-
-

<% if @organizations.present? %>

<% campaign = @campaigns_by_repo_identifier[repo[:repo].full_name] %> - <% if campaign %> - <%= link_to 'Show Campaign', user_campaign_path(current_user, campaign, repo_identifier: repo[:repo].full_name), class: "btn btn-success" %> + <% if wallet_connected %> + <% if campaign %> + <%= link_to 'Show Campaign', user_campaign_path(current_user, campaign, repo_identifier: repo[:repo].full_name), class: "btn btn-success" %> + <% else %> + <%= link_to 'Create Campaign', new_user_campaign_path(current_user, repo_name: repo[:repo].full_name), class: "btn btn-primary" %> + <% end %> <% else %> - <%= link_to 'Create Campaign', new_user_campaign_path(current_user, repo_name: repo[:repo].full_name), class: "btn btn-primary" %> +
+ + + Please connect a wallet to create campaigns + +
<% end %> @@ -75,12 +92,12 @@ <% end %> - - - <% else %> -

No repos found.

- <% end %> -
+ + <% else %> +

No repos found.

+ <% end %> + +