bullet_train-themes-custom 1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.bt-link +0 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +28 -0
  5. data/Rakefile +8 -0
  6. data/app/assets/config/bullet_train_themes_custom_manifest.js +0 -0
  7. data/app/assets/stylesheets/custom/actiontext.css +26 -0
  8. data/app/assets/stylesheets/custom/application.css +33 -0
  9. data/app/assets/stylesheets/custom/electron.css +46 -0
  10. data/app/assets/stylesheets/custom/fields/cloudinary_image.css +58 -0
  11. data/app/assets/stylesheets/custom/fields/date_field.css +19 -0
  12. data/app/assets/stylesheets/custom/fields/index.css +5 -0
  13. data/app/assets/stylesheets/custom/fields/phone_field.css +7 -0
  14. data/app/assets/stylesheets/custom/fields/super_select.css +103 -0
  15. data/app/assets/stylesheets/custom/fields/trix_editor.css +90 -0
  16. data/app/assets/stylesheets/custom/mailer.scss +359 -0
  17. data/app/assets/stylesheets/custom/tailwind/colors.css +100 -0
  18. data/app/assets/stylesheets/custom/tailwind/components.css +151 -0
  19. data/app/assets/stylesheets/custom/tailwind/dark-mode.css +218 -0
  20. data/app/assets/stylesheets/custom/tailwind/utilities.css +49 -0
  21. data/app/assets/stylesheets/custom/turn.css +44 -0
  22. data/app/assets/stylesheets/custom.tailwind.css +5 -0
  23. data/app/assets/stylesheets/tailwindcss/base.css +1 -0
  24. data/app/assets/stylesheets/tailwindcss/components.css +1 -0
  25. data/app/assets/stylesheets/tailwindcss/utilities.css +1 -0
  26. data/app/javascript/application.custom.js +0 -0
  27. data/app/views/themes/custom/_alert.html.erb +13 -0
  28. data/app/views/themes/custom/_box.html.erb +66 -0
  29. data/app/views/themes/custom/_breadcrumb.html.erb +23 -0
  30. data/app/views/themes/custom/_cell.html.erb +41 -0
  31. data/app/views/themes/custom/_decision_line.html.erb +12 -0
  32. data/app/views/themes/custom/_line.html.erb +3 -0
  33. data/app/views/themes/custom/_notices.html.erb +15 -0
  34. data/app/views/themes/custom/_page.html.erb +12 -0
  35. data/app/views/themes/custom/_title.html.erb +18 -0
  36. data/app/views/themes/custom/attributes/_base.html.erb +30 -0
  37. data/app/views/themes/custom/attributes/_block.html.erb +9 -0
  38. data/app/views/themes/custom/breadcrumbs/_actions.html.erb +22 -0
  39. data/app/views/themes/custom/commentary/_box.html.erb +13 -0
  40. data/app/views/themes/custom/conversations/_card.html.erb +21 -0
  41. data/app/views/themes/custom/conversations/_comment.html.erb +26 -0
  42. data/app/views/themes/custom/conversations/_message.html.erb +136 -0
  43. data/app/views/themes/custom/conversations/_thread_border.html.erb +3 -0
  44. data/app/views/themes/custom/fields/_field.html.erb +81 -0
  45. data/app/views/themes/custom/forms/_errors.html.erb +14 -0
  46. data/app/views/themes/custom/layouts/_account.html.erb +138 -0
  47. data/app/views/themes/custom/layouts/_devise.html.erb +11 -0
  48. data/app/views/themes/custom/layouts/_head.html.erb +8 -0
  49. data/app/views/themes/custom/layouts/_mailer.html.erb +429 -0
  50. data/app/views/themes/custom/memberships/_photos.html.erb +18 -0
  51. data/app/views/themes/custom/menu/_heading.html.erb +3 -0
  52. data/app/views/themes/custom/menu/_item.html.erb +16 -0
  53. data/app/views/themes/custom/menu/_section.html.erb +7 -0
  54. data/app/views/themes/custom/workflow/_box.html.erb +30 -0
  55. data/config/routes.rb +2 -0
  56. data/lib/bullet_train/themes/custom/engine.rb +12 -0
  57. data/lib/bullet_train/themes/custom/version.rb +7 -0
  58. data/lib/bullet_train/themes/custom.rb +16 -0
  59. data/lib/tasks/bullet_train/themes/custom_tasks.rake +53 -0
  60. data/tailwind.custom.config.js +80 -0
  61. metadata +132 -0
