diff --git a/Gemfile b/Gemfile index 01f5d3e..436cc39 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem "puma", "~> 5.0" # Bundle and transpile JavaScript [https://github.com/rails/jsbundling-rails] gem "jsbundling-rails" -gem "hotwire_combobox" +gem "hotwire_combobox", github: "josefarias/hotwire_combobox", branch: "main" # Hotwire's SPA-like page accelerator [https://turbo.hotwired.dev] gem "turbo-rails", github: "hotwired/turbo-rails", branch: "main" diff --git a/Gemfile.lock b/Gemfile.lock index 09acd44..ebe2c26 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -20,14 +20,24 @@ GIT GIT remote: https://github.com/hotwired/turbo-rails.git - revision: e8dd34a11b588978534ce9b8f8e0822f2c6e3f2a + revision: e376852bfb273f69f4ebb54cf516b99fcbaa7acb branch: main specs: - turbo-rails (2.0.4) + turbo-rails (2.0.5) actionpack (>= 6.0.0) activejob (>= 6.0.0) railties (>= 6.0.0) +GIT + remote: https://github.com/josefarias/hotwire_combobox.git + revision: 201954ceecf369f4ec70fbd50afaa4e3d0cebedc + branch: main + specs: + hotwire_combobox (0.2.5) + rails (>= 7.0.7.2) + stimulus-rails (>= 1.2) + turbo-rails (>= 1.2) + GIT remote: https://github.com/rspec/rspec-core.git revision: 81589709e88db1ec2537faee3a7f4a43c7d9aac1 @@ -268,10 +278,6 @@ GEM groupdate (6.3.0) activesupport (>= 6.1) hashie (5.0.0) - hotwire_combobox (0.2.1) - rails (>= 7.0.7.2) - stimulus-rails (>= 1.2) - turbo-rails (>= 1.2) http (5.1.1) addressable (~> 2.8) http-cookie (~> 1.0) @@ -340,7 +346,7 @@ GEM json (>= 1.4.6) meta-tags (2.18.0) actionpack (>= 3.2.0, < 7.1) - method_source (1.0.0) + method_source (1.1.0) mini_magick (4.12.0) mini_mime (1.1.5) minitest (5.22.3) @@ -558,7 +564,7 @@ GEM rubocop-performance (~> 1.18.0) standardrb (1.0.1) standard - stimulus-rails (1.2.1) + stimulus-rails (1.3.3) railties (>= 6.0.0) store_attribute (1.1.1) activerecord (>= 6.0) @@ -620,7 +626,7 @@ DEPENDENCIES friendly_id (~> 5.4) geocoder (~> 1.8) groupdate (~> 6.3) - hotwire_combobox + hotwire_combobox! http (~> 5.1) image_processing (~> 1.2) jbuilder diff --git a/app/assets/stylesheets/application.tailwind.css b/app/assets/stylesheets/application.tailwind.css index 358c665..675465a 100644 --- a/app/assets/stylesheets/application.tailwind.css +++ b/app/assets/stylesheets/application.tailwind.css @@ -45,7 +45,7 @@ /* Brand shinanigans -> These will be computed for the users theme at runtime. */ - --rau-brand: #002c63; + --rau-brand: #ea09e3; --rau-brand-emphasis: #002c63; --rau-brand-text: white; } @@ -89,7 +89,7 @@ -> These will be computed for the users theme at runtime. */ - --rau-brand: #002c63; + --rau-brand: #ea09e3; --rau-brand-emphasis: #002c63; --rau-brand-text: white; } @@ -203,6 +203,10 @@ @apply bg-white; } + .scaleX { + @apply hover:scale-125 transform-gpu hover:animate-pulse transition duration-500; + } + textarea { @apply block w-full rounded-md border-0 py-1.5 dark:bg-gray-900 dark:text-gray-100 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-brand-600 sm:text-sm sm:leading-6; } @@ -342,16 +346,16 @@ /* COMBOBOX */ .hw-combobox__main__wrapper { - @apply sm:w-[35rem] rounded-full w-80; + @apply sm:w-full rounded-full w-80 relative; } .hw-combobox__handle { @apply right-3; } .hw-combobox__listbox { - @apply rounded-2xl bg-subtle; + @apply rounded-2xl bg-subtle overflow-auto h-48 absolute w-full z-[500]; } - .hw-combobox__option { + .hw-combobox__listbox .hw-combobox__option { @apply p-2 border-b border-muted hover:bg-emphasis; } } diff --git a/app/controllers/account_connections_controller.rb b/app/controllers/account_connections_controller.rb new file mode 100644 index 0000000..6e5bf90 --- /dev/null +++ b/app/controllers/account_connections_controller.rb @@ -0,0 +1,110 @@ +class AccountConnectionsController < ApplicationController + + + def user_search + @title = "Tracks" + + q = params[:q] + if q.present? + @artists = current_user.find_artists_excluding_children(q) + end + #.with_attached_avatar + #.order("id desc") + @artists = @artists ? @artists.page(params[:page]).per(5) : [] + end + + def new + @collection = [] + @user = FormModels::ArtistForm.new( + request_access: "request", + hide: false, + is_new: params[:kind] == "new" + ) + @users = User.where(role: "artists").page(params[:page]).per(10) + end + + def create + if params[:form_models_artist_form] + resource_params = params.require(:form_models_artist_form).permit( + :password, :username, :hide, :request_access, :email, :search, :first_name, :last_name, :logo + ) + @user = FormModels::ArtistForm.new(resource_params) + @user.is_new = params[:kind] == "new" + @user.inviter = current_user + + unless @user.username.present? + @user.username = User.find_by(id: @user.search)&.username if @user.search.present? + @user.inviter = current_user + end + if @user.valid? + created_user = @user.process_user_interaction + if !created_user + flash.now[:error] = "not invited user" + else + @created = true + end + end + return + end + + if params[:commit] == "Select user" + a = User.find(params[:search]) + @selected_artist = FormModels::ArtistForm.new(username: a.username) + if @selected_artist.valid? + @selected_artist + end + return + end + + if params[:commit] == "Send connect request" + user = User.find(params[:user][:id]) + connected_account = ConnectedAccount.attach_account(inviter: current_user , invited_user: user) if user + + if connected_account + ConnectedAccountMailer.invitation_email(connected_account).deliver_now + + @created = true + end + return + end + end + + def impersonate + if params[:username] + user = User.find_by(username: params[:username]) + if current_user.child_accounts.find(user.id) + session[:parent_user] = current_user.id + Current.label_user = current_user + flash[:notice] = "signed as #{user.username}" + sign_in(:user, user) + redirect_to user_path(user.username) + end + else + if session[:parent_user].present? + user = User.find(session[:parent_user]) + session[:parent_user] = nil + Current.label_user = nil + flash[:notice] = "signed as #{user.username}" + sign_in(:user, user) + redirect_to user_path(user.username) + end + end + end + + def update + + end + + def approve + @connected_account = ConnectedAccount.find_signed(params[:id]) + @label = @connected_account.parent + @artist = @connected_account.user + if request.get? + sign_in(:user, @artist) + elsif request.post? + flash[:notice] = "you are now part of #{@label.username}" + redirect_to user_path(@artist.username) + end + + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4e2013f..cba0733 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,13 +1,23 @@ class ApplicationController < ActionController::Base before_action do ActiveStorage::Current.url_options = {protocol: request.protocol, host: request.host, port: request.port} - ActiveStorage::Current.host = request.url - # ActiveStorage::Current.url_options = { protocol: "http://", host: "localhost", port: "3000" } + Current.label_user = User.find(session[:parent_user]) if session[:parent_user].present? end before_action :set_locale + helper_method :flash_stream + + def flash_stream + turbo_stream.replace("flash", partial: "shared/flash", locals: { flash: flash }) + end + + helper_method :impersonating? + def impersonating?(user) + label_user.present? && current_user&.id == user&.id + end + def set_locale if params[:locale].present? cookies[:locale] = params[:locale] @@ -19,6 +29,12 @@ def set_locale end end + helper_method :label_user + def label_user + return if session[:parent_user].blank? + @label_user ||= User.find session[:parent_user] + end + def become if current_user.is_admin? user = User.find_by(username: params[:id]) diff --git a/app/controllers/label_artists_controller.rb b/app/controllers/label_artists_controller.rb new file mode 100644 index 0000000..f4006ce --- /dev/null +++ b/app/controllers/label_artists_controller.rb @@ -0,0 +1,7 @@ +class LabelArtistsController < ApplicationController + + + def index + @label = User.where(role: ["artist", "admin"], label: true).find_by(username: params[:user_id]) + end +end diff --git a/app/controllers/label_auth_controller.rb b/app/controllers/label_auth_controller.rb new file mode 100644 index 0000000..bf33357 --- /dev/null +++ b/app/controllers/label_auth_controller.rb @@ -0,0 +1,34 @@ +class LabelAuthController < ApplicationController + before_action :authenticate_user! + + # Assuming `User` model and `Accounts` is a service object that contains user related queries + # and `is_child_of?` is a method defined within your User model or an associated service. + + def add + username = params[:username] + user = User.get_user_by_username(username) + + if current_user.is_child_of?(user.id) + sign_in(:user, user) # Devise's sign_in helper + session[:parent_user] = current_user.id + redirect_to "/#{user.username}" + else + flash[:error] = "Not allowed" + redirect_to "/#{current_user.username}" + end + end + + def back + username = params[:username] + user = User.get_user_by_username(username) + + if user.is_child_of?(current_user.id) + sign_in(:user, user) # Devise's sign_in helper + session[:parent_user] = nil + redirect_to "/#{user.username}" + else + flash[:error] = "Not allowed" + redirect_to "/#{current_user.username}" + end + end +end \ No newline at end of file diff --git a/app/controllers/labels_controller.rb b/app/controllers/labels_controller.rb new file mode 100644 index 0000000..fc6eeb1 --- /dev/null +++ b/app/controllers/labels_controller.rb @@ -0,0 +1,6 @@ +class LabelsController < ApplicationController + + before_action :find_user, except: [:index] + before_action :check_user_role, except: [:index] + +end diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb index 4d5b04a..99ac617 100644 --- a/app/controllers/likes_controller.rb +++ b/app/controllers/likes_controller.rb @@ -1,9 +1,14 @@ class LikesController < ApplicationController + + before_action :check_user + def create @resource = find_resource @button_class = current_user.toggle_like!(@resource) ? "button-active" : "button" end + private + def find_resource if params[:track_id] @resource = Track.friendly.find(params[:track_id]) @@ -11,4 +16,10 @@ def find_resource @resource = Playlist.friendly.find(params[:playlist_id]) end end + + def check_user + redirect_to new_user_session_path and return if current_user.blank? + end + + end diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index f12e3e3..c476e26 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -4,6 +4,14 @@ class PhotosController < ApplicationController def create end + def show + @photos = User.find(params[:user_id]).photos + @photo = User.find(params[:user_id]).photos.find(params[:id]) + @prev_photo = @photos.where("id < ?", @photo.id).last + @next_photo = @photos.where("id > ?", @photo.id).first + + end + def update current_user.update(resource_params) diff --git a/app/controllers/playlists_controller.rb b/app/controllers/playlists_controller.rb index 375574b..90a0b9a 100644 --- a/app/controllers/playlists_controller.rb +++ b/app/controllers/playlists_controller.rb @@ -43,7 +43,8 @@ def show def edit @tab = params[:tab] || "basic-info-tab" - @playlist = current_user.playlists.friendly.find(params[:id]) + @playlist = find_playlist + @playlist.enable_label = @playlist.label_id.present? end def new @@ -56,19 +57,25 @@ def new def create @tab = params[:tab] || "basic-info-tab" @playlist = current_user.playlists.create(playlist_params) - if @playlist.errors.blank? - flash[:now] = "successfully created" + if @playlist + flash.now[:notice] = "successfully created" + else + flash.now[:error] = "error in creating" end end def update @tab = params[:tab] || "basic-info-tab" - @playlist = current_user.playlists.friendly.find(params[:id]) + @playlist = find_playlist - if !params[:nonpersist] && @playlist.update(playlist_params) - flash[:now] = "successfully updated" - end + @playlist.assign_attributes(playlist_params) + if !params[:nonpersist] && @playlist.save + flash.now[:notice] = "successfully updated" + else + flash.now[:error] = "error updating playlist" + end + if params[:nonpersist] @playlist.assign_attributes(playlist_params) end @@ -83,6 +90,7 @@ def playlist_params :title, :description, :private, :price, :playlist_type, :release_date, :cover, :record_label, :buy_link, + :enable_label, :copyright, :attribution, :noncommercial, :non_derivative_works, :copies, track_playlists_attributes: [ @@ -107,4 +115,10 @@ def sort render "update" end + + def find_playlist + Playlist + .where(user_id: current_user.id).or(Playlist.where(label_id: current_user.id)) + .friendly.find(params[:id]) + end end diff --git a/app/controllers/tracks_controller.rb b/app/controllers/tracks_controller.rb index 443906d..ee30e92 100644 --- a/app/controllers/tracks_controller.rb +++ b/app/controllers/tracks_controller.rb @@ -23,6 +23,7 @@ def create audios = track_bulk_params["audio"].select { |o| o.is_a?(String) }.reject(&:empty?) # @track = current_user.tracks.new(track_params) @track_form.user = current_user + @track_form.private = track_bulk_params[:private] @track_form.tracks_attributes = audios.map { |o| {audio: o} } @track_form.step = "info" else @@ -44,12 +45,16 @@ def edit def update @track = current_user.tracks.friendly.find(params[:id]) @tab = params[:track][:tab] || "basic-info-tab" + @track.assign_attributes(track_params) if params[:nonpersist] - @track.assign_attributes(track_params) @track.valid? else - flash.now[:notice] = "Track was successfully updated." - @track.update(track_params) + @track.label_id = label_user.id if !label_user.blank? && @track.enable_label + if @track.save + flash.now[:notice] = "Track was successfully updated." + else + flash.now[:error] = @track.errors.full_messages + end end # puts @track.errors.as_json @track.tab = @tab @@ -103,6 +108,7 @@ def get_meta_tags def track_params params.require(:track).permit( :private, + :enable_label, :audio, :title, :step, :description, :tab, :genre, :contains_music, :artist, :publisher, :isrc, :composer, :release_title, :buy_link, :album_title, @@ -124,7 +130,9 @@ def check_activated_account def track_bulk_params params.require(:track_bulk_creator).permit( - :make_playlist, :private, + :make_playlist, + :private, + :enable_label, :step, audio: [], tracks_attributes: [ :audio, :cover, :title, :tags, :description diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 785ec39..3ccd386 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,11 +4,14 @@ class UsersController < ApplicationController def index @title = "Tracks" - @artists = User.where(role: "artist") - .where.not(username: nil) + @artists = User.where(role: "artist").where.not(username: nil) + q = params[:q] + if q.present? + @artists = @artists.where("username ILIKE :q OR email ILIKE :q OR first_name ILIKE :q OR last_name ILIKE :q", q: "%#{q}%") + end #.with_attached_avatar #.order("id desc") - .page(params[:page]).per(5) + @artists = @artists.page(params[:page]).per(5) end def show @@ -17,6 +20,8 @@ def show get_meta_tags @as = :track @section = "tracks/track_item" + + # render @user.label ? "labels/show" : "show" end def tracks @@ -25,7 +30,6 @@ def tracks @as = :track @title = "Tracks" @section = "tracks/track_item" - paginated_render end @@ -33,9 +37,10 @@ def playlists_filter @kind = params[:kind].present? ? params[:kind].split(",") : Category.playlist_types - @playlists = @user.playlists + @playlists = Playlist .where(playlist_type: @kind) - .where(user_id: @user.id) + .where(user_id: @user.id).or(Playlist.where(label_id: @user.id)) + .where(private: false) .with_attached_cover .includes(user: {avatar_attachment: :blob}) .includes(tracks: {cover_attachment: :blob}) @@ -54,7 +59,8 @@ def playlists_filter def playlists @title = "Playlists" @section = "playlists" - @collection = @user.playlists + @collection = Playlist + .where(user_id: @user.id).or(Playlist.where(label_id: @user.id)) .where.not(playlist_type: ["album", "ep"]) .with_attached_cover .includes(user: {avatar_attachment: :blob}) @@ -67,33 +73,24 @@ def playlists @collection = @collection.references(:tracks) .page(params[:page]) - #@collection = @collection - #.where( - # playlists: {user_id: @user.id}, - # tracks: {user_id: @user.id} - #) if current_user.present? - - #.or( - # @user.playlists - # .where( - # playlists: {private: true}, - # tracks: {private: true, user_id: @user.id} - # ) - #) - #.or( - # @user.playlists - # .where.not( - # playlists: {user_id: @user.id}, - # tracks: {user_id: @user.id} - # ) - # .where(tracks: {private: true}) - #) - @as = :playlist @section = "playlists/playlist_item" render "show" end + def artists + @label = User.where(role: ["artist", "admin"], label: true).find_by(username: params[:user_id]) + @collection = @label.child_accounts.page(params[:page]).per(5) # connected_accounts.page(params[:page]).per(5) + @as = :artist + @section = "label_artists/artist" + @title = "Artists" + @cta_url = new_account_connection_path + @cta_label = "New account connection" + @collection_class = "mt-6 grid grid-cols-2 gap-x-4 gap-y-10 sm:gap-x-6 md:grid-cols-4 md:gap-y-0 lg:gap-x-8" + @admin = current_user && current_user.id == @label&.id + render "show" + end + def reposts @title = "Reposts" @collection = @user.reposts_preloaded.page(params[:page]).per(5) @@ -105,9 +102,9 @@ def reposts def albums @title = "Albums" @section = "albums" - @collection = @user.playlists + @collection = Playlist + .where(user_id: @user.id).or(Playlist.where(label_id: @user.id)) .where(playlist_type: ["album", "ep"]) - .where(user_id: @user.id) .with_attached_cover .includes(user: {avatar_attachment: :blob}) .includes(tracks: {cover_attachment: :blob}) @@ -148,18 +145,18 @@ def get_meta_tags def get_tracks # @collection = @user.tracks.page(params[:page]).per(2) @collection = if current_user && @user.id == current_user&.id - User.track_preloaded_by_user(current_user&.id) - .where(user_id: @user.id) - .with_attached_cover - .includes(user: {avatar_attachment: :blob}) - .order("id desc") - .page(params[:page]).per(6) + User.track_preloaded_by_user(current_user_id: current_user&.id, user: @user ) + #.where(user_id: @user.id) else - @user.tracks.published - .with_attached_cover - .includes(user: {avatar_attachment: :blob}) - .order("id desc").page(params[:page]).per(6) + User.track_preloaded_by_user_n(user: @user) + #.where(user_id: @user.id) + #@user.tracks.published end + + @collection = @collection + .with_attached_cover + .includes(user: {avatar_attachment: :blob}) + .order("id desc").page(params[:page]).per(6) end def find_user diff --git a/app/helpers/account_connections_helper.rb b/app/helpers/account_connections_helper.rb new file mode 100644 index 0000000..d7a86af --- /dev/null +++ b/app/helpers/account_connections_helper.rb @@ -0,0 +1,2 @@ +module AccountConnectionsHelper +end diff --git a/app/helpers/label_artists_helper.rb b/app/helpers/label_artists_helper.rb new file mode 100644 index 0000000..3c8a95b --- /dev/null +++ b/app/helpers/label_artists_helper.rb @@ -0,0 +1,2 @@ +module LabelArtistsHelper +end diff --git a/app/helpers/label_auth_helper.rb b/app/helpers/label_auth_helper.rb new file mode 100644 index 0000000..ebc5deb --- /dev/null +++ b/app/helpers/label_auth_helper.rb @@ -0,0 +1,2 @@ +module LabelAuthHelper +end diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb new file mode 100644 index 0000000..9802e31 --- /dev/null +++ b/app/helpers/labels_helper.rb @@ -0,0 +1,2 @@ +module LabelsHelper +end diff --git a/app/helpers/tailwind_form_builder.rb b/app/helpers/tailwind_form_builder.rb index 54f091d..30131b3 100644 --- a/app/helpers/tailwind_form_builder.rb +++ b/app/helpers/tailwind_form_builder.rb @@ -121,20 +121,25 @@ def div_radio_button(method, tag_value, options = {}) end def radio_button(method, value, options = {}) - info = @template.label_tag( - tr(options[:label] || method), nil, - class: "block font-bold text-md leading-5 text-gray-900 dark:text-white pt-0" - ) + - field_details(method, object, options) - - options[:class] = "self-start mt-1 mr-1 h-4 w-4 text-brand-600 transition duration-150 ease-in-out" - @template.tag.div(class: "flex items-center") do - @template.radio_button( - @object_name, method, value, objectify_options(options) - ) + @template.tag.div(class: "flex-col items-center") { info } + options.merge!(class: "form-radio mr-2 h-4 w-4 text-indigo-600 transition duration-150 ease-in-out") unless options.has_key?(:class) + + label_content = if options[:label] == false + "" + else + @template.label_tag( + tr(options[:label] || method), nil, + class: "block text-sm leading-5 text-muted" + ) + end + + @template.tag.div(class: "inline-flex items-center #{options[:wrapper_class]}") do + super + label_content + + @template.tag.div(class: "text-sm font-normal leading-5 text-muted") do + field_details(method, object, options) + end end end - + def check_box(method, options = {}, checked_value = "1", unchecked_value = "0") info = @template.label_tag( tr(options[:label] || method), nil, diff --git a/app/javascript/controllers/audio_upload_controller.js b/app/javascript/controllers/audio_upload_controller.js index ac1da6d..ab366f4 100644 --- a/app/javascript/controllers/audio_upload_controller.js +++ b/app/javascript/controllers/audio_upload_controller.js @@ -148,7 +148,6 @@ export default class extends Controller { this.preventDefaults(e); let files = e.dataTransfer.files; this.inputTarget.files = files; - debugger this.uploadFile(); } } \ No newline at end of file diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 3c34c81..43ae421 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -1,4 +1,4 @@ class ApplicationMailer < ActionMailer::Base - default from: "from@example.com" + default from: ENV['EMAIL_ACCOUNT'] layout "mailer" end diff --git a/app/mailers/connected_account_mailer.rb b/app/mailers/connected_account_mailer.rb new file mode 100644 index 0000000..279a79c --- /dev/null +++ b/app/mailers/connected_account_mailer.rb @@ -0,0 +1,24 @@ +class ConnectedAccountMailer < ApplicationMailer + # default from: 'noreply@labelx.com' + + # Method to send an invitation confirmation email to existing artists + def invitation_email(connected_account) + @artist = connected_account.user + @label = connected_account.parent + @connected_account = connected_account + mail(to: @artist.email, subject: "Welcome to Join Us at Label #{@label.username} on Rauversion.com!") + end + + # Method to notify the label of a new artist account creation + def new_account_notification_to_label(connected_account) + @artist = connected_account.user + @label = connected_account.parent + mail(to: @label.email, subject: "New Artist Account Activation at Label #{@label.username}!") + end + + def new_account_notification_to_artist(connected_account) + @artist = connected_account.user + @label = connected_account.parent + mail(to: @label.email, subject: "New Artist Account Activation at Label #{@label.username}!") + end +end diff --git a/app/models/connected_account.rb b/app/models/connected_account.rb new file mode 100644 index 0000000..a0e30bc --- /dev/null +++ b/app/models/connected_account.rb @@ -0,0 +1,23 @@ +class ConnectedAccount < ApplicationRecord + belongs_to :user + belongs_to :parent, class_name: "User" + + validate :validate_unique_user_for_parent + + private + + def validate_unique_user_for_parent + # Check if any other connected accounts have the same user_id and parent_id + exists = ConnectedAccount.where(parent_id: parent_id, user_id: user_id).exists? + errors.add(:user_id, "is already connected to this parent") if exists && new_record? || persisted? && changed? + end + + def self.attach_account(inviter: , invited_user:, state: "peding") + inviter.connected_accounts.create(user_id: invited_user.id, state: state) + end + + def self.attach_new_account(inviter: , user_params:, state: "pending") + user = User.create(user_params) + self.attach_account(inviter: inviter , invited_user: user, state: state) + end +end diff --git a/app/models/current.rb b/app/models/current.rb new file mode 100644 index 0000000..ffeeb32 --- /dev/null +++ b/app/models/current.rb @@ -0,0 +1,12 @@ +class Current < ActiveSupport::CurrentAttributes + attribute :label_user, :user + attribute :request_id, :user_agent, :ip_address + + resets { Time.zone = nil } + + def user=(user) + super + #self.label_user = user.account + #Time.zone = user.time_zone + end +end diff --git a/app/models/form_models/artist_form.rb b/app/models/form_models/artist_form.rb new file mode 100644 index 0000000..b679d23 --- /dev/null +++ b/app/models/form_models/artist_form.rb @@ -0,0 +1,88 @@ +class FormModels::ArtistForm + include ActiveModel::Model + include ActiveModel::Validations + + attr_accessor :username, :artist_url, :request_access, + :first_name, :last_name, :logo, + :password, :hide, :inviter, :email, :search, :is_new + + validates :username, presence: true + validate :username_must_exist, if: ->{ !self.is_new } + validate :username_must_not_exist, if: ->{ self.is_new } + validates :search, presence: true, if: ->{ !self.is_new } + # validates :request_access, inclusion: { in: [true, false] } + validates :password, presence: true, if: -> { request_access_kind } + validates :hide, inclusion: { in: [true, false, "1", "0"] }, if: ->{ !self.is_new } + validates :request_access, inclusion: { in: ["password", "request"] }, if: ->{ !self.is_new } + # validates :email, presence: true, format: { with: URI::MailTo::EMAIL_REGEXP }, length: { maximum: 160 } + + def request_access_kind + request_access == "password" + end + # Custom validation to check if the username exists in the User model + def username_must_not_exist + errors.add(:username, "does exist new") if User.exists?(username: username) + end + + def username_must_exist + errors.add(:username, "does not exist") if !User.exists?(username: username) + end + + # Method to process user creation or send an invitation based on request_access + def process_user_interaction + return false unless valid? # Ensure all validations pass before processing + + User.transaction do + if !is_new + send_invitation + else + create_user + end + end + end + + private + + # Create a new user with the provided username and password + def create_user + user = User.create(username: username, + password: password, + email: email, + role: "artist", + first_name: first_name, + last_name: last_name, + password_confirmation: password + ) + user.confirm + + if user + connected_account = ConnectedAccount.attach_account(inviter: inviter , invited_user: user, state: "active") + + ConnectedAccountMailer.new_account_notification_to_label(connected_account).deliver_now + + user + else + error.add(:base, "user not created!") + end + end + + # Send an invitation to the existing user + def send_invitation + + invited_user = User.find_by(username: username) + + if !inviter.child_accounts.exists?(invited_user.id) + + connected_account = ConnectedAccount.attach_account( + inviter: inviter, + invited_user: invited_user, + state: "pending" + ) if invited_user + + ConnectedAccountMailer.invitation_email(connected_account).deliver_now + invited_user + else + nil + end + end +end \ No newline at end of file diff --git a/app/models/playlist.rb b/app/models/playlist.rb index 931c7fc..d115ba7 100644 --- a/app/models/playlist.rb +++ b/app/models/playlist.rb @@ -16,11 +16,14 @@ def self.plain friendly_id :title, use: :slugged belongs_to :user + belongs_to :label, class_name: "User", optional: true + has_many :track_playlists has_many :tracks, through: :track_playlists has_many :listening_events has_many :comments, as: :commentable has_many :likes, as: :likeable + has_one_attached :cover has_one_attached :zip @@ -28,6 +31,14 @@ def self.plain accepts_nested_attributes_for :track_playlists, allow_destroy: true + belongs_to :label, class_name: "User", optional: true + attr_accessor :enable_label + before_save :check_label + + def check_label + self.label_id = Current.label_user.id if enable_label && Current.label_user + end + scope :latests, -> { order("id desc") } scope :published, -> { where(private: false) } diff --git a/app/models/track.rb b/app/models/track.rb index 8c9e8d5..529a536 100644 --- a/app/models/track.rb +++ b/app/models/track.rb @@ -15,6 +15,13 @@ class Track < ApplicationRecord has_many :spotlights, as: :spotlightable # has_many :spotlighted_tracks, through: :spotlight_tracks + belongs_to :label, class_name: "User", optional: true + attr_accessor :enable_label + before_save :check_label + + def check_label + self.label_id = Current.label_user.id if enable_label && Current.label_user + end has_one_attached :cover has_one_attached :audio diff --git a/app/models/track_bulk_creator.rb b/app/models/track_bulk_creator.rb index b8a5016..2087f1f 100644 --- a/app/models/track_bulk_creator.rb +++ b/app/models/track_bulk_creator.rb @@ -10,7 +10,7 @@ class TrackBulkCreator # Initialize the tracks_attributes with an empty array def initialize(attributes = {}) - self.private = true + self.private = attributes[:private] self.tracks_attributes ||= [] end @@ -36,7 +36,7 @@ def tracks @tracks ||= tracks_attributes.map do |attributes| blob = ActiveStorage::Blob.find_signed(attributes[:audio]) t = Track.new(attributes) - t.title = File.basename(blob.filename, File.extname(blob.filename)) + t.title = File.basename(blob.filename.to_s, File.extname(blob.filename.to_s)) t.user = user t.private = private t diff --git a/app/models/user.rb b/app/models/user.rb index 961ab73..d87557f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -20,6 +20,12 @@ class User < ApplicationRecord has_many :hosted_events, through: :event_hosts has_many :purchases has_many :comments + + + has_many :connected_accounts, foreign_key: :parent_id + + has_many :child_accounts, through: :connected_accounts, source: :user + has_many :spotlights, autosave: true # has_many :spotlighted_tracks, through: :spotlight_tracks, source: :spotlight_tracks has_one_attached :profile_header @@ -54,12 +60,17 @@ class User < ApplicationRecord accepts_nested_attributes_for :photos, allow_destroy: true scope :artists, -> { where(role: "artist").where.not(username: nil) } + + + def full_name + [first_name, last_name].compact.join(" ") + end # Ex:- scope :active, -> {where(:active => true)} def has_invitations_left? true end - def avatar_url(size) + def avatar_url(size = :medium) url = case size when :medium avatar.variant(resize_to_fill: [200, 200]) # &.processed&.url @@ -77,11 +88,11 @@ def avatar_url(size) url || "daniel-schludi-mbGxz7pt0jM-unsplash-sqr-s-bn.png" end - def self.track_preloaded_by_user(id) + def self.track_preloaded_by_user(current_user_id:, user: ) # Track.left_outer_joins(:reposts, :likes) # .where("reposts.user_id = :id OR likes.liker_id = :id OR reposts.user_id IS NULL OR likes.liker_id IS NULL", id: id) # .includes(:audio_blob, :cover_blob, user: :avatar_attachment) - + # user = User.find(id) tracks = Track.arel_table users = User.arel_table reposts_alias = Repost.arel_table.alias("r") @@ -90,27 +101,61 @@ def self.track_preloaded_by_user(id) reposts_join = tracks .join(reposts_alias, Arel::Nodes::OuterJoin) .on(reposts_alias[:track_id].eq(tracks[:id]) - .and(reposts_alias[:user_id].eq(id))) + .and(reposts_alias[:user_id].eq(current_user_id))) .join_sources likes_join = tracks .join(likes_alias, Arel::Nodes::OuterJoin) .on(likes_alias[:likeable_id].eq(tracks[:id]) .and(likes_alias[:likeable_type].eq("Track")) - .and(likes_alias[:liker_id].eq(id)) + .and(likes_alias[:liker_id].eq(current_user_id)) .and(likes_alias[:liker_type].eq("User"))) .join_sources - result = Track.includes(:audio_blob, :cover_blob, user: :avatar_attachment) - .joins(reposts_join, likes_join) - .select("tracks.*, r.id as repost_id, l.id as like_id") - .references(:r, :l) + if !user.label + result = Track.includes(:audio_blob, :cover_blob, user: :avatar_attachment) + .joins(reposts_join, likes_join) + .where(tracks[:user_id].eq(user.id)) + .select("tracks.*, r.id as repost_id, l.id as like_id") + .references(:r, :l) + return result + else + + # Gather child account IDs + # child_ids = User.find(id).child_accounts.pluck(:id) + + # Adjust where clause to include tracks from child accounts + result = Track.includes(:audio_blob, :cover_blob, user: :avatar_attachment) + .joins(reposts_join, likes_join) + .where(tracks[:user_id].eq(user.id).or(tracks[:label_id].in(user.id))) + .select("tracks.*, r.id as repost_id, l.id as like_id") + .references(:r, :l) + end + + end + + def self.track_preloaded_by_user_n(user:) + tracks = Track.arel_table + users = User.arel_table + + if !user.label + result = Track.includes(:audio_blob, :cover_blob, user: :avatar_attachment) + .where(tracks[:user_id].in(user.id)) + return result + else + # Gather child account IDs + # Adjust where clause to include tracks from child accounts + result = Track.includes(:audio_blob, :cover_blob, user: :avatar_attachment) + .where(tracks[:user_id].in(user.id).or(tracks[:label_id].in(user.id))) + end + end - def reposts_preloaded - User.track_preloaded_by_user(id) - .joins(:reposts) - .where("reposts.user_id =?", id) + def reposts_preloaded(current_user: nil) + tracks = current_user.blank? ? + User.track_preloaded_by_user_n(user: self) : + User.track_preloaded_by_user(current_user_id: current_user, user: self) + tracks.joins(:reposts).where("reposts.user_id =?", id) end def is_publisher? @@ -150,7 +195,38 @@ def user_sales_for(kind = "Track") .where(tracks: {user_id: id}) end + + def active_connected_accounts(user) + ConnectedAccount.where(parent_id: user.id, state: 'active').includes(:user) + end + + def is_child_of?(child_user_id) + ConnectedAccount.exists?(parent_id: self.id, state: 'active', user_id: child_user_id) + end + + def to_combobox_display + self.username + end + + def find_artists_excluding_children(q = nil) + # Get IDs of all child accounts for the current user + child_account_ids = self.child_accounts.pluck(:id) + + # Base query adjusted to exclude child account IDs + artists = User.where(role: "artist") + .where.not(username: nil) + #.where.not(label: true) + .where.not(id: child_account_ids) + + # Apply search filter if 'q' is provided + if q.present? + artists = artists.where("username ILIKE :q OR email ILIKE :q", q: "%#{q}%") + end + + artists + end + # def password_required? # false # end -end +end \ No newline at end of file diff --git a/app/views/account_connections/_existing.erb b/app/views/account_connections/_existing.erb new file mode 100644 index 0000000..e0116b1 --- /dev/null +++ b/app/views/account_connections/_existing.erb @@ -0,0 +1,70 @@ + +
+ <% if false %> +

