diff --git a/app/assets/stylesheets/admin/pages/publisher.scss b/app/assets/stylesheets/admin/pages/publisher.scss index a1b9207bd7..e880aff91d 100644 --- a/app/assets/stylesheets/admin/pages/publisher.scss +++ b/app/assets/stylesheets/admin/pages/publisher.scss @@ -159,3 +159,14 @@ } } } + +.not-verified { + color: $braveGray-6; + + img { + filter: grayscale(100%); + } + a { + color: $braveGray-6; + } +} diff --git a/app/assets/stylesheets/pages/home.scss b/app/assets/stylesheets/pages/home.scss index ac136d83a0..f2c8a55352 100644 --- a/app/assets/stylesheets/pages/home.scss +++ b/app/assets/stylesheets/pages/home.scss @@ -232,9 +232,6 @@ } .channel--promo-info-container { - position: absolute; - right: 24px; - @media only screen and (max-width: 520px) { margin: 8px 0; display: flex; @@ -700,6 +697,11 @@ .channel-summary { width: 100%; + // Apply a max width when the screen gets smaller to trim long channel names + @media only screen and (max-width: 768px) { + max-width: 10rem; + } + h3 { font-size: 20px; } @@ -718,6 +720,13 @@ } } + .channel-secondary-information { + @media only screen and (max-width: 560px) { + width: 100%; + margin: 0.5em 0; + } + } + &.channel-incomplete, &.channel-started, &.channel-failed { @@ -870,7 +879,6 @@ } &--intro { - margin-bottom: 8px; display: flex; align-items: center; } @@ -901,7 +909,6 @@ .bat-channel { &--amount { font-size: 28px; - font-weight: bolder; display: inline; line-height: 1; } @@ -1058,9 +1065,6 @@ overflow-y: auto; max-height: calc(100vh - 150px); } - &--icon { - margin: 0; - } } .new-tag { diff --git a/app/controllers/admin/publishers_controller.rb b/app/controllers/admin/publishers_controller.rb index 8d3f343cba..d1dad12c43 100644 --- a/app/controllers/admin/publishers_controller.rb +++ b/app/controllers/admin/publishers_controller.rb @@ -112,7 +112,7 @@ def refresh_uphold connection = UpholdConnection.find_by(publisher: params[:publisher_id]) if connection.present? connection.sync_from_uphold! - CreateUpholdCardsJob.perform_now(uphold_connection_id: connection.id) + connection.create_uphold_cards end redirect_to admin_publisher_path(@publisher.id) end diff --git a/app/controllers/publishers/uphold_controller.rb b/app/controllers/publishers/uphold_controller.rb index c0775d0cdd..0bc155c638 100644 --- a/app/controllers/publishers/uphold_controller.rb +++ b/app/controllers/publishers/uphold_controller.rb @@ -32,7 +32,7 @@ def confirm_default_currency uphold_connection.update(confirm_default_currency_params.merge(default_currency_confirmed_at: Time.now)) if uphold_connection.can_create_uphold_cards? - uphold_connection.create_uphold_card_for_default_currency + uphold_connection.create_uphold_cards # TODO do we need this refresh? render(json: { diff --git a/app/controllers/publishers_controller.rb b/app/controllers/publishers_controller.rb index 5ec1669c5c..54456f9b57 100644 --- a/app/controllers/publishers_controller.rb +++ b/app/controllers/publishers_controller.rb @@ -212,7 +212,7 @@ def home uphold_connection.sync_from_uphold! # Handles legacy case where user is missing an Uphold card - uphold_connection.create_uphold_card_for_default_currency if uphold_connection.missing_card? + uphold_connection.create_uphold_cards if uphold_connection.missing_card? end end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 9a7a8aa431..8f5c19960c 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -77,12 +77,13 @@ def publisher_link(publisher) end def payout_report_status_header(account_type) - report_date = PayoutReport.most_recent_final_report.created_at.strftime("%b %d") + report_date = PayoutReport.most_recent_final_report.created_at + report_date = report_date.strftime("%B #{report_date.day.ordinalize}") if account_type == 'owner' - "#{report_date}'s Payout Report Status (Referrals)" + "#{report_date} Payout (Referrals)" else account_type == 'channel' - "#{report_date}'s Payout Report Status (Contributions)" + "#{report_date} Payout Contributions" end end end diff --git a/app/javascript/views/admin/components/userNavbar/components/TopNav/TopNavStyle.ts b/app/javascript/views/admin/components/userNavbar/components/TopNav/TopNavStyle.ts index 64d13a509d..e35f03d329 100644 --- a/app/javascript/views/admin/components/userNavbar/components/TopNav/TopNavStyle.ts +++ b/app/javascript/views/admin/components/userNavbar/components/TopNav/TopNavStyle.ts @@ -17,7 +17,6 @@ export const Container = styled.div` display: none; } background-color: white; - box-shadow: rgba(99, 105, 110, 0.18) 0px 1px 12px 0px; padding: 28px; margin-top: -53px; `; diff --git a/app/jobs/create_uphold_cards_job.rb b/app/jobs/create_uphold_cards_job.rb index 2c3945c285..7d33c9bad7 100644 --- a/app/jobs/create_uphold_cards_job.rb +++ b/app/jobs/create_uphold_cards_job.rb @@ -9,8 +9,17 @@ def perform(uphold_connection_id:) return end + card = nil + # Search for an existing card - card = uphold_connection.uphold_client.card.where(uphold_connection: uphold_connection)&.first + cards = uphold_connection.uphold_client.card.where(uphold_connection: uphold_connection) + existing_private_cards = UpholdConnectionForChannel.select(:card_id).where(uphold_connection: uphold_connection).to_a + + cards.each do |c| + # We don't want to accidentally set the Publisher's card used for auto contribute and referral deposits into a channel card + # So we should check the address for the card and make sure that we haven't already used it + card = c and break if existing_private_cards.exclude?(c.id) + end # If the card doesn't exist so we should create it if card.blank? diff --git a/app/jobs/create_uphold_channel_card_job.rb b/app/jobs/create_uphold_channel_card_job.rb new file mode 100644 index 0000000000..df5568aac0 --- /dev/null +++ b/app/jobs/create_uphold_channel_card_job.rb @@ -0,0 +1,70 @@ +class CreateUpholdChannelCardJob < ApplicationJob + queue_as :default + + def perform(uphold_connection_id:, channel_id:) + uphold_connection = UpholdConnection.find(uphold_connection_id) + channel = Channel.find(channel_id) + return unless uphold_connection&.is_member? && channel&.verified? + + unless uphold_connection.can_create_uphold_cards? + Rails.logger.info("Could not create uphold card for channel #{uphold_connection.publisher_id}. Uphold Verified: #{uphold_connection.uphold_verified}") + return + end + + upfc = UpholdConnectionForChannel.find_by( + uphold_connection: uphold_connection, + currency: uphold_connection.default_currency, + channel_identifier: channel.details.channel_identifier + ) + + if upfc.present? + card_id = upfc.card_id + else + (card_id, upfc) = create_card(uphold_connection, channel) + end + + # If the channel was deleted and then recreated we should update this to be the new channel id + upfc.update( + address: get_address(uphold_connection, card_id), + channel_id: channel.id + ) + end + + def create_card(uphold_connection, channel) + card_label = "#{channel.type_display} - #{channel.details.publication_title} - Brave Rewards" + + # If the card doesn't exist so we should create it + card_id = uphold_connection.uphold_client.card.create( + uphold_connection: uphold_connection, + currency: uphold_connection.default_currency, + label: card_label + ).id + + upfc = UpholdConnectionForChannel.create( + uphold_connection: uphold_connection, + channel: channel, + card_id: card_id, + currency: uphold_connection.default_currency, + channel_identifier: channel.details.channel_identifier + ) + + [card_id, upfc] + end + + def get_address(uphold_connection, card_id) + addresses = uphold_connection.uphold_client.address.all( + uphold_connection: uphold_connection, + id: card_id + ) + address = addresses.detect { |a| a.type == UpholdConnectionForChannel::NETWORK } + address = address.formats.first.dig('value') if address.present? + + return address if address.present? + + uphold_connection.uphold_client.address.create( + uphold_connection: uphold_connection, + id: card_id, + network: UpholdConnectionForChannel::NETWORK + ) + end +end diff --git a/app/jobs/migrate_uphold_access_parameters_job.rb b/app/jobs/migrate_uphold_access_parameters_job.rb index c4690a45fd..a5037b81e8 100644 --- a/app/jobs/migrate_uphold_access_parameters_job.rb +++ b/app/jobs/migrate_uphold_access_parameters_job.rb @@ -19,7 +19,7 @@ def perform(publisher_id:, parameters:, default_currency:) connection.reload # Sync the uphold card or create it if the card is missing - CreateUpholdCardsJob.perform_later(uphold_connection_id: connection.id) + connection.create_uphold_cards else Rails.logger.info("Couldn't find publisher #{publisher_id} in creator's database but exists on mongo owner's database (Probably not a big deal)") end diff --git a/app/models/channel.rb b/app/models/channel.rb index 3f515cf540..c2a4bd5500 100644 --- a/app/models/channel.rb +++ b/app/models/channel.rb @@ -48,6 +48,7 @@ class Channel < ApplicationRecord }, foreign_key: 'details_id' has_one :promo_registration, dependent: :destroy + has_many :uphold_connection_for_channel has_one :contesting_channel, class_name: "Channel", foreign_key: 'contested_by_channel_id' @@ -76,7 +77,7 @@ class Channel < ApplicationRecord validate :verified_duplicate_channels_must_be_contested, if: -> { verified? } after_save :register_channel_for_promo, if: :should_register_channel_for_promo - after_save :notify_slack, if: :saved_change_to_verified? + after_save :create_channel_card, :notify_slack, if: -> { :saved_change_to_verified? && verified? } before_save :clear_verified_at_if_necessary @@ -360,6 +361,10 @@ def most_recent_potential_payment PayoutReport.most_recent_final_report&.potential_payments&.where(channel_id: id)&.first end + def uphold_connection + @uphold_connection ||= UpholdConnectionForChannel.joins(:uphold_connection).where(channel_id: id).where("uphold_connections.default_currency = uphold_connection_for_channels.currency").first + end + private def should_register_channel_for_promo @@ -376,6 +381,10 @@ def register_channel_for_promo Promo::RegisterChannelForPromoJob.new.perform(channel: self) end + def create_channel_card + CreateUpholdChannelCardJob.perform_later(uphold_connection_id: publisher.uphold_connection&.id, channel_id: id) + end + def notify_slack return unless verified? emoji = diff --git a/app/models/json_builders/channels_json_builder_v2.rb b/app/models/json_builders/channels_json_builder_v2.rb index e4e4cb86b4..a3c722ee7e 100644 --- a/app/models/json_builders/channels_json_builder_v2.rb +++ b/app/models/json_builders/channels_json_builder_v2.rb @@ -55,9 +55,9 @@ def include_verified_channel(verified_channel) # Skip if channel publisher has not yet KYC'd return unless verified_channel.publisher&.uphold_connection&.is_member - wallet_address_id = verified_channel.publisher&.uphold_connection&.address + wallet_address_id = verified_channel.uphold_connection&.address + return if wallet_address_id.nil? - return if existing_wallet_address?(wallet_address_id) @channels.push([ verified_channel.details.channel_identifier, diff --git a/app/models/uphold_connection.rb b/app/models/uphold_connection.rb index 3b4d1a7c45..cb79ea8866 100644 --- a/app/models/uphold_connection.rb +++ b/app/models/uphold_connection.rb @@ -26,6 +26,8 @@ class UpholdAccountState belongs_to :publisher + has_many :uphold_connection_for_channels + # uphold_code is an intermediate step to acquiring uphold_access_parameters # and should be cleared once it has been used to get uphold_access_parameters validates :uphold_code, absence: true, if: -> { uphold_access_parameters.present? || uphold_verified? } @@ -38,7 +40,7 @@ class UpholdAccountState } # If the user became KYC'd let's create the uphold card for them - after_save :create_uphold_card_for_default_currency, if: -> { saved_change_to_is_member? && is_member? } + after_save :create_uphold_cards, if: -> { saved_change_to_is_member? && uphold_verified? } # publishers that have access params that havent accepted by eyeshade # can be cleared after 2 hours @@ -141,9 +143,14 @@ def wallet @wallet ||= publisher&.wallet end - def create_uphold_card_for_default_currency + def create_uphold_cards return unless can_create_uphold_cards? + CreateUpholdCardsJob.perform_now(uphold_connection_id: id) + + publisher.channels.each do |channel| + CreateUpholdChannelCardJob.perform_now(uphold_connection_id: id, channel_id: channel.id) + end end def missing_card? diff --git a/app/models/uphold_connection_for_channel.rb b/app/models/uphold_connection_for_channel.rb new file mode 100644 index 0000000000..dc33d8c916 --- /dev/null +++ b/app/models/uphold_connection_for_channel.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# Creates a connection between uphold and a channel +# +# We use this to look up existing cards. If a user deletes a channel then we should not destroy this. +# Really the only time we should delete is if the uphold connection gets deleted, which should only happen if the publisher +class UpholdConnectionForChannel < ApplicationRecord + belongs_to :uphold_connection + belongs_to :channel + + NETWORK = 'anonymous' + + validates :channel_identifier, uniqueness: { scope: [:uphold_connection_id, :channel_identifier, :currency] } +end diff --git a/app/services/payout_report_publisher_includer.rb b/app/services/payout_report_publisher_includer.rb index e173305f64..4791bc87b7 100644 --- a/app/services/payout_report_publisher_includer.rb +++ b/app/services/payout_report_publisher_includer.rb @@ -14,7 +14,7 @@ def perform uphold_connection.sync_from_uphold! if uphold_connection.missing_card? - uphold_connection.create_uphold_card_for_default_currency + uphold_connection.create_uphold_cards end probi = wallet.referral_balance.amount_probi # probi = balance diff --git a/app/services/uphold/client.rb b/app/services/uphold/client.rb index 6e7db5cff6..0150ba18d2 100644 --- a/app/services/uphold/client.rb +++ b/app/services/uphold/client.rb @@ -4,6 +4,10 @@ def initialize(params = {}) @connection = connection end + def address + @address ||= Uphold::Models::Address.new + end + def card @card ||= Uphold::Models::Card.new end diff --git a/app/services/uphold/models/address.rb b/app/services/uphold/models/address.rb new file mode 100644 index 0000000000..a9a19d762c --- /dev/null +++ b/app/services/uphold/models/address.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'addressable/template' + +module Uphold + module Models + class Address < Client + include Initializable + + # For more information about how these URI templates are structured read the explaination in the RFC + # https://www.rfc-editor.org/rfc/rfc6570.txt + PATH = Addressable::Template.new("/v0/me/cards/{id}/addresses") + + attr_accessor :formats, :type + + def initialize(params = {}) + super + end + + # Lists all the addresses a specified card has + # + # @param [UpholdConnection] connection The uphold connection to find. + # @param [string] iid The id of the card you want to find. + # + # @return [Uphold::Models::Address[]] an array of th addresses + def all(uphold_connection:, id: nil) + Rails.logger.info("Connection #{uphold_connection.id} is missing uphold_access_parameters") and return if uphold_connection.uphold_access_parameters.blank? + id = uphold_connection.address if id.blank? + + response = get(PATH.expand(id: id), {}, authorization(uphold_connection)) + + JSON.parse(response.body).map { |a| Address.new(a) } + end + + # Creates an address for a given card + # + # @param [string] network Network for the card, must be one of ["anonymous", "bitcoin", "bitcoin-cash", "bitcoin-gold", "dash", "ethereum", "litecoin", "voxel", "xrp-ledger"] + # + # @returns the id for the address + def create(uphold_connection:, id:, network: "anonymous") + Rails.logger.info("Connection #{uphold_connection.id} is missing uphold_access_parameters") and return if uphold_connection.uphold_access_parameters.blank? + + response = post(PATH.expand(id: id), { network: network }, authorization(uphold_connection)) + + JSON.parse(response.body).dig('id') + end + + def authorization(uphold_connection) + token = JSON.parse(uphold_connection.uphold_access_parameters || "{}").try(:[], "access_token") + "Authorization: Bearer #{token}" + end + end + end +end diff --git a/app/services/uphold/models/card.rb b/app/services/uphold/models/card.rb index 6eb791d71b..d4373c238c 100644 --- a/app/services/uphold/models/card.rb +++ b/app/services/uphold/models/card.rb @@ -74,6 +74,7 @@ def create(uphold_connection:, currency: nil, label: "Brave Rewards") params = { currency: currency || uphold_connection.default_currency, label: label, + settings: { starred: true }, } response = post(PATH, params, authorization(uphold_connection)) diff --git a/app/views/admin/publishers/_channel.html.slim b/app/views/admin/publishers/_channel.html.slim new file mode 100644 index 0000000000..39f2536b6d --- /dev/null +++ b/app/views/admin/publishers/_channel.html.slim @@ -0,0 +1,135 @@ + +.m-3 class=(channel.verified? ? '' : 'not-verified') + / This is information for this + div + / Container for the title, contributions and referrals + div + / Title + div + small.text-muted TITLE + .d-flex + h5.m-0.font-weight-bold + img src=(channel_type_icon_url(channel)) width=16 height=16 class="mr-3" + = link_to(channel.publication_title, channel.details.url, target: '_blank') + + - if channel.details.is_a?(SiteChannelDetails) + .d-flex.align-items-center + .text-muted.mx-3= "|" + - case channel.details.verification_method + - when "dns_record" + = fa_icon "server", class: 'text-muted' + - when "public_file" + = fa_icon "file-o", class: 'text-muted' + - when "wordpress" + = fa_icon "wordpress", class: 'text-muted' + span.text-muted.ml-2 data-tooltip="Verification method" + = channel.details.verification_method + + - if channel.uphold_connection.blank? && channel.verified? + .mt-3 + .rounded.p-3.alert-warning + .d-flex.align-items-center.mb-2 + =fa_icon "exclamation-circle", class: 'mr-2' + .font-weight-bold This channel does not have an associated Uphold card. + div In newer versions of Brave this channel will no longer appear has verified. In order to resolve this the creator must verify their identity with Uphold. + + + / This is the details and statistics information + - if channel.verified? + .d-flex.mt-3 + div + div + small.text-muted CONTRIBUTIONS + .d-flex + h6.font-weight-bold= publisher_channel_bat_balance(@publisher, channel.details.channel_identifier) + small.ml-1 BAT + + - if channel.promo_registration.present? + div + div.mr-5 + small.text-muted REFERRAL CODE + h6.m-0.font-weight-bold= channel.promo_registration.referral_code + + + .d-flex + - potential_contribution_payment = channel.most_recent_potential_payment + - if potential_contribution_payment.present? + .border-right.mx-3 + .d-flex.flex-column.d-inline-flex + span.mb-1.text-wrap=payout_report_status_header('channel') + small.text-muted AMOUNT + div + span.font-weight-bold= "#{(potential_contribution_payment.amount.to_d * 1/1E18).round(2)}" + small.mt-1.ml-1 BAT + + .d-flex + - if channel.promo_registration.present? + .border-right.mx-3 + div + span Referral Statistics + - totals = channel.promo_registration.aggregate_stats + - if totals.present? + .d-flex + div.mr-3 + small.text-muted DOWNLOADED + .font-weight-bold.text-center= totals[PromoRegistration::RETRIEVALS] + div.mx-3 + small.text-muted INSTALLED + .font-weight-bold.text-center= totals[PromoRegistration::FIRST_RUNS] + div.mx-3 + small.text-muted CONFIRMED + .font-weight-bold.text-center= totals[PromoRegistration::FINALIZED] + + + div + - if channel.details.stats.is_a?(Hash) + .border-right.mx-3 + div + span Channel Statistics + .d-flex + - channel.details.stats.keys.each do |key| + - if channel.details.stats[key].present? && key.exclude?("comment") + div.mx-3.text-center + small.text-muted= "#{key.upcase.gsub("_", " ")}" + .font-weight-bold + = number_with_delimiter(channel.details.stats[key]) + + / When the channel is being contested + - if channel.verification_pending? + small= link_to "Channel is being contested", admin_channel_transfer_path(@publisher) + - elsif !channel.verified? + / Unverified channel, let the admins know + .mt-2 + = fa_icon "exclamation-circle", class: 'mr-2' + span Unverified + + + - if channel.verification_awaiting_admin_approval? + .d-flex.align-items-center + span.text-danger= "Admin approval required" + .admin-approval-button.ml-2 + = form_for channel, as: :channel, method: :patch, url: approve_channel_admin_publishers_path(channel_id: channel.id) do |f| + = f.submit("Approve", class: "btn btn-primary") + - elsif channel.verification_approved_by_admin? + .mt-3 + small.text-muted= "Admin approved" + + - if channel.uphold_connection.present? + + small + a id="view_more_#{channel.id}" href="#" View More + div.toggle.d-none id="more_info_#{channel.id}" + small.text-muted= "UPHOLD CARD" + table.table.small.d-inline-flex + tr + td Card ID + td= channel.uphold_connection.card_id + tr + td Address + td= channel.uphold_connection.address + tr + td Currency + td= channel.uphold_connection.currency + javascript: + document.getElementById("view_more_#{channel.id}").onclick = function anonymous() { document.getElementById("more_info_#{channel.id}").classList.toggle("d-none"); return false; } + diff --git a/app/views/admin/publishers/_uphold.html.slim b/app/views/admin/publishers/_uphold.html.slim index f18b26b979..9765ba01c7 100644 --- a/app/views/admin/publishers/_uphold.html.slim +++ b/app/views/admin/publishers/_uphold.html.slim @@ -29,7 +29,7 @@ h3.text-dark.d-flex.align-items-center = @publisher.uphold_connection.is_member? ? fa_icon("check", text: "Yes") : fa_icon("times", text: "No") tr td Uphold ID - td= link_to @publisher.uphold_connection.uphold_id, admin_publishers_path(q: @publisher.uphold_connection.uphold_id) + td= link_to_if @publisher.uphold_connection.uphold_id, @publisher.uphold_connection.uphold_id, admin_publishers_path(q: @publisher.uphold_connection.uphold_id) tr td Country td= @publisher.uphold_connection.country diff --git a/app/views/admin/publishers/show.html.slim b/app/views/admin/publishers/show.html.slim index ca8c3a8909..805c12c895 100644 --- a/app/views/admin/publishers/show.html.slim +++ b/app/views/admin/publishers/show.html.slim @@ -8,11 +8,13 @@ div.row = submit_tag("Search", class: 'btn btn-default') hr #publisher - #publisher-section + #publisher-section.shadow-sm = render partial: 'admin/shared/publisher_header', locals: { navigation_view: @navigation_view } + .border-top - .rounded-box.split-row-container + .p-4.split-row-container.bg-white .split-row + h5= "Overview" .db-info-row .db-field = "ID:" .db-value = @publisher.id @@ -69,7 +71,7 @@ hr .db-value= @referral_owner_status #statement-section.split-row - h3.admin-header = "Statements" + h5.admin-header = "Statements" .statement = link_to("this month", statement_admin_publishers_path(publisher_id: @publisher.id, statement_period: "this_month")) .statement @@ -78,7 +80,7 @@ hr = link_to("all", statement_admin_publishers_path(publisher_id: @publisher.id, statement_period: "all")) .payout-report-status-section - if @potential_referral_payment.present? - h4= payout_report_status_header('owner') + h5= payout_report_status_header('owner') .db-info-row .db-field = "Uphold status" .db-value = @potential_referral_payment.uphold_status || 'unavailable' @@ -87,7 +89,7 @@ hr .db-field = "Reauthorization status" .db-value = @potential_referral_payment.reauthorization_needed .db-info-row - .db-field = "Uphold membership stattus" + .db-field = "Uphold membership status" .db-value = @potential_referral_payment.uphold_member - if @potential_referral_payment.suspended .db-info-row @@ -101,61 +103,22 @@ hr .db-field = "Approx. amount" .db-value = "#{@potential_referral_payment.amount.to_d * 1/1E18} BAT" - .c-4.shadow-sm.rounded.p-3.my-4 + .c-4.shadow-sm.bg-white.rounded.p-3.my-4 = render partial: 'uphold' -if @publisher.partner? - hr - =render partial: "invoices", locals: { partner: @publisher.becomes(Partner), limit: params[:view_more].present? ? nil : 3 } - - h3.admin-header = "Channels (#{@publisher.channels.count})" - #channels-section - - @publisher.channels.each do |channel| - .channel - .channel-link - = link_to(on_channel_type(channel), channel.details.url) - .channel-info - - if channel.verification_awaiting_admin_approval? - .admin-approval - span.admin-approval-warning = "Admin approval required" - span.admin-approval-button - = form_for channel, as: :channel, method: :patch, url: approve_channel_admin_publishers_path(channel_id: channel.id) do |f| - = f.submit("Approve", class: "btn btn-primary") - hr - - elsif channel.verification_approved_by_admin? - .admin-approval - span.admin-approval-success = "Admin approved" - hr - .db-info-row - .db-field = "Channel BAT balance" - .db-value = publisher_channel_bat_balance(@publisher, channel.details.channel_identifier) - - if channel.details.is_a?(SiteChannelDetails) - .db-info-row - .db-field = "Verified" - .db-value = channel.verified? - .db-info-row - .db-field = "Verification Method" - .db-value = channel.details.verification_method - .db-info-row - .db-field = "Token" - .db-value.token = channel.details.verification_token - - if channel.promo_registration.present? - .db-info-row - .db-field = "Referral code:" - .db-value = channel.promo_registration.referral_code - - if channel.verified? - .payout-report-status-section - - potential_contribution_payment = channel.most_recent_potential_payment - - if potential_contribution_payment.present? - h4= payout_report_status_header('channel') - .db-info-row - .db-field = "Approx. amount" - .db-value = "#{potential_contribution_payment.amount.to_d * 1/1E18} BAT" - + .c-4.shadow-sm.bg-white.rounded.p-3.my-4 + =render partial: "invoices", locals: { partner: @publisher.becomes(Partner), limit: params[:view_more].present? ? nil : 3 } - hr + .c-4.shadow-sm.bg-white.rounded.p-3.my-4 + h3.text-dark Channels + #channels-section + - @publisher.channels.each do |channel| + = render partial: 'channel', locals: { channel: channel } + - unless channel == @publisher.channels.last + hr - .c-4.shadow-sm.rounded.p-3.accordion.mb-4 + .c-4.shadow-sm.bg-white.rounded.p-3.my-4 .panel input type="checkbox" name="panels" id="panel_id" label for="panel_id" @@ -164,7 +127,7 @@ hr = render partial: 'admin/publisher_notes/form', locals: { note: PublisherNote.new, publisher: @publisher } - .c-4.shadow-sm.rounded.p-3.mt-4 + .c-4.shadow-sm.bg-white.rounded.p-3.my-4 h3.text-dark.d-flex.align-items-center small=fa_icon "hourglass-half", class: 'mx-2' = "History" @@ -184,5 +147,12 @@ hr +javascript: + window.addEventListener("keydown",function (e) { + if ((e.ctrlKey || e.metaKey) && e.keyCode === 70) { + document.querySelectorAll('.toggle').forEach((i) => i.classList.toggle('d-none')) + } + }) + = javascript_pack_tag 'tribute' = stylesheet_pack_tag 'tribute' diff --git a/app/views/admin/shared/_publisher_header.html.slim b/app/views/admin/shared/_publisher_header.html.slim index 73be8b7bd2..2bf3045567 100644 --- a/app/views/admin/shared/_publisher_header.html.slim +++ b/app/views/admin/shared/_publisher_header.html.slim @@ -1,2 +1,2 @@ =javascript_pack_tag "UserNavbar" -.mt-5.mb-3#publisherHeader data-props=navigation_view +.mt-5#publisherHeader data-props=navigation_view diff --git a/app/views/publishers/_channel.html.slim b/app/views/publishers/_channel.html.slim index 85388b261f..b040f006f5 100644 --- a/app/views/publishers/_channel.html.slim +++ b/app/views/publishers/_channel.html.slim @@ -1,90 +1,92 @@ .row.channel-row id=("channel_row_#{channel.id}") data-remove-message=(t("shared.channel_removed")) .col.mb-4 div class=("channel-panel channel-#{channel_verification_status(channel)}") - .channel-panel--intro + .channel-panel--intro.mb-1 .channel-panel--intro-icon img src=(channel_type_icon_url(channel)) width=16 height=16 .channel-panel--intro-body = channel_type(channel).upcase - - if channel.verified? - - if current_publisher.promo_status(promo_running?) == :active && channel.promo_enabled? && !current_publisher.only_user_funds? - .channel--promo-info-container - = link_to("", tweet_url(channel.promo_registration.referral_code), target: :_blank, class: "promo-share-button promo-share-button-twitter") - = link_to("", facebook_url(channel.promo_registration.referral_code), target: :_blank, class: "promo-share-button promo-share-button-facebook") - .referral-link-url.promo-info-item - span= https_referral_url(channel.promo_registration.referral_code) - .referral-link-button.referral-link-button-desktop.promo-info-item - span= t("promo.shared.referral_link") - .referral-link-button.referral-link-button-mobile.promo-info-item.copy-button data-clipboard-text="#{https_referral_url(channel.promo_registration.referral_code)}" - span= t("promo.shared.referral_link") - .referral-link-copy-button.promo-info-item.copy-button data-clipboard-text="#{https_referral_url(channel.promo_registration.referral_code)}" - span= t("promo.shared.copy") - / Need to tell the users that it will take 48 hours for their verified channel to appear in the web browser - - if channel.created_at > 2.days.ago - .channel-info - .info-popup - .info--details - // JS will break if the next two elements aren't siblings - span.info--what-happened=t(".verification_status_title") - span.info--explanation - span.verification-failed-explanation--content - = t(".verification_status") - - else - .channel-status.float-right + + .d-flex.justify-content-between.align-items-center.flex-wrap + / Channel name + div.my-1 + .channel-summary + h3.text-truncate= channel.publication_title + + / The secondary information on the tile, balance, etc + div.channel-secondary-information.d-flex.justify-content-between + / Show the balance if the channel has been verified + - if channel.verified? .bat-channel h4.bat-channel--amount id=("channel_amount_bat_#{channel.details.channel_identifier}") = publisher_channel_bat_balance(current_publisher, channel.details.channel_identifier) span.bat-channel--currency= " BAT" .bat-channel--period - = t(".channel_balance_period") - .channel-summary - h3= channel.publication_title - .channel-details - .added-date - = t(".added", date: channel.created_at.to_date.iso8601) - span.separator - = ' | ' - a.remove-channel href="#" data-channel-id=(channel.id) - = t(".remove_verified") - script type="text/html" data-js-channel-removal-confirmation-template=(channel.id) - = render "publishers/remove_channel_modal", channel: channel - = form_for(channel, html: {id: "remove_channel_#{channel.id}"}) do |f| - - elsif channel.verification_failed? - .channel-status.float-right - .verification-failed - .verification-failed--header - = t("helpers.channels.verification_failure") - .verification-failed--details - // JS will break if the next two elements aren't siblings - span.verification-failed--what-happened=t("helpers.channels.verification_failure_what_happened") - span.verification-failed--explanation - span.verification-failed-explanation--content - = channel_verification_details(channel).upcase_first - span.separator - = ' | ' - a.remove-channel href="#" data-channel-id=(channel.id) - = t(".remove_verified") - script type="text/html" data-js-channel-removal-confirmation-template=(channel.id) - = render "publishers/remove_channel_modal", channel: channel - = form_for(channel, html: {id: "remove_channel_#{channel.id}"}) do |f| - = link_to(t(".try_again"), channel_next_step_path(channel), class: "btn btn-primary try-again") - - elsif channel.verification_pending? - .channel-status.float-right - = t("shared.channel_contested", time_until_transfer: time_until_transfer(channel)) - - elsif channel.verification_awaiting_admin_approval? - .channel-status.float-right - = t("helpers.channels.verification_awaiting_admin_approval") - - else - .channel-status.float-right - = link_to(t(".lets_finish"), channel_next_step_path(channel), class: "btn btn-primary") - .channel-progress.float-right - .one-more-step= t(".one_more_step") - - unless channel.verified - .channel-summary - h3.unverified = channel.publication_title + small= t(".channel_balance_period") + + / Show the promo registration if the promo is running + - if current_publisher.promo_status(promo_running?) == :active && channel.promo_enabled? && !current_publisher.only_user_funds? + .d-flex.channel--promo-info-container.ml-3 + .d-none.d-sm-block + = link_to("", tweet_url(channel.promo_registration.referral_code), target: :_blank, class: "promo-share-button promo-share-button-twitter") + = link_to("", facebook_url(channel.promo_registration.referral_code), target: :_blank, class: "promo-share-button promo-share-button-facebook") + div + .referral-link-url.promo-info-item + span= https_referral_url(channel.promo_registration.referral_code) + .referral-link-button.referral-link-button-desktop.promo-info-item + span= t("promo.shared.referral_link") + .referral-link-button.referral-link-button-mobile.promo-info-item.copy-button data-clipboard-text="#{https_referral_url(channel.promo_registration.referral_code)}" + span= t("promo.shared.referral_link") + .referral-link-copy-button.promo-info-item.copy-button data-clipboard-text="#{https_referral_url(channel.promo_registration.referral_code)}" + span= t("promo.shared.copy") + + / If the verification failed we should tell the user + - if channel.verification_failed? + .channel-status + .verification-failed + .verification-failed--header + = t("helpers.channels.verification_failure") + .verification-failed--details + // JS will break if the next two elements aren't siblings + span.verification-failed--what-happened=t("helpers.channels.verification_failure_what_happened") + span.verification-failed--explanation + span.verification-failed-explanation--content + = channel_verification_details(channel).upcase_first + .ml-2 + = link_to(t(".try_again"), channel_next_step_path(channel), class: "btn btn-primary try-again") + + + - if channel.verification_pending? + span.channel-contested= t("shared.channel_contested", time_until_transfer: time_until_transfer(channel)) + - elsif channel.verification_awaiting_admin_approval? + = t("helpers.channels.verification_awaiting_admin_approval") + - elsif !channel.verified? && !channel.verification_failed? + .channel-progress + .one-more-step= t(".one_more_step") + .channel-status + = link_to(t(".lets_finish"), channel_next_step_path(channel), class: "btn btn-primary") + + .d-flex.flex-wrap + .added-date.d-none.d-sm-block + = t(".added", date: channel.created_at.to_date.iso8601) + span.mx-2= ' | ' + - if channel.uphold_connection.present? + =image_tag 'uphold.svg', style: "width: 18px; height: 18px; margin-top: 3px;" + =link_to(t('.uphold'), "#{uphold_dashboard_url}/cards/#{channel.uphold_connection.card_id}", class: 'px-1', target: "_blank") + span.mx-2 + = ' | ' + a.remove-channel href="#" data-channel-id=(channel.id) + = t(".remove_verified") + script type="text/html" data-js-channel-removal-confirmation-template=(channel.id) + = render "publishers/remove_channel_modal", channel: channel + = form_for(channel, html: {id: "remove_channel_#{channel.id}"}) do |f| + + + - if channel.contested_by_channel .channel-contested p = t "shared.channel_contested_by", time_until_transfer: time_until_transfer(channel.contested_by_channel), verified_by_email: channel.contested_by_channel.publisher.email a.reject_transfer href=token_reject_transfer_url(channel, channel.contest_token) = t ".reject_transfer" + diff --git a/app/views/static/index.html b/app/views/static/index.html index 75034cedd0..d8b2566450 100644 --- a/app/views/static/index.html +++ b/app/views/static/index.html @@ -1 +1 @@ -Earn more for content you publish to the web - Brave Creators
Brave
\ No newline at end of file +Earn more for content you publish to the web - Brave Creators
Brave
\ No newline at end of file diff --git a/config/locales/en.yml b/config/locales/en.yml index 15dcca7806..381b08330b 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -609,13 +609,15 @@ en: update: Update channel: added: added %{date} - remove_verified: Remove Channel + remove_verified: Remove channel one_more_step: One more step to complete... - lets_finish: Let's Finish - try_again: Try Again + lets_finish: Let's finish + try_again: Try again verification_status: Verification status will be displayed in the Brave browser within the next 24-48 hours verification_status_title: Verification Information channel_balance_period: CURRENT PERIOD + uphold: Uphold + reject_transfer: Reject transfer omniauth_callbacks: register_youtube_channel: channel_already_registered: You have already registered this YouTube channel. diff --git a/db/migrate/20190730162819_create_uphold_connection_for_channel.rb b/db/migrate/20190730162819_create_uphold_connection_for_channel.rb new file mode 100644 index 0000000000..b3220f17df --- /dev/null +++ b/db/migrate/20190730162819_create_uphold_connection_for_channel.rb @@ -0,0 +1,15 @@ +class CreateUpholdConnectionForChannel < ActiveRecord::Migration[5.2] + def change + create_table :uphold_connection_for_channels, id: :uuid, default: -> { "uuid_generate_v4()"}, force: :cascade do |t| + t.belongs_to :uphold_connection, type: :uuid, index: true, null: false + t.belongs_to :channel, type: :uuid, index: true, null: false + + t.string :currency, index: true + t.string :channel_identifier, index: true + t.string :card_id + t.string :address + end + + add_index :uphold_connection_for_channels, [:channel_identifier, :currency, :uphold_connection_id], unique: true, name: 'unique_uphold_connection_for_channels' + end +end diff --git a/db/schema.rb b/db/schema.rb index 9fc89cfc63..ac7aadd90c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_07_17_030948) do +ActiveRecord::Schema.define(version: 2019_07_30_162819) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -505,6 +505,20 @@ t.index ["publisher_id"], name: "index_u2f_registrations_on_publisher_id" end + create_table "uphold_connection_for_channels", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t| + t.uuid "uphold_connection_id", null: false + t.uuid "channel_id", null: false + t.string "currency" + t.string "channel_identifier" + t.string "card_id" + t.string "address" + t.index ["channel_id"], name: "index_uphold_connection_for_channels_on_channel_id" + t.index ["channel_identifier", "currency", "uphold_connection_id"], name: "unique_uphold_connection_for_channels", unique: true + t.index ["channel_identifier"], name: "index_uphold_connection_for_channels_on_channel_identifier" + t.index ["currency"], name: "index_uphold_connection_for_channels_on_currency" + t.index ["uphold_connection_id"], name: "index_uphold_connection_for_channels_on_uphold_connection_id" + end + create_table "uphold_connections", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t| t.string "uphold_state_token" t.boolean "uphold_verified", default: false diff --git a/lib/tasks/database_updates/create_cards_for_channels.rake b/lib/tasks/database_updates/create_cards_for_channels.rake new file mode 100644 index 0000000000..f211b702dc --- /dev/null +++ b/lib/tasks/database_updates/create_cards_for_channels.rake @@ -0,0 +1,16 @@ +namespace :database_updates do + task :create_cards_for_channels => :environment do + + completed_kyc = UpholdConnection.where(is_member: true) + + puts "Queueing up create cards for #{completed_kyc.size} users" + completed_kyc.each do |connection| + next unless connection.can_create_uphold_cards? + + connection.publisher.channels.each do |channel| + CreateUpholdChannelCardJob.perform_later(uphold_connection_id: connection.id, channel_id: channel.id) + end + end + puts 'Done!' + end +end diff --git a/lib/tasks/database_updates/mock_data.rake b/lib/tasks/database_updates/mock_data.rake index eefaee3647..591c1c45bf 100644 --- a/lib/tasks/database_updates/mock_data.rake +++ b/lib/tasks/database_updates/mock_data.rake @@ -9,6 +9,19 @@ namespace :database_updates do PromoRegistration.find_each do |promo| stats = [REFERRAL_CODES_1, REFERRAL_CODES_2].sample stats = stats.each { |x| x["referral_code"] = promo.referral_code } + + date = Date.today + entry = stats.reverse.each_slice(2).map do |a, b| + next if a.nil? + a["ymd"] = date + next if b.nil? + b["ymd"] = date + + date -= 1.day + + [a, b] + end.flatten + promo.stats = stats.to_json if promo.save puts "Saved stats to promo #{promo.referral_code}" diff --git a/public/asset-manifest.json b/public/asset-manifest.json index 8544d89ff0..6db2b4d44f 100644 --- a/public/asset-manifest.json +++ b/public/asset-manifest.json @@ -1,6 +1,6 @@ { "files": { - "main.css": "/static/css/main.dec8ec33.chunk.css", + "main.css": "/static/css/main.35597b27.chunk.css", "main.js": "/static/js/main.71177221.chunk.js", "main.js.map": "/static/js/main.71177221.chunk.js.map", "runtime~main.js": "/static/js/runtime~main.a8a9905a.js", @@ -8,9 +8,9 @@ "static/js/2.afab0b54.chunk.js": "/static/js/2.afab0b54.chunk.js", "static/js/2.afab0b54.chunk.js.map": "/static/js/2.afab0b54.chunk.js.map", "index.html": "/index.html", - "precache-manifest.c6b8c25924c72c5e54d05623453f02ae.js": "/precache-manifest.c6b8c25924c72c5e54d05623453f02ae.js", + "precache-manifest.c565935f291e217d63c168970232e219.js": "/precache-manifest.c565935f291e217d63c168970232e219.js", "service-worker.js": "/service-worker.js", - "static/css/main.dec8ec33.chunk.css.map": "/static/css/main.dec8ec33.chunk.css.map", + "static/css/main.35597b27.chunk.css.map": "/static/css/main.35597b27.chunk.css.map", "static/media/brave-rewards-creators-logo.svg": "/static/media/brave-rewards-creators-logo.74b29633.svg", "static/media/brave-rewards-creators-mobile-logo.svg": "/static/media/brave-rewards-creators-mobile-logo.58394134.svg", "static/media/built-with-bat-pill.svg": "/static/media/built-with-bat-pill.f4c2d5ec.svg", diff --git a/public/precache-manifest.c6b8c25924c72c5e54d05623453f02ae.js b/public/precache-manifest.c565935f291e217d63c168970232e219.js similarity index 89% rename from public/precache-manifest.c6b8c25924c72c5e54d05623453f02ae.js rename to public/precache-manifest.c565935f291e217d63c168970232e219.js index f5339bc352..be42f7f9f4 100644 --- a/public/precache-manifest.c6b8c25924c72c5e54d05623453f02ae.js +++ b/public/precache-manifest.c565935f291e217d63c168970232e219.js @@ -1,18 +1,18 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ { - "revision": "78734c31a3dc41ceb14ddf16f6f534ea", + "revision": "4185b1e2898c3e2e8889ec5078c1f57d", "url": "/index.html" }, { - "revision": "14c941efab2dc136810e", - "url": "/static/css/main.dec8ec33.chunk.css" + "revision": "be4f1a1897ae818cee38", + "url": "/static/css/main.35597b27.chunk.css" }, { "revision": "0714d1baebf2047752cb", "url": "/static/js/2.afab0b54.chunk.js" }, { - "revision": "14c941efab2dc136810e", + "revision": "be4f1a1897ae818cee38", "url": "/static/js/main.71177221.chunk.js" }, { diff --git a/public/service-worker.js b/public/service-worker.js index eb4a2db352..f967dbbe2f 100644 --- a/public/service-worker.js +++ b/public/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.0/workbox-sw.js"); importScripts( - "/precache-manifest.c6b8c25924c72c5e54d05623453f02ae.js" + "/precache-manifest.c565935f291e217d63c168970232e219.js" ); self.addEventListener('message', (event) => { diff --git a/public/static/css/main.dec8ec33.chunk.css b/public/static/css/main.35597b27.chunk.css similarity index 52% rename from public/static/css/main.dec8ec33.chunk.css rename to public/static/css/main.35597b27.chunk.css index 5902a64b81..90c3b71554 100644 --- a/public/static/css/main.dec8ec33.chunk.css +++ b/public/static/css/main.35597b27.chunk.css @@ -1,2 +1,2 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}h1,h2,h3,h4,h5,h6{font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,"sans-serif",Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}body,p{line-height:1.6!important}h4{font-weight:400!important}.main-btns{align-items:center;display:flex;flex-wrap:wrap}#nav{position:absolute;top:0;width:100%;z-index:400}.carousel-container{margin-bottom:60px}@media (max-width:960px){.carousel-container{flex-direction:column-reverse!important}}#carousel-img{z-index:400;max-width:500px;align-self:center;max-height:300px}#carousel-img img,#signoff img{max-width:100%;max-height:100%}.carousel-quote{min-width:300px;max-width:700px}#row-reverse{flex-direction:row-reverse}.top-swoop{top:-2px}.bottom-swoop,.top-swoop{position:absolute;width:100vw!important}.bottom-swoop{bottom:-2px;z-index:0}.terms-help{position:absolute;bottom:60px;left:72px;color:#b6b6b6}.terms-help a{font-size:14px}.terms-help img{display:none}@media (max-width:840px){.terms-help{position:absolute;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.terms-help img{display:flex}}.sign-icon{padding:8px;display:flex;border-radius:40px;margin:4px}.sign-icon svg{height:32px;width:32px}.sign-icon:hover{background:rgba(0,0,0,.2)}.confetti-overflow{position:relative}.bat-pill img{display:none;height:24px}@media (max-width:840px){.bat-pill img{display:flex;align-self:flex-start;margin:0 0 18px}}#zindex{z-index:2}.fade{position:absolute;bottom:0;width:100%;z-index:0;opacity:.05}.email-input{display:flex;flex-direction:column}@media (max-width:720px){.notification-layer{width:96%}}.summary-spacer{height:100px}@media (min-width:1200px){.summary-spacer{height:200px}}.spacer{display:flex;height:60px}.icon{height:180px}.bat-svg{overflow:visible}.circle{-webkit-animation:pulse 1.3s infinite alternate;animation:pulse 1.3s infinite alternate;z-index:30}.circle2{-webkit-animation:pulse 1.7s infinite alternate;animation:pulse 1.7s infinite alternate;z-index:30}.circle-delay{-webkit-animation:pulse 2.2s infinite alternate;animation:pulse 2.2s infinite alternate;z-index:30}.circle-delay2{-webkit-animation:pulse 2.6s infinite alternate;animation:pulse 2.6s infinite alternate;z-index:30}@-webkit-keyframes pulse{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition-timing-function:ease;transition-timing-function:ease}to{opacity:1;-webkit-transform:translateY(4px);transform:translateY(4px);-webkit-transition-timing-function:ease;transition-timing-function:ease}}@keyframes pulse{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition-timing-function:ease;transition-timing-function:ease}to{opacity:1;-webkit-transform:translateY(4px);transform:translateY(4px);-webkit-transition-timing-function:ease;transition-timing-function:ease}}a{text-decoration:none} -/*# sourceMappingURL=main.dec8ec33.chunk.css.map */ \ No newline at end of file +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}h1,h2,h3,h4,h5,h6{font-family:Poppins,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,"sans-serif",Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol}body,p{line-height:1.6!important}h4{font-weight:400!important}.main-btns{align-items:center;display:flex;flex-wrap:wrap}#nav{position:absolute;top:0;width:100%;z-index:400}.carousel-container{margin-bottom:60px}@media (max-width:960px){.carousel-container{flex-direction:column-reverse!important}}#carousel-img{z-index:400;max-width:500px;align-self:center;max-height:300px}#carousel-img img,#signoff img{max-width:100%;max-height:100%}.carousel-quote{min-width:300px;max-width:700px}#row-reverse{flex-direction:row-reverse}.top-swoop{position:absolute;top:-2px;width:100%!important}.bottom-swoop{position:absolute;bottom:-2px;width:100vw!important;z-index:0}.terms-help{position:absolute;bottom:60px;left:72px;color:#b6b6b6}.terms-help a{font-size:14px}.terms-help img{display:none}@media (max-width:840px){.terms-help{position:absolute;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.terms-help img{display:flex}}.sign-icon{padding:8px;display:flex;border-radius:40px;margin:4px}.sign-icon svg{height:32px;width:32px}.sign-icon:hover{background:rgba(0,0,0,.2)}.confetti-overflow{position:relative}.bat-pill img{display:none;height:24px}@media (max-width:840px){.bat-pill img{display:flex;align-self:flex-start;margin:0 0 18px}}#zindex{z-index:2}.fade{position:absolute;bottom:0;width:100%;z-index:0;opacity:.05}.email-input{display:flex;flex-direction:column}@media (max-width:720px){.notification-layer{width:96%}}.summary-spacer{height:100px}@media (min-width:1200px){.summary-spacer{height:200px}}.spacer{display:flex;height:60px}.icon{height:180px}.bat-svg{overflow:visible}.circle{-webkit-animation:pulse 1.3s infinite alternate;animation:pulse 1.3s infinite alternate;z-index:30}.circle2{-webkit-animation:pulse 1.7s infinite alternate;animation:pulse 1.7s infinite alternate;z-index:30}.circle-delay{-webkit-animation:pulse 2.2s infinite alternate;animation:pulse 2.2s infinite alternate;z-index:30}.circle-delay2{-webkit-animation:pulse 2.6s infinite alternate;animation:pulse 2.6s infinite alternate;z-index:30}@-webkit-keyframes pulse{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition-timing-function:ease;transition-timing-function:ease}to{opacity:1;-webkit-transform:translateY(4px);transform:translateY(4px);-webkit-transition-timing-function:ease;transition-timing-function:ease}}@keyframes pulse{0%{opacity:0;-webkit-transform:translateY(0);transform:translateY(0);-webkit-transition-timing-function:ease;transition-timing-function:ease}to{opacity:1;-webkit-transform:translateY(4px);transform:translateY(4px);-webkit-transition-timing-function:ease;transition-timing-function:ease}}a{text-decoration:none} +/*# sourceMappingURL=main.35597b27.chunk.css.map */ \ No newline at end of file diff --git a/public/static/css/main.35597b27.chunk.css.map b/public/static/css/main.35597b27.chunk.css.map new file mode 100644 index 0000000000..02d42062d6 --- /dev/null +++ b/public/static/css/main.35597b27.chunk.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["normalize-style.css","style.css"],"names":[],"mappings":"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","file":"main.35597b27.chunk.css","sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15;\n /* 1 */\n -webkit-text-size-adjust: 100%;\n /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box;\n /* 1 */\n height: 0;\n /* 1 */\n overflow: visible;\n /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace;\n /* 1 */\n font-size: 1em;\n /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none;\n /* 1 */\n text-decoration: underline;\n /* 2 */\n text-decoration: underline dotted;\n /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n /* 1 */\n font-size: 1em;\n /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit;\n /* 1 */\n font-size: 100%;\n /* 1 */\n line-height: 1.15;\n /* 1 */\n margin: 0;\n /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput {\n /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect {\n /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box;\n /* 1 */\n color: inherit;\n /* 2 */\n display: table;\n /* 1 */\n max-width: 100%;\n /* 1 */\n padding: 0;\n /* 3 */\n white-space: normal;\n /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box;\n /* 1 */\n padding: 0;\n /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield;\n /* 1 */\n outline-offset: -2px;\n /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button;\n /* 1 */\n font: inherit;\n /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}","h1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-family: \"Poppins\", \"-apple-system\", \"BlinkMacSystemFont\", \"Segoe UI\",\n \"Helvetica\", \"Arial\", \"sans-serif\", \"Apple Color Emoji\", \"Segoe UI Emoji\",\n \"Segoe UI Symbol\";\n}\n\n/* correct the tight line height on Muli */\n\nbody,\np {\n line-height: 1.6 !important;\n}\n\nh4 {\n font-weight: 400 !important;\n}\n\n/* Main section styling */\n\n.main-btns {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n}\n\n#nav {\n position: absolute;\n top: 0;\n width: 100%;\n z-index: 400;\n}\n\n.carousel-container {\n margin-bottom: 60px;\n}\n\n@media (max-width: 960px) {\n .carousel-container {\n flex-direction: column-reverse !important;\n }\n}\n\n#carousel-img {\n z-index: 400;\n max-width: 500px;\n align-self: center;\n max-height: 300px;\n}\n\n#carousel-img img {\n max-width: 100%;\n max-height: 100%;\n}\n\n#signoff img {\n max-width: 100%;\n max-height: 100%;\n}\n\n.carousel-quote {\n min-width: 300px;\n max-width: 700px;\n}\n\n/* reverses the order of the carousel divs */\n\n#row-reverse {\n flex-direction: row-reverse;\n}\n\n/* swoop positioning */\n\n.top-swoop {\n position: absolute;\n top: -2px;\n width: 100% !important;\n}\n\n.bottom-swoop {\n position: absolute;\n bottom: -2px;\n width: 100vw !important;\n z-index: 0;\n}\n\n/* Terms in Signup and Signin */\n\n.terms-help {\n position: absolute;\n bottom: 60px;\n left: 72px;\n color: rgb(182, 182, 182);\n}\n\n.terms-help a {\n font-size: 14px;\n}\n\n.terms-help img {\n display: none;\n}\n\n@media (max-width: 840px) {\n .terms-help {\n position: absolute;\n left: 50%;\n transform: translate(-50%, -50%);\n width: fit-content;\n }\n\n .terms-help img {\n display: flex;\n }\n}\n\n.sign-icon {\n padding: 8px;\n display: flex;\n border-radius: 40px;\n margin: 4px;\n}\n\n.sign-icon svg {\n height: 32px;\n width: 32px;\n}\n\n.sign-icon:hover {\n background: rgba(0, 0, 0, 0.2);\n}\n\n.confetti-overflow {\n position: relative;\n}\n\n/* Responsive BAT pill changes oh landing main section */\n\n.bat-pill img {\n display: none;\n height: 24px;\n}\n\n@media (max-width: 840px) {\n .bat-pill img {\n display: flex;\n align-self: flex-start;\n margin: 0 0 18px;\n }\n}\n\n#zindex {\n z-index: 2;\n}\n\n.fade {\n position: absolute;\n bottom: 0;\n width: 100%;\n z-index: 0;\n opacity: 0.05;\n}\n\n.email-input {\n display: flex;\n flex-direction: column;\n}\n\n@media (max-width: 720px) {\n .notification-layer {\n width: 96%;\n }\n}\n\n.summary-spacer {\n height: 100px;\n}\n\n@media (min-width: 1200px) {\n .summary-spacer {\n height: 200px;\n }\n}\n\n.spacer {\n display: flex;\n height: 60px;\n}\n\n/* BAT Logo Animation */\n.icon {\n height: 180px;\n}\n\n.bat-svg {\n overflow: visible;\n}\n\n.circle {\n animation: pulse 1.3s alternate infinite;\n z-index: 30;\n}\n\n.circle2 {\n animation: pulse 1.7s alternate infinite;\n z-index: 30;\n}\n\n.circle-delay {\n animation: pulse 2.2s alternate infinite;\n z-index: 30;\n}\n\n.circle-delay2 {\n animation: pulse 2.6s alternate infinite;\n z-index: 30;\n}\n\n@keyframes pulse {\n 0% {\n opacity: 0;\n transform: translateY(0);\n transition-timing-function: ease;\n }\n\n 100% {\n opacity: 1;\n transform: translateY(4px);\n transition-timing-function: ease;\n }\n}\n\na {\n text-decoration: none;\n}\n"]} \ No newline at end of file diff --git a/public/static/css/main.dec8ec33.chunk.css.map b/public/static/css/main.dec8ec33.chunk.css.map deleted file mode 100644 index af7bc1c6b7..0000000000 --- a/public/static/css/main.dec8ec33.chunk.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["normalize-style.css","style.css"],"names":[],"mappings":"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","file":"main.dec8ec33.chunk.css","sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15;\n /* 1 */\n -webkit-text-size-adjust: 100%;\n /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box;\n /* 1 */\n height: 0;\n /* 1 */\n overflow: visible;\n /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace;\n /* 1 */\n font-size: 1em;\n /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none;\n /* 1 */\n text-decoration: underline;\n /* 2 */\n text-decoration: underline dotted;\n /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace;\n /* 1 */\n font-size: 1em;\n /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit;\n /* 1 */\n font-size: 100%;\n /* 1 */\n line-height: 1.15;\n /* 1 */\n margin: 0;\n /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput {\n /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect {\n /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box;\n /* 1 */\n color: inherit;\n /* 2 */\n display: table;\n /* 1 */\n max-width: 100%;\n /* 1 */\n padding: 0;\n /* 3 */\n white-space: normal;\n /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box;\n /* 1 */\n padding: 0;\n /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield;\n /* 1 */\n outline-offset: -2px;\n /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button;\n /* 1 */\n font: inherit;\n /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}","h1,\nh2,\nh3,\nh4,\nh5,\nh6 {\n font-family: \"Poppins\", \"-apple-system\", \"BlinkMacSystemFont\", \"Segoe UI\",\n \"Helvetica\", \"Arial\", \"sans-serif\", \"Apple Color Emoji\", \"Segoe UI Emoji\",\n \"Segoe UI Symbol\";\n}\n\n/* correct the tight line height on Muli */\n\nbody,\np {\n line-height: 1.6 !important;\n}\n\nh4 {\n font-weight: 400 !important;\n}\n\n/* Main section styling */\n\n.main-btns {\n align-items: center;\n display: flex;\n flex-wrap: wrap;\n}\n\n#nav {\n position: absolute;\n top: 0;\n width: 100%;\n z-index: 400;\n}\n\n.carousel-container {\n margin-bottom: 60px;\n}\n\n@media (max-width: 960px) {\n .carousel-container {\n flex-direction: column-reverse !important;\n }\n}\n\n#carousel-img {\n z-index: 400;\n max-width: 500px;\n align-self: center;\n max-height: 300px;\n}\n\n#carousel-img img {\n max-width: 100%;\n max-height: 100%;\n}\n\n#signoff img {\n max-width: 100%;\n max-height: 100%;\n}\n\n.carousel-quote {\n min-width: 300px;\n max-width: 700px;\n}\n\n/* reverses the order of the carousel divs */\n\n#row-reverse {\n flex-direction: row-reverse;\n}\n\n/* swoop positioning */\n\n.top-swoop {\n position: absolute;\n top: -2px;\n width: 100vw !important;\n}\n\n.bottom-swoop {\n position: absolute;\n bottom: -2px;\n width: 100vw !important;\n z-index: 0;\n}\n\n/* Terms in Signup and Signin */\n\n.terms-help {\n position: absolute;\n bottom: 60px;\n left: 72px;\n color: rgb(182, 182, 182);\n}\n\n.terms-help a {\n font-size: 14px;\n}\n\n.terms-help img {\n display: none;\n}\n\n@media (max-width: 840px) {\n .terms-help {\n position: absolute;\n left: 50%;\n transform: translate(-50%, -50%);\n width: fit-content;\n }\n\n .terms-help img {\n display: flex;\n }\n}\n\n.sign-icon {\n padding: 8px;\n display: flex;\n border-radius: 40px;\n margin: 4px;\n}\n\n.sign-icon svg {\n height: 32px;\n width: 32px;\n}\n\n.sign-icon:hover {\n background: rgba(0, 0, 0, 0.2);\n}\n\n.confetti-overflow {\n position: relative;\n}\n\n/* Responsive BAT pill changes oh landing main section */\n\n.bat-pill img {\n display: none;\n height: 24px;\n}\n\n@media (max-width: 840px) {\n .bat-pill img {\n display: flex;\n align-self: flex-start;\n margin: 0 0 18px;\n }\n}\n\n#zindex {\n z-index: 2;\n}\n\n.fade {\n position: absolute;\n bottom: 0;\n width: 100%;\n z-index: 0;\n opacity: 0.05;\n}\n\n.email-input {\n display: flex;\n flex-direction: column;\n}\n\n@media (max-width: 720px) {\n .notification-layer {\n width: 96%;\n }\n}\n\n.summary-spacer {\n height: 100px;\n}\n\n@media (min-width: 1200px) {\n .summary-spacer {\n height: 200px;\n }\n}\n\n.spacer {\n display: flex;\n height: 60px;\n}\n\n/* BAT Logo Animation */\n.icon {\n height: 180px;\n}\n\n.bat-svg {\n overflow: visible;\n}\n\n.circle {\n animation: pulse 1.3s alternate infinite;\n z-index: 30;\n}\n\n.circle2 {\n animation: pulse 1.7s alternate infinite;\n z-index: 30;\n}\n\n.circle-delay {\n animation: pulse 2.2s alternate infinite;\n z-index: 30;\n}\n\n.circle-delay2 {\n animation: pulse 2.6s alternate infinite;\n z-index: 30;\n}\n\n@keyframes pulse {\n 0% {\n opacity: 0;\n transform: translateY(0);\n transition-timing-function: ease;\n }\n\n 100% {\n opacity: 1;\n transform: translateY(4px);\n transition-timing-function: ease;\n }\n}\n\na {\n text-decoration: none;\n}\n"]} \ No newline at end of file diff --git a/test/controllers/admin/payout_reports_controller_test.rb b/test/controllers/admin/payout_reports_controller_test.rb index 2f26364856..005fb144d1 100644 --- a/test/controllers/admin/payout_reports_controller_test.rb +++ b/test/controllers/admin/payout_reports_controller_test.rb @@ -11,6 +11,11 @@ class PayoutReportsControllerTest < ActionDispatch::IntegrationTest before do @prev_eyeshade_offline = Rails.application.secrets[:api_eyeshade_offline] stub_request(:get, uphold_url).to_return(body: { status: "ok", memberAt: "2019", uphold_id: "123e4567-e89b-12d3-a456-426655440000" }.to_json) + + # Mock out the creation of cards + stub_request(:get, /cards/).to_return(body: [id: "fb25048b-79df-4e64-9c4e-def07c8f5c04"].to_json) + stub_request(:post, /cards/).to_return(body: { id: "fb25048b-79df-4e64-9c4e-def07c8f5c04" }.to_json) + stub_request(:get, /address/).to_return(body: [{ formats: [{ format: "uuid", value: "e306ec64-461b-4723-bf75-015ffc99ebe1" }], type: "anonymous" }].to_json) end after do diff --git a/test/controllers/channel_transfer_controller_test.rb b/test/controllers/channel_transfer_controller_test.rb index 89e6cae3b1..410bf493c9 100644 --- a/test/controllers/channel_transfer_controller_test.rb +++ b/test/controllers/channel_transfer_controller_test.rb @@ -13,24 +13,24 @@ class ChannelTransferControllerTest < ActionDispatch::IntegrationTest # contest channel Channels::ContestChannel.new(channel: channel, contested_by: contested_by_channel).perform - assert_enqueued_jobs(4) do + assert_enqueued_jobs(5) do get token_reject_transfer_path(channel, channel.contest_token) end assert_redirected_to home_publishers_path - assert_equal I18n.t("shared.channel_transfer_rejected"), flash[:notice] + assert_equal I18n.t("shared.channel_transfer_rejected"), flash[:notice] end test "#rejects_transfer does not go thorugh and redirects to home with fake contest token" do channel = channels(:fraudulently_verified_site) contested_by_channel = channels(:locked_out_site) - + # contest channel Channels::ContestChannel.new(channel: channel, contested_by: contested_by_channel).perform get token_reject_transfer_path(channel, "fake token") assert response.status, 404 assert_redirected_to home_publishers_path - assert_equal I18n.t("shared.channel_not_found"), flash[:notice] + assert_equal I18n.t("shared.channel_not_found"), flash[:notice] end end diff --git a/test/controllers/publishers/omniauth_callbacks_controller_test.rb b/test/controllers/publishers/omniauth_callbacks_controller_test.rb index b5267101d4..1dd06a5cf9 100644 --- a/test/controllers/publishers/omniauth_callbacks_controller_test.rb +++ b/test/controllers/publishers/omniauth_callbacks_controller_test.rb @@ -23,6 +23,10 @@ def request_login_email(publisher:) Rails.application.secrets[:active_promo_id] = "" uphold_url = Rails.application.secrets[:uphold_api_uri] + "/v0/me" stub_request(:get, uphold_url).to_return(body: { status: "pending", memberAt: "2019", uphold_id: "123e4567-e89b-12d3-a456-426655440000" }.to_json) + # Mock out the creation of cards + stub_request(:get, /cards/).to_return(body: [id: "fb25048b-79df-4e64-9c4e-def07c8f5c04"].to_json) + stub_request(:post, /cards/).to_return(body: { id: "fb25048b-79df-4e64-9c4e-def07c8f5c04" }.to_json) + stub_request(:get, /address/).to_return(body: [{ formats: [{ format: "uuid", value: "e306ec64-461b-4723-bf75-015ffc99ebe1" }], type: "anonymous" }].to_json) end after(:example) do @@ -131,7 +135,7 @@ def channel_data(options = {}) follow_redirect! end - assert_select('div.channel-status.float-right') do |element| + assert_select('span.channel-contested') do |element| assert_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(publisher.channels.where(verification_pending: true).first)), element.text) end end @@ -178,7 +182,7 @@ def channel_data(options = {}) follow_redirect! # Channel was transferred - assert_select('div.channel-status.float-right') do |element| + assert_select('span.channel-contested') do |element| assert_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(publisher.channels.where(verification_pending: true).first)), element.text) end @@ -191,7 +195,7 @@ def channel_data(options = {}) get(url) follow_redirect! - assert_select('div.channel-status.float-right') do |element| + assert_select('.channel-secondary-information') do |element| refute_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(Channel.where(verification_pending: true).first)), element.text) end end @@ -485,7 +489,7 @@ def auth_hash(options = {}) follow_redirect! end - assert_select('div.channel-status') do |element| + assert_select('span.channel-contested') do |element| assert_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(publisher.channels.where(verification_pending: true).first)), element.text) end @@ -592,7 +596,8 @@ def auth_hash(options = {}) follow_redirect! end - assert_select('div.channel-status') do |element| + + assert_select('span.channel-contested') do |element| assert_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(publisher.channels.where(verification_pending: true).first)), element.text) end @@ -689,7 +694,7 @@ def auth_hash(options = {}) follow_redirect! end - assert_select('div.channel-status') do |element| + assert_select('span.channel-contested') do |element| assert_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(publisher.channels.where(verification_pending: true).first)), element.text) end @@ -785,7 +790,7 @@ def auth_hash(options = {}) follow_redirect! end - assert_select('div.channel-status') do |element| + assert_select('span.channel-contested') do |element| assert_match(I18n.t("shared.channel_contested", time_until_transfer: time_until_transfer(publisher.channels.where(verification_pending: true).first)), element.text) end diff --git a/test/controllers/site_channels_controller_test.rb b/test/controllers/site_channels_controller_test.rb index 3b917a54ad..9bb5fe036a 100644 --- a/test/controllers/site_channels_controller_test.rb +++ b/test/controllers/site_channels_controller_test.rb @@ -265,7 +265,7 @@ class SiteChannelsControllerTest < ActionDispatch::IntegrationTest new_channel = publisher.channels.order(created_at: :asc).last # Triggering an update to test if the promo was created - assert_no_enqueued_jobs do + assert_enqueued_jobs(1) do new_channel.update(verified: true) end ensure diff --git a/test/features/publishers_home_test.rb b/test/features/publishers_home_test.rb index 44b1ce9391..484c69a73f 100644 --- a/test/features/publishers_home_test.rb +++ b/test/features/publishers_home_test.rb @@ -9,6 +9,10 @@ class PublishersHomeTest < Capybara::Rails::TestCase @prev_eyeshade_offline = Rails.application.secrets[:api_eyeshade_offline] stub_request(:get, uphold_url).to_return(body: { status: "restricted", uphold_id: "123e4567-e89b-12d3-a456-426655440000", currencies: [] }.to_json) + # Mock out the creation of cards + stub_request(:get, /cards/).to_return(body: [id: "fb25048b-79df-4e64-9c4e-def07c8f5c04"].to_json) + stub_request(:post, /cards/).to_return(body: { id: "fb25048b-79df-4e64-9c4e-def07c8f5c04" }.to_json) + stub_request(:get, /address/).to_return(body: [{ formats: [{ format: "uuid", value: "e306ec64-461b-4723-bf75-015ffc99ebe1" }], type: "anonymous" }].to_json) end after do @@ -100,7 +104,7 @@ class PublishersHomeTest < Capybara::Rails::TestCase visit home_publishers_path assert_content page, channel.publication_title - find("#channel_row_#{channel.id}").click_link('Remove Channel') + find("#channel_row_#{channel.id}").click_link('Remove channel') assert_content page, "Are you sure you want to remove this channel?" find('[data-test-modal-container]').click_link("Remove Channel") wait_until { !page.find('.cssload-container', visible: :all).visible? } diff --git a/test/jobs/transfer_channels_job_test.rb b/test/jobs/transfer_channels_job_test.rb index abaaa0f6dc..b9adbafadd 100644 --- a/test/jobs/transfer_channels_job_test.rb +++ b/test/jobs/transfer_channels_job_test.rb @@ -2,13 +2,20 @@ require "webmock/minitest" class TransferChannelsJobTest < ActiveJob::TestCase + before do + # Mock out the creation of cards + stub_request(:get, /cards/).to_return(body: [id: "fb25048b-79df-4e64-9c4e-def07c8f5c04"].to_json) + stub_request(:post, /cards/).to_return(body: { id: "fb25048b-79df-4e64-9c4e-def07c8f5c04" }.to_json) + stub_request(:get, /address/).to_return(body: [{ formats: [{ format: "uuid", value: "e306ec64-461b-4723-bf75-015ffc99ebe1" }], type: "anonymous" }].to_json) + end + test "does not approve channels unless timeout period has passed" do channel = channels(:fraudulently_verified_site) contested_by_channel = channels(:locked_out_site) # contest channel Channels::ContestChannel.new(channel: channel, contested_by: contested_by_channel).perform - assert_enqueued_jobs(0) do + assert_enqueued_jobs(0) do TransferChannelsJob.perform_now end @@ -23,10 +30,10 @@ class TransferChannelsJobTest < ActiveJob::TestCase Channels::ContestChannel.new(channel: channel, contested_by: contested_by_channel).perform travel (Channel::CONTEST_TIMEOUT + 1.minute) do - assert_enqueued_jobs(4) do + assert_enqueued_jobs(6) do TransferChannelsJob.perform_now end - + contested_by_channel.reload assert contested_by_channel.verified end diff --git a/test/models/channel_test.rb b/test/models/channel_test.rb index 10fde74afa..6005b73b90 100644 --- a/test/models/channel_test.rb +++ b/test/models/channel_test.rb @@ -4,6 +4,13 @@ class ChannelTest < ActionDispatch::IntegrationTest include Devise::Test::IntegrationHelpers include ActionMailer::TestHelper + before do + # Mock out the creation of cards + stub_request(:get, /cards/).to_return(body: [id: "fb25048b-79df-4e64-9c4e-def07c8f5c04"].to_json) + stub_request(:post, /cards/).to_return(body: { id: "fb25048b-79df-4e64-9c4e-def07c8f5c04" }.to_json) + stub_request(:get, /address/).to_return(body: [{ formats: [{ format: "uuid", value: "e306ec64-461b-4723-bf75-015ffc99ebe1" }], type: "anonymous" }].to_json) + end + test "site channel must have details" do channel = channels(:verified) assert channel.valid? @@ -82,7 +89,7 @@ class ChannelTest < ActionDispatch::IntegrationTest # verify RegisterChannelForPromoJob is called channel.verified = true - assert_enqueued_jobs(1) do + assert_enqueued_with(job: ActionMailer::DeliveryJob) do channel.save! end @@ -112,7 +119,7 @@ class ChannelTest < ActionDispatch::IntegrationTest # check that RegisterChannelForPromoJob is called when it is verified # channel_copy.verified = true channel_copy = Channel.new(details: channel_details_copy, verified: true, publisher: publisher) - assert_enqueued_jobs(1) do + assert_enqueued_with(job: ActionMailer::DeliveryJob) do channel_copy.save! end diff --git a/test/services/channels/contest_channel_test.rb b/test/services/channels/contest_channel_test.rb index 0d214dfd34..a163799fcc 100644 --- a/test/services/channels/contest_channel_test.rb +++ b/test/services/channels/contest_channel_test.rb @@ -6,7 +6,7 @@ class ContestChannelTest < ActiveJob::TestCase channel = channels(:fraudulently_verified_site) contested_by_channel = channels(:locked_out_site) - assert_enqueued_jobs(2) do + assert_enqueued_jobs(3) do Channels::ContestChannel.new(channel: channel, contested_by: contested_by_channel).perform end end diff --git a/test/services/payout_report_publisher_includer_test.rb b/test/services/payout_report_publisher_includer_test.rb index 21c32181d4..96940f4add 100644 --- a/test/services/payout_report_publisher_includer_test.rb +++ b/test/services/payout_report_publisher_includer_test.rb @@ -10,6 +10,11 @@ class PayoutReportPublisherIncluderTest < ActiveJob::TestCase PotentialPayment.destroy_all @prev_offline = Rails.application.secrets[:api_eyeshade_offline] @prev_fee_rate = Rails.application.secrets[:fee_rate] + + # Mock out the creation of cards + stub_request(:get, /cards/).to_return(body: [id: "fb25048b-79df-4e64-9c4e-def07c8f5c04"].to_json) + stub_request(:post, /cards/).to_return(body: { id: "fb25048b-79df-4e64-9c4e-def07c8f5c04" }.to_json) + stub_request(:get, /address/).to_return(body: [{ formats: [{ format: "uuid", value: "e306ec64-461b-4723-bf75-015ffc99ebe1" }], type: "anonymous" }].to_json) end after do