@@ -0,0 +1,136 @@
1
+ <% new_message ||= false %>
2
+ <% current_author = defined?(current_user) ? current_user : send(BulletTrain::Conversations.current_participant_helper_method) %>
3
+ <% current_user_message = message.author == current_author %>
4
+ <% avatar = capture do %>
5
+ <% if message.membership %>
6
+ <img src="<%= membership_profile_photo_url(message.membership) %>" title="<%= message.user_name %>" alt="<%= message.user_name %>" class="w-6 h-6 rounded-full <%= current_user_message ? 'order-2' : 'order-1' %>">
7
+ <% elsif message.participant %>
8
+ <div class="<%= current_user_message ? 'order-2' : 'order-1' %>">
9
+ <% if BulletTrain::Conversations.respond_to?(:participant_avatar_partial) && BulletTrain::Conversations.participant_avatar_partial %>
10
+ <%= render BulletTrain::Conversations.participant_avatar_partial, participant: message.participant %>
11
+ <% end %>
12
+ </div>
13
+ <% end %>
14
+ <% end %>
15
+ <% next_message ||= message.next_message %>
16
+
17
+ <%# A message series is a series of messages by the same user, each message within 5 minutes of the previous message. It has nothing to do with replies and message threads %>
18
+ <% next_message_in_series = (message.author == next_message&.author) && (message.created_at > next_message.created_at - 5.minutes) && (message.parent_message_id == next_message&.parent_message_id || message.id == next_message.parent_message_id)%>
19
+ <% if next_message_in_series %>
20
+ <% avatar = nil %>
21
+ <% end %>
22
+
23
+ <%# We set this to true when rendering the messages for the reply view. All messages in the thread are shown in order without any other messages from the conversation %>
24
+ <% show_as_thread ||= false %>
25
+
26
+ <%# placeholder messages are used when displaying a reply to a message that we need to show out of order with the rest %>
27
+ <% placeholder_message ||= false %>
28
+
29
+ <% if avatar.nil? %>
30
+ <% avatar = capture do %>
31
+ <div style="height: 24px; width: 24px;" class="<%= current_user_message ? 'order-2' : 'order-1' %>"></div>
32
+ <% end %>
33
+ <% end %>
34
+
35
+ <% rounding_modifier = message_corner_class(next_message_in_series, current_user_message) %>
36
+
37
+ <% timestamp = next_message_in_series || show_as_thread ? '' : time_ago_in_words(message.created_at) + " ago" %>
38
+
39
+ <% threaded_message = message.threaded? %>
40
+ <% thread_started_by_current_user = message.thread_origin_user == current_author %>
41
+ <% last_message_in_thread = !placeholder_message && threaded_message && (message.next_message.nil? || message.next_message.thread_id != message.thread_id)%>
42
+ <% out_of_thread_message = !show_as_thread && threaded_message && message.reply? && message.previous_message != message.previous_message_in_thread %>
43
+ <% has_replies = message.replies.any? && message.next_message == message.next_message_in_thread %>
44
+ <% border_side = thread_started_by_current_user ? :left : :right %>
45
+ <% show_borders = !show_as_thread && threaded_message %>
46
+
47
+ <% if out_of_thread_message %>
48
+ <%= render 'account/shared/message', message: message.thread_origin_message, next_message: message, placeholder_message: true, show_as_thread: show_as_thread %>
49
+ <% end %>
50
+
51
+
52
+ <div class="chat-message"
53
+ <% unless show_as_thread %>
54
+ data-reply-target="message"
55
+ data-user="<%= message.author.label_string %>"
56
+ data-message-id="<%= message.parent_message_id || message.id %>"
57
+ data-action="mouseleave->reply#hideReplyButton"
58
+ <% end %>
59
+ >
60
+ <div class="group flex <%= 'justify-end' if current_user_message %> <%= 'opacity-20' if new_message %> items-stretch">
61
+ <% if show_borders %>
62
+ <% if (has_replies || placeholder_message) %>
63
+ <%= message_thread_border(side: border_side, position: :start) unless show_as_thread %>
64
+ <% end %>
65
+ <% if message.reply? && ((current_user_message && thread_started_by_current_user) || (!current_user_message && !thread_started_by_current_user) ) %>
66
+ <%= message_thread_border(side: border_side, position: (last_message_in_thread ? :end : :middle)) %>
67
+ <% end %>
68
+ <% end %>
69
+
70
+
71
+ <div class="flex flex-col <%= 'mb-0.5' if next_message_in_series %>">
72
+ <div class="flex items-end relative <%= 'justify-end' if current_user_message %>" data-action="<%= 'click->reply#preventDefault' if show_as_thread %>">
73
+ <div class="flex flex-col space-y-2 text-xs max-w-xs mx-2 <%= current_user_message ? 'order-1 items-end' : 'order-3 items-start' %> z-10 transition-all duration-300"
74
+ data-action="<%= 'mouseenter->reply#showReplyButton click->reply#showReplyButton' unless placeholder_message || show_as_thread %>" data-show-class="<%= current_user_message ? 'mr-10' : 'ml-10' %>"
75
+ >
76
+ <% if placeholder_message %>
77
+ <div class="cursor-pointer" data-thread-url="<%= url_for([:thread, :account, message.thread_origin_message || message]) %>" data-action="click->reply#reply"><span class="px-2 py-1 text-xs text-gray-300 rounded-lg inline-block <%= rounding_modifier %> border-primary-300 border break-words sm:max-w-sm max-w-tiny"><%= Nokogiri::HTML.fragment(trix_sanitize(message.body)).text.truncate(80) %></span></div>
78
+ <% else %>
79
+ <div><span class="px-4 py-2 rounded-lg inline-block <%= rounding_modifier %> <%= current_user_message ? ' bg-primary-600 text-white' : ' bg-gray-300 text-gray-600' %> "><%= trix_sanitize(message.body) %></span></div>
80
+ <% end %>
81
+ </div>
82
+ <%= avatar %>
83
+ <% unless placeholder_message || show_as_thread %>
84
+ <div class="order-2 absolute text-gray-400 bottom-1 hover:text-gray-500 <%= current_user_message ? 'right-10' : 'left-10' %> z-0">
85
+ <button
86
+ data-action="click->reply#reply"
87
+ data-thread-url="<%= url_for([:thread, :account, message.thread_origin_message || message]) %>"
88
+ >
89
+ <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 stroke-current" fill="none" viewBox="0 0 24 24">
90
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
91
+ </svg>
92
+ </button>
93
+ </div>
94
+ <% end %>
95
+ </div>
96
+ <% if message.replies.any? && !show_as_thread %>
97
+ <div class="<%= 'text-right' if current_user_message %>">
98
+ <button class="text-xs text-primary-400 text-right mr-12 ml-12" data-thread-url="<%= url_for([:thread, :account, message.thread_origin_message || message]) %>" data-action="reply#reply"><%= message.replies.size %> <%= t("conversations/messages.navigation.reply").pluralize(message.replies.size) %></button>
99
+ </div>
100
+ <% end %>
101
+
102
+ </div>
103
+ </div>
104
+ <% unless next_message_in_series || placeholder_message %>
105
+ <div class="flex">
106
+ <% if show_borders && !last_message_in_thread %>
107
+ <% if (thread_started_by_current_user && current_user_message) || (!thread_started_by_current_user && !current_user_message) %>
108
+ <%= message_thread_border(side: border_side, position: :middle) %>
109
+ <% end %>
110
+ <% end %>
111
+
112
+ <div class="flex flex-grow order-1 <%= current_user_message ? 'justify-end items-end pr-8' : 'justify-start items-start pl-8' %> <%= 'mb-3' unless next_message_in_series %>">
113
+ <div class="<%= show_as_thread ? 'text-gray-400' : 'text-gray-300' %> text-sm">
114
+ <strong><%= message.author.name %></strong>
115
+ <%= timestamp %>
116
+ </div>
117
+ </div>
118
+ </div>
119
+ <% end %>
120
+ <% if message.replies.any? && false %>
121
+ <div class="mb-4">
122
+ <% message.replies.each do |reply| %>
123
+ <div class="flex text-xs font-extralight text-gray-300 ml-12">
124
+ <div class="<%= 'w-full' if current_user_message %>"></div>
125
+ <svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 682" class="w-5 h-5 stroke-current mt-4 text-gray-50 fill-current">
126
+ <path d="M0 57.7c.1 145.1 4.1 224 14.5 281.1 19.4 106.3 65.2 156.4 166.3 181.7 48.7 12.1 111.4 18.8 211.7 22.5 23.8.9 196.6 2.8 268.2 3H683l.2 67.8.3 67.8 170.3-102.1L1024 477.3l-170.2-102-170.3-102-.3 67.8-.2 67.9h-75.8c-184.7 0-266.9-4.8-327.2-19-34.2-8.1-62.8-21.1-81.2-37-36.1-31.3-52.3-76.8-58.8-165.5-2-28-3-69.2-3-127.8V0H0v57.7z"/>
127
+ </svg>
128
+ <div class="flex flex-col mr-10 min-w-max">
129
+ <div class="pt-0 mr-2 ml-4 text-xxs"><%= reply.membership.label_string %> reply: </div>
130
+ <div class="bg-gray-100 rounded py-2 px-4 mt-0 text-gray-400 max-w-md"><%= reply.body.html_safe %></div>
131
+ </div>
132
+ </div>
133
+ <% end %>
134
+ </div>
135
+ <% end %>
136
+ </div>
@@ -0,0 +1,3 @@
1
+ <div class="flex-grow flex <%= side == :left ? 'justify-start' : 'justify-end order-2' %>">
2
+ <div class=" border-solid border-gray-300 <%= border_classes %> text-white <%= side == :left ? 'ml-12 mr-0' : 'ml-0 mr-12' %> w-6"></div>
3
+ </div>
@@ -0,0 +1,81 @@
1
+ <% yield %>
2
+
3
+ <%
4
+ form ||= current_fields_form
5
+ # returns a struct with `label`, `placeholder`, and `help` methods.
6
+ labels = labels_for(form, method)
7
+ options ||= {}
8
+ options[:id] ||= id_for(form, method)
9
+ # options[:disabled] ||= !field_editable?(form.object, method) if user_signed_in?
10
+ options[:placeholder] ||= labels.placeholder if labels.placeholder
11
+ other_options ||= {}
12
+ other_options[:help] = [other_options[:help], labels.help].compact.join(" ")
13
+
14
+ errors = [method, method.to_s.gsub(/_id$/, '').to_sym].uniq.map { |attribute| form.object.errors.full_messages_for(attribute) }.flatten
15
+ has_errors = errors.any? || content_for(:error).present? || other_options[:error].present?
16
+
17
+ options[:class] = "#{options[:class]} block w-full rounded-md shadow-sm font-light text-sm"
18
+
19
+ options[:class] += if has_errors
20
+ " pr-10 border-red-500 text-red-900 placeholder-red-500 focus:outline-none focus:ring-red-500 focus:border-red-500 dark:bg-darkPrimary-800 dark:text-darkPrimary-300"
21
+ else
22
+ " focus:ring-primary-500 focus:border-primary-500 border-gray-300 dark:bg-darkPrimary-800 dark:border-darkPrimary-900 dark:text-darkPrimary-300"
23
+ end
24
+
25
+ %>
26
+
27
+ <div class="<%= 'required' if presence_validated?(form.object, method) %>">
28
+
29
+ <% # the label. %>
30
+ <% unless other_options[:hide_label] == true %>
31
+ <% if content_for? :label %>
32
+ <%= yield :label %>
33
+ <% flush_content_for :label %>
34
+ <% else %>
35
+ <% # allow the label to be defined via an inline option or else one of the locale yaml definitions. %>
36
+ <% label = (other_options[:label].presence || labels.label || legacy_label_for(form, method)) %>
37
+ <%= form.label method, label&.html_safe, class: 'block', for: options[:id] %>
38
+ <% end %>
39
+ <% end %>
40
+
41
+ <div class="mt-1.5">
42
+
43
+ <% # the actual field. %>
44
+ <% if content_for? :field %>
45
+ <%= yield :field %>
46
+ <% flush_content_for :field %>
47
+ <% else %>
48
+ <% # e.g. form.text_field(method, options) %>
49
+ <%= form.send(helper, method, options) %>
50
+ <% end %>
51
+
52
+ </div>
53
+
54
+ <% # any error messages. %>
55
+ <% if has_errors %>
56
+ <p class="mt-1.5 text-xs text-red">
57
+ <%= errors.map { |error| error + ". " }.join %>
58
+ <%= yield :error %>
59
+ <% flush_content_for :error %>
60
+ <% if other_options[:hide_custom_error].blank? %>
61
+ <%= other_options[:error]&.html_safe %>
62
+ <% end %>
63
+ </p>
64
+ <% end %>
65
+
66
+ <% # any help text. %>
67
+ <% if content_for?(:help) || other_options[:help] || content_for?(:after_help) %>
68
+ <p class="mt-1.5 text-xs text-gray-500">
69
+ <%= yield :help %>
70
+ <% flush_content_for :help %>
71
+ <%= other_options[:help]&.html_safe %>
72
+ <%= yield :after_help %>
73
+ <% flush_content_for :after_help %>
74
+ </p>
75
+ <% end %>
76
+
77
+ <% if other_options[:icon] %>
78
+ <div class="pre-icon os-icon <%= other_options[:icon] %>"></div>
79
+ <% end %>
80
+
81
+ </div>
@@ -0,0 +1,14 @@
1
+ <% attributes ||= [] %>
2
+ <% attributes.select! { |attribute| form.object.errors[attribute].any? } %>
3
+ <% if form.object.errors[:base].any? || form.object.errors.present? || attributes.any? %>
4
+ <%= render 'account/shared/alert', color: 'red' do %>
5
+ <% if form.object.errors[:base].any? || attributes.any? %>
6
+ <%= form.object.errors[:base].join(' ') %>
7
+ <% attributes.each do |attribute| %>
8
+ <%= resource.class.human_attribute_name(attribute) %> <%= resource.errors[attribute].to_sentence %>.
9
+ <% end %>
10
+ <% else %>
11
+ Please correct the errors below.
12
+ <% end %>
13
+ <% end %>
14
+ <% end %>
@@ -0,0 +1,138 @@
1
+ <!DOCTYPE html>
2
+ <html class="theme-<%= BulletTrain::Themes::Custom.color %>">
3
+ <head>
4
+ <%= render 'shared/layouts/head' %>
5
+ </head>
6
+ <body class="bg-light-gradient text-gray-700 text-sm font-normal dark:bg-dark-gradient dark:text-darkPrimary-300">
7
+ <div class="p-4 bg-primary-900 electron-draggable electron-title-bar hidden electron-mobile-only"></div>
8
+ <div class="md:p-5 main-container-padding">
9
+ <div class="h-screen md:h-auto overflow-hidden md:rounded-lg flex shadow main-container"
10
+ data-controller="mobile-menu"
11
+ data-mobile-menu-hidden-class="hidden"
12
+ data-mobile-menu-show-event-name-value="mobile-menu:show"
13
+ data-mobile-menu-hide-event-name-value="mobile-menu:hide"
14
+ >
15
+
16
+ <% menu = capture do %>
17
+ <div class="flex items-center flex-shrink-0 p-4 bg-primary-900 md:rounded-tl-lg electron-draggable electron-title-bar dark:bg-black dark:bg-opacity-10">
18
+ <%= image_tag image_path("logo/logo.png"), class: 'h-5 w-auto mx-auto' %>
19
+
20
+ <div class="lg:hidden absolute right-0">
21
+ <button class="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white dark:ring-transparent"
22
+ data-action="reveal#hide"
23
+ >
24
+ <span class="sr-only">Close Application Menu</span>
25
+ <svg class="h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
26
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
27
+ </svg>
28
+ </button>
29
+ </div>
30
+ </div>
31
+
32
+ <nav class="flex-1 space-y-1 overflow-y-auto select-none">
33
+ <div class="flex-shrink-0 flex shadow px-5 py-4">
34
+ <div class="flex-shrink-0 w-full group block no-underline">
35
+ <div class="flex items-center">
36
+ <div class="inline-block rounded-full border border-white p-1">
37
+ <%= image_tag membership_profile_photo_url(current_membership), class: 'h-9 w-9 rounded-full', alt: current_user.name %>
38
+ </div>
39
+ <div class="ml-3">
40
+ <div class="text-white">
41
+ <%= current_user.name %>
42
+ </div>
43
+ <div class="text-2xs tracking-widest uppercase text-primary-300 group-hover:text-white dark:text-gray-500">
44
+ <%= current_team.name %>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
50
+
51
+ <div class="px-5 py-4 menu">
52
+ <%= render 'account/shared/menu' %>
53
+ </div>
54
+ </nav>
55
+ <% end %>
56
+
57
+ <div class="lg:hidden hidden"
58
+ data-mobile-menu-target="wrapper"
59
+
60
+ data-controller="reveal"
61
+ data-reveal-away-value="true"
62
+ data-reveal-hide-keys-value="escape"
63
+
64
+ data-action="mobile-menu:show->reveal#show mobile-menu:hide->reveal#hide mobile-menu-toggle->reveal#toggle reveal:hidden->mobile-menu#hideWrapper"
65
+ >
66
+ <div class="fixed inset-0 flex z-40">
67
+ <button
68
+ data-action="reveal#hide"
69
+
70
+ hidden
71
+ data-reveal
72
+ data-transition
73
+ data-transition-enter="transition-opacity ease-linear duration-200"
74
+ data-transition-enter-start="opacity-0"
75
+ data-transition-enter-end="opacity-100"
76
+ data-transition-leave="transition-opacity ease-linear duration-200"
77
+ data-transition-leave-start="opacity-100"
78
+ data-transition-leave-end="opacity-0"
79
+
80
+ class="fixed inset-0" aria-hidden="true"
81
+ >
82
+ <div class="absolute inset-0 bg-light-gradient opacity-75"></div>
83
+ </button>
84
+ <div
85
+ hidden
86
+ data-reveal
87
+ data-transition
88
+ data-transition-enter="transition ease-in-out duration-200 transform"
89
+ data-transition-enter-start="-trandarkPrimary-x-full"
90
+ data-transition-enter-end="trandarkPrimary-x-0"
91
+ data-transition-leave="transition ease-in-out duration-200 transform"
92
+ data-transition-leave-start="trandarkPrimary-x-0"
93
+ data-transition-leave-end="-trandarkPrimary-x-full"
94
+
95
+ class="relative flex-1 flex flex-col max-w-xs w-full pb-4 bg-dark-gradient shadow-xl"
96
+ >
97
+ <%= menu %>
98
+ </div>
99
+ <div class="flex-shrink-0 w-14" aria-hidden="true"></div>
100
+ </div>
101
+ </div>
102
+
103
+ <div class="hidden lg:flex lg:flex-shrink-0 overflow-y-auto bg-gradient-to-b from-primary-700 to-primary-800 dark:from-darkPrimary-800 dark:to-darkPrimary-800">
104
+ <div class="w-64">
105
+ <%= menu %>
106
+ </div>
107
+ </div>
108
+
109
+ <div class="flex flex-col w-0 flex-1 overflow-y-auto bg-gray-100 dark:bg-darkPrimary-800 lg:border-l dark:border-gray-500">
110
+ <main class="flex-1 relative z-0 focus:outline-none" tabindex="0">
111
+ <div class="flex flex-row items-center shadow-sm electron-draggable">
112
+ <button class="mobile-menu-trigger lg:hidden h-12 w-12 ml-1 flex-none inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-blue-500"
113
+ data-action="mobile-menu#toggle"
114
+ >
115
+ <span class="sr-only">Open Application Menu</span>
116
+ <svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
117
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
118
+ </svg>
119
+ </button>
120
+
121
+ <nav class="flex px-1 lg:px-4 py-2 overflow-x-auto select-none" aria-label="Breadcrumb">
122
+ <ol class="breadcrumb whitespace-nowrap flex items-center space-x-3 py-0.5 pr-3">
123
+ <%= render('breadcrumbs').strip.html_safe %>
124
+ </ol>
125
+ </nav>
126
+ </div>
127
+
128
+ <div class="py-2 px-1">
129
+ <div class="mx-auto px-4 sm:px-6 py-4">
130
+ <%= yield %>
131
+ </div>
132
+ </div>
133
+ </main>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </body>
138
+ </html>
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html class="theme-<%= BulletTrain::Themes::Custom.color %>">
3
+ <head>
4
+ <%= render 'shared/layouts/head' %>
5
+ </head>
6
+ <body class="bg-light-gradient text-gray-700 text-sm font-normal electron-draggable dark:bg-dark-gradient dark:text-darkPrimary-300">
7
+ <div data-turn-enter data-turn-exit>
8
+ <%= yield %>
9
+ </div>
10
+ </body>
11
+ </html>
@@ -0,0 +1,8 @@
1
+ <%= stylesheet_link_tag 'https://rsms.me/inter/inter.css', media: 'all', 'data-turbo-track': 'reload' %>
2
+ <link href="<%= image_path('logo/favicon.png') %>" rel="shortcut icon" />
3
+ <link href="<%= image_path('logo/icon.png') %>" rel="apple-touch-icon" />
4
+ <%= javascript_include_tag 'application', 'data-turbo-track': 'reload' %>
5
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbo-track': 'reload' %>
6
+ <%= javascript_include_tag 'application.custom', 'data-turbo-track': 'reload' %>
7
+ <%= stylesheet_link_tag 'application.custom', media: 'all', 'data-turbo-track': 'reload' %>
8
+ <%= render 'layouts/head' %>