+ <%= t("existing_artist") %> +

+

Please search for an existing artist.

+ <%= form_with url: account_connections_path(kind: :existing), local: true do |form| %> + <%= form.combobox :search, user_search_account_connections_path, + name_when_new: :search, mobile_at: "0px" + %> +
+ <%= form.submit "Select user" %> +
+ <% end %> + <% end %> + + <% if true %> + + <%= form_for @user, url: account_connections_path(kind: "existing"), method: :post do |f| %> + +

+ <%= t("Existing User") %> +

+ +

Please search for an existing artist.

+ + <% # f.text_field :username, label: "username", hint: "Artist URL http://#{ ENV["DOMAIN"] }/jjj" %> + +
+ http:// + <%= f.combobox :search, user_search_account_connections_path, + name_when_new: :search_1, mobile_at: "0px" + %> + .rauversion.com +
+ + + + + + +
+ <%= f.check_box :hide, label: "Hide artist", hint: "You can hide and unhide artists later, too." %> +
+ +
+
+ <%= link_to "back", new_account_connection_path, data: {turbo_frame: "modal"} %> + <%= f.submit "Save", data: { disable_with: "Saving..." } %> +
+
+ <% end %> + + <% end %> + +
diff --git a/app/views/account_connections/_new_user.erb b/app/views/account_connections/_new_user.erb new file mode 100644 index 0000000..2e9ba9f --- /dev/null +++ b/app/views/account_connections/_new_user.erb @@ -0,0 +1,43 @@ + +
+ +
+ <%= form_with model: @user, + url: account_connections_path(kind: "new"), local: true do |f| %> + +

+ <%= t("New user") %> +

+ +

Please specify an account to add.

+ + <% # f.text_field :username, label: "username", hint: "Artist URL http://#{ ENV["DOMAIN"] }/jjj" %> + +
+ <%= f.text_field :first_name %> + <%= f.text_field :last_name %> +
+ +
+ http:// + <%= f.text_field :username, label: false %> + .rauversion.com +
+ +
+ <%= f.text_field :email, hint: gettext("Email") %> +
+ + + +
+
+ <%= link_to "back", new_account_connection_path, data: {turbo_frame: "modal"} %> + <%= f.submit "Save", data: { disable_with: "Saving..." } %> +
+
+ <% end %> +
+
\ No newline at end of file diff --git a/app/views/account_connections/_searchable.erb b/app/views/account_connections/_searchable.erb new file mode 100644 index 0000000..e5ed012 --- /dev/null +++ b/app/views/account_connections/_searchable.erb @@ -0,0 +1,4 @@ +
+ <%= image_tag searchable.avatar_url, class: "w-10" %> + <%= searchable.username %> +
diff --git a/app/views/account_connections/approve.erb b/app/views/account_connections/approve.erb new file mode 100644 index 0000000..0c55c2d --- /dev/null +++ b/app/views/account_connections/approve.erb @@ -0,0 +1,27 @@ + + + + +
+
+
+

+ Be part of <%= @label.username %> label. +

+

+ <%= @label.username %>, has extended an invitation to be part of their catalog. + If you are agree please click on accept button, if not, just ignore the message +

+
+ <%= button_to approve_account_connection_url(params[:id]), class: "button-sm-outline space-x-2" do %> + Get started + <% end %> + + + Learn more + + +
+
+
+
diff --git a/app/views/account_connections/create.turbo_stream.erb b/app/views/account_connections/create.turbo_stream.erb new file mode 100644 index 0000000..c0e5ace --- /dev/null +++ b/app/views/account_connections/create.turbo_stream.erb @@ -0,0 +1,23 @@ + + +<% if !@created %> + <%= turbo_stream.replace("modal") do %> + <%= render "shared/modal" do %> + <% if params[:kind] %> + <% if params[:kind] == "new" %> + <%= render "new_user" %> + <% elsif params[:kind] == "existing" %> + <%= render "existing" %> + <% end %> + <% end %> + <% end %> + <% end %> +<% else %> + <%= turbo_stream.update("modal") do %> + <%= render "shared/modal" do %> + user invited + <% end %> + <% end %> +<% end %> + +<%= flash_stream %> \ No newline at end of file diff --git a/app/views/account_connections/new.html.erb b/app/views/account_connections/new.html.erb new file mode 100644 index 0000000..be7f21e --- /dev/null +++ b/app/views/account_connections/new.html.erb @@ -0,0 +1,30 @@ + + +<%= render "shared/modal" do %> + <% if params[:kind] %> + + <% if params[:kind] == "new" %> + <%= render "new_user" %> + <% elsif params[:kind] == "existing" %> + <%= render "existing" %> + <% end %> + + <% else %> + +
+
+ +
+ <%= link_to "New Artist", new_account_connection_path(kind: "new"), data: {turbo_frame: "modal"}, class: "p-4 flex justify-center border border-default hover:bg-emphasis" %> + <%= link_to "Existing Artist", new_account_connection_path(kind: "existing"), data: {turbo_frame: "modal"}, class: "p-4 flex justify-center border border-default hover:bg-emphasis" %> +
+ + <%= turbo_frame_tag "dynamic-content" do %> + + <% end %> + +
+
+ + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/account_connections/search b/app/views/account_connections/search new file mode 100644 index 0000000..0549fc3 --- /dev/null +++ b/app/views/account_connections/search @@ -0,0 +1 @@ +rout diff --git a/app/views/account_connections/user_search.turbo_stream.erb b/app/views/account_connections/user_search.turbo_stream.erb new file mode 100644 index 0000000..d9aa7df --- /dev/null +++ b/app/views/account_connections/user_search.turbo_stream.erb @@ -0,0 +1,3 @@ +<%= async_combobox_options @artists, + render_in: { partial: "searchable" }, + next_page: @artists.last_page? ? nil : @artists.next_page %> \ No newline at end of file diff --git a/app/views/connected_account_mailer/invitation_email.erb b/app/views/connected_account_mailer/invitation_email.erb new file mode 100644 index 0000000..aaaf4e1 --- /dev/null +++ b/app/views/connected_account_mailer/invitation_email.erb @@ -0,0 +1,19 @@ + +Dear <%= @artist.full_name %>, +
+ +We are delighted to extend an exclusive invitation for you to join Label <%= @label.username %>, on Rauversion platform. +
+Please confirm your interest by clicking on the following link: +
+<%= approve_account_connection_url(@connected_account.signed_id ) %> + +
+As a member of Label <%= @label.username %>, you will have access to unique collaborative opportunities, +promotional support, and the chance to connect with a network of talented artists and industry professionals. +
+If you have any questions or wish to discuss this exciting opportunity further, please do not hesitate to contact us. +
+Warm regards, +
+Rauversion team \ No newline at end of file diff --git a/app/views/connected_account_mailer/new_account_notification_to_label.erb b/app/views/connected_account_mailer/new_account_notification_to_label.erb new file mode 100644 index 0000000..620afdb --- /dev/null +++ b/app/views/connected_account_mailer/new_account_notification_to_label.erb @@ -0,0 +1,28 @@ + +Dear <%= @label.username %>,
+ +We are excited to announce that a new artist account has been created on the your label, <%= @label.username%> on Rauversion. +
+This addition underscores our commitment to nurturing a diverse and vibrant artistic community. + +
+Artist Details: +
+ +
+Name: <%= @artist.full_name %> +
+ +Account Created On: <%= l @artist.created_at, format: :short %> +
+Please ensure that the artist’s onboarding process is seamless and engaging. +For more information or to review their profile, please visit the link below: +
+<%= user_url @artist.username %> +
+Thank you for your cooperation and enthusiasm as we welcome our newest artist to the Label <%= @label.full_name%> family. + +
+Best regards, +
+Rauversion Team \ No newline at end of file diff --git a/app/views/event_hosts/edit.html.erb b/app/views/event_hosts/edit.html.erb index 2d17c2b..0ba5adc 100644 --- a/app/views/event_hosts/edit.html.erb +++ b/app/views/event_hosts/edit.html.erb @@ -1,5 +1,3 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> - <%= render "form", event_host: @event_host %> - <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> + <%= render "form", event_host: @event_host %> +<% end %> diff --git a/app/views/event_hosts/new.html.erb b/app/views/event_hosts/new.html.erb index 2d17c2b..0ba5adc 100644 --- a/app/views/event_hosts/new.html.erb +++ b/app/views/event_hosts/new.html.erb @@ -1,5 +1,3 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> - <%= render "form", event_host: @event_host %> - <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> + <%= render "form", event_host: @event_host %> +<% end %> diff --git a/app/views/event_purchases/new.html.erb b/app/views/event_purchases/new.html.erb index d108033..487883a 100644 --- a/app/views/event_purchases/new.html.erb +++ b/app/views/event_purchases/new.html.erb @@ -1,6 +1,4 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> - <%= @resp %> - <%= render "form", purchase: @purchase %> - <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> + <%= @resp %> + <%= render "form", purchase: @purchase %> +<% end %> diff --git a/app/views/event_recordings/edit.html.erb b/app/views/event_recordings/edit.html.erb index e916405..fb6c996 100644 --- a/app/views/event_recordings/edit.html.erb +++ b/app/views/event_recordings/edit.html.erb @@ -1,5 +1,3 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> - <%= render "form", event_recording: @event_recording %> - <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> + <%= render "form", event_recording: @event_recording %> +<% end %> diff --git a/app/views/event_recordings/new.html.erb b/app/views/event_recordings/new.html.erb index e916405..fb6c996 100644 --- a/app/views/event_recordings/new.html.erb +++ b/app/views/event_recordings/new.html.erb @@ -1,5 +1,3 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> - <%= render "form", event_recording: @event_recording %> - <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> + <%= render "form", event_recording: @event_recording %> +<% end %> diff --git a/app/views/event_streaming_services/new.html.erb b/app/views/event_streaming_services/new.html.erb index de9d8f6..a5609a5 100644 --- a/app/views/event_streaming_services/new.html.erb +++ b/app/views/event_streaming_services/new.html.erb @@ -1,5 +1,3 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> - <%= render "form", event: @event %> - <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> + <%= render "form", event: @event %> +<% end %> diff --git a/app/views/label_artists/_artist.erb b/app/views/label_artists/_artist.erb new file mode 100644 index 0000000..c8ebd88 --- /dev/null +++ b/app/views/label_artists/_artist.erb @@ -0,0 +1,35 @@ +
+
+ <%= link_to user_path(artist.username), data: {turbo_frame: "_top"} do %> +
+ <%= image_tag(artist.avatar_url, class: "h-full w-full object-cover object-center") %> +
+ +

+ <%= artist.full_name.present? ? artist.full_name : artist.username %> +

+ <% end %> + + + <% if @admin %> + + <% end %> +
+ +
\ No newline at end of file diff --git a/app/views/label_artists/index.html.erb b/app/views/label_artists/index.html.erb new file mode 100644 index 0000000..7b10e4d --- /dev/null +++ b/app/views/label_artists/index.html.erb @@ -0,0 +1,73 @@ + <% admin = current_user && current_user.id == @label&.id %> + +
+
+ + <% # link_to "existing artist", new_account_connection_path %> + +
+ +
+

+ <%= link_to user_path(@label.username), class: "flex space-x-2 items-center py-2" do %> + <%= heroicon("chevron-left") %> + <%= @label.username %> + <% end %> +

+ +

+ Artists +

+
+ + <% if admin %> + <%= link_to new_account_connection_path, class: "button-sm-outline space-x-2", data: {turbo_frame: "modal"} do %> + <%= heroicon("plus") %> + New account Connection + <% end %> + <% end %> +
+ +
+ + <% @label.child_accounts.each do |artist| %> +
+
+ <%= link_to user_path(artist.username) do %> +
+ <%= image_tag(artist.avatar_url, class: "h-full w-full object-cover object-center") %> +
+ +

+ <%= artist.username %> +

+ <% end %> + + + <% if admin %> + + <% end %> +
+ +
+ <% end %> +
+ + +
+
\ No newline at end of file diff --git a/app/views/labels/show.html.erb b/app/views/labels/show.html.erb new file mode 100644 index 0000000..759604c --- /dev/null +++ b/app/views/labels/show.html.erb @@ -0,0 +1,294 @@ +
+
+
+
+ <%= image_tag @user.avatar_url(:medium), class: "sm:w-48 sm:h-48 w-16 h-16 rounded-full" %> +
+
+

<%= @user.username %>

+

<%= @user.first_name %> <%= @user.last_name%>

+

<%= @user.country %> <%= @user.city %>

+
+
+ +
+
+ + +
+ +
+
+ +
+
+
+ + +
+ +
+ +
+
+ + <% if @title == "All" %> + +
+ + <%= turbo_frame_tag "playlist-cards", src: user_playlists_filter_path(@user.username) do %> + loading.... + <% end %> + +
+ + <%= render "spotlights/form" %> + + <% if @user.posts.published.any? %> + <%= render "article_side", articles: @user.posts.published.limit(3) %> + <% end %> + + <% end %> + +
+
+ + + +
+
+
+ +
+ + <%= turbo_frame_tag "paginated-list", class: 'flex flex-col-reverse' do %> + <%= render partial: @section, collection: @collection, as: @as %> + <% end %> + + +
+ + +
+
+
+
+ + + +
\ No newline at end of file diff --git a/app/views/photos/new.erb b/app/views/photos/new.erb index 2c152cb..2c548d9 100644 --- a/app/views/photos/new.erb +++ b/app/views/photos/new.erb @@ -1,15 +1,11 @@ - -<%= turbo_frame_tag "modal" do %> - - <%= render "shared/modal" do %> - <%= form_for current_user, url: photo_path(current_user.id), data: {turbo_frame: "_top"} do |form| %> -

Upload a Image

- <%= form.fields_for :photos, Photo.new do |f| %> -
- <%= f.file_field :image %> - <%= f.submit %> -
- <% end %> +<%= render "shared/modal" do %> + <%= form_for current_user, url: photo_path(current_user.id), data: {turbo_frame: "_top"} do |form| %> +

Upload a Image

+ <%= form.fields_for :photos, Photo.new do |f| %> +
+ <%= f.file_field :image %> + <%= f.submit %> +
<% end %> <% end %> -<% end %> \ No newline at end of file +<% end %> diff --git a/app/views/photos/show.erb b/app/views/photos/show.erb new file mode 100644 index 0000000..de83a68 --- /dev/null +++ b/app/views/photos/show.erb @@ -0,0 +1,24 @@ +<%= render "shared/modal" do %> +
+ + <% if @prev_photo.present? %> +
+ <%= link_to photo_path(@prev_photo, user_id: params[:user_id]), class: "border bg-emphasis rounded-full p-2 w-10 h-10 flex animate scaleX" do %> + <%= heroicon("chevron-left") %> + <% end %> +
+ <% end %> + + <% if @photo.image.present? %> + <%= image_tag @photo.image.variant(resize_to_fill: [1200, 1200]) %> + <% end %> + + <% if @next_photo.present? %> +
+ <%= link_to photo_path(@next_photo, user_id: params[:user_id]), class: "border bg-emphasis rounded-full p-2 w-10 h-10 flex animate scaleX" do %> + <%= heroicon("chevron-right") %> + <% end %> +
+ <% end %> +
+<% end %> \ No newline at end of file diff --git a/app/views/player/_track_info.erb b/app/views/player/_track_info.erb index a1ac010..bde73f1 100644 --- a/app/views/player/_track_info.erb +++ b/app/views/player/_track_info.erb @@ -9,25 +9,25 @@
-
-
+
<% #= Time.now.to_i %> <%= link_to track_path(track), class: "float-left my-0 mr-2 ml-0 text-blue-500 cursor-pointer hover:text-zinc-100" do %>
@@ -42,7 +42,7 @@ "data-turbo-frame": "_top" %> -
+
<%= link_to user_path(track.user.username), "data-turbo-frame": "_top", class: "text-xs cursor-pointer truncate text-muted focus:text-black hover:text-subtle" do %> diff --git a/app/views/playlists/_basic_info_tab.html.erb b/app/views/playlists/_basic_info_tab.html.erb index e210adb..dc2e49f 100644 --- a/app/views/playlists/_basic_info_tab.html.erb +++ b/app/views/playlists/_basic_info_tab.html.erb @@ -9,6 +9,12 @@ <%= form.text_field :title %>
+ <% if impersonating?(@playlist.user) %> +
+ <%= form.check_box :enable_label, hint: "Associate this playlist to the label" %> +
+ <% end %> +
<%= form.text_area :description %>
diff --git a/app/views/playlists/_cards.html.erb b/app/views/playlists/_cards.html.erb index 46d62d5..3bb0cfc 100644 --- a/app/views/playlists/_cards.html.erb +++ b/app/views/playlists/_cards.html.erb @@ -14,7 +14,7 @@ <% end %>
- <%= link_to user_playlists_path(@user.username), class: "text-sm font-semibold leading-6 text-brand-600" do %> + <%= link_to user_playlists_path(@user.username), class: "text-sm font-semibold leading-6 text-brand-600", data: {turbo_frame: "_top"} do %> See all <% end %>
diff --git a/app/views/playlists/_form.html.erb b/app/views/playlists/_form.html.erb index 1b11b8d..93b4c9d 100644 --- a/app/views/playlists/_form.html.erb +++ b/app/views/playlists/_form.html.erb @@ -12,10 +12,19 @@
+ + <% if impersonating?(@playlist.user) %> +
+ <%= form.check_box :enable_label, hint: "Associate this playlist to the label" %> +
+ <% end %> +
<%= form.label :playlist_type %> <%= form.select :playlist_type, Playlist::Types.plain, label: "Playlist type" %>
+ +
@@ -31,6 +40,7 @@
<%= form.radio_button :private, false, label: "Acceso público", hint: "Todo el mundo con el enlace verá este artículo." %>
+
<%= form.radio_button :private, true, label: "Miembros privados al artículo", hint: "Sólo los miembros de este artículo podrían acceder." %>
diff --git a/app/views/playlists/create.turbo_stream.erb b/app/views/playlists/create.turbo_stream.erb index bf71144..91ed366 100644 --- a/app/views/playlists/create.turbo_stream.erb +++ b/app/views/playlists/create.turbo_stream.erb @@ -3,7 +3,7 @@ <%= @playlist.errors.to_json %> <%= render "form" %> <% else %> -

<%= @playlist.type %> Created

+

<%= @playlist.playlist_type %> Created

<%= link_to "Go to playlist", playlist_path(@playlist), "data-turbo-frame": "_top" %>
diff --git a/app/views/playlists/edit.html.erb b/app/views/playlists/edit.html.erb index aea1a4b..ab37524 100644 --- a/app/views/playlists/edit.html.erb +++ b/app/views/playlists/edit.html.erb @@ -1,8 +1,6 @@ -<%= turbo_frame_tag "modal" do %> - <%= render "shared/modal" do %> -
- <%= render "edit_form", playlist: @playlist, tab: @tab %> -
- <% end %> -<% end %> \ No newline at end of file +<%= render "shared/modal" do %> +
+ <%= render "edit_form", playlist: @playlist, tab: @tab %> +
+<% end %> diff --git a/app/views/playlists/new.html.erb b/app/views/playlists/new.html.erb index 5958ced..66f360e 100644 --- a/app/views/playlists/new.html.erb +++ b/app/views/playlists/new.html.erb @@ -1,59 +1,56 @@ -<%= turbo_frame_tag "modal" do %> - - <%= render "shared/modal" do %> -
- - - - - <% if @tab == "add-to-playlist" %> -
-

- <%= t("playlists.add_to_playlist" )%> -

- -
-
-
    - <% Playlist.list_playlists_by_user_with_track(@track.id, current_user.id).each do |playlist| %> - -
  • -
    -
    - - -
    -
    -

    - <%= playlist.title %> -

    -

    -
    -
    - - <%= render "track_playlists/track_item", track: @track, playlist: playlist, track_count: playlist.track_count %> +<%= render "shared/modal" do %> +
    + + + + + <% if @tab == "add-to-playlist" %> +
    +

    + <%= t("playlists.add_to_playlist" )%> +

    + +
    +
    +
      + <% Playlist.list_playlists_by_user_with_track(@track.id, current_user.id).each do |playlist| %> + +
    • +
      +
      + +
      -
    • - - <% end %> - -
    -
    - +
    +

    + <%= playlist.title %> +

    +

    +
    +
    + + <%= render "track_playlists/track_item", track: @track, playlist: playlist, track_count: playlist.track_count %> + +
    +
  • + + <% end %> + +
+
+ -
- <% else %> - <%= render "form" %> - <% end %> -
- <% end %> - -<% end %> \ No newline at end of file +
+ + <% else %> + <%= render "form" %> + <% end %> +
+<% end %> diff --git a/app/views/playlists/show.html.erb b/app/views/playlists/show.html.erb index 6f74195..20ceb37 100644 --- a/app/views/playlists/show.html.erb +++ b/app/views/playlists/show.html.erb @@ -112,7 +112,7 @@ <% if @playlist.user.present? %> -
+
<%= link_to @playlist.user.username, user_path(@playlist.user.username) %>
<% end %> diff --git a/app/views/shared/_modal.html.erb b/app/views/shared/_modal.html.erb index 25c91b3..3147158 100644 --- a/app/views/shared/_modal.html.erb +++ b/app/views/shared/_modal.html.erb @@ -1,3 +1,5 @@ +<%= turbo_frame_tag "modal" do %> +
+<% end %> diff --git a/app/views/shared/_turbo_delete_modal.erb b/app/views/shared/_turbo_delete_modal.erb index a776a12..cbea6aa 100644 --- a/app/views/shared/_turbo_delete_modal.erb +++ b/app/views/shared/_turbo_delete_modal.erb @@ -1,10 +1,10 @@
- + Delete -

+

diff --git a/app/views/shared/_user_menu.html.erb b/app/views/shared/_user_menu.html.erb index 0ed3e43..514758e 100644 --- a/app/views/shared/_user_menu.html.erb +++ b/app/views/shared/_user_menu.html.erb @@ -1,3 +1,17 @@ + +<% if label_user %> + +<% end %> +
<% if current_user && @user.id != current_user&.id %> @@ -87,14 +99,13 @@

<%= @title %>

+ <% if @user.id == current_user&.id %> + <%= link_to @cta_url || new_account_connection_path, class: "button-sm-outline space-x-2", data: {turbo_frame: "modal"} do %> + <%= heroicon("plus") %> + <%= @cta_label || t("tracks.new_track") %> + <% end %> + <% end %> - - - - - <%= t("tracks.new_track") %> - -
@@ -106,7 +117,7 @@ data-infinite-pagination-target="entries" data-turbo="true"> - <%= turbo_frame_tag "paginated-list", class: 'flex flex-col-reverse' do %> + <%= turbo_frame_tag "paginated-list", class: "#{ @collection_class || "flex flex-col-reverse"}" do %> <%= render partial: @section, collection: @collection, as: @as %> <% end %> @@ -153,6 +164,40 @@ <%= link_to "more", "/#{@user.username}/about", class: "mr-2 btn-xs outline rounded-sm p-1" %> + + +
+
+ <% @user.photos.each do |image| %> +
+ <%= link_to photo_path(image, user_id: @user.id), + data: {turbo_frame: "modal"}, + class: "h-auto max-w-full rounded-lg" do %> + +
+
+ +
+
+ + <% end %> +
+ <% end %> +
+
+ +