maquina 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (134) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/images/maquina/maquina.svg +18 -0
  6. data/app/assets/javascripts/maquina/application.js +4 -0
  7. data/app/assets/javascripts/maquina/controllers/alert_controller.js +29 -0
  8. data/app/assets/javascripts/maquina/controllers/application.js +9 -0
  9. data/app/assets/javascripts/maquina/controllers/file_controller.js +60 -0
  10. data/app/assets/javascripts/maquina/controllers/index.js +11 -0
  11. data/app/assets/javascripts/maquina/controllers/mobile_menu_controller.js +31 -0
  12. data/app/assets/javascripts/maquina/controllers/modal_controller.js +39 -0
  13. data/app/assets/javascripts/maquina/controllers/modal_open_controller.js +15 -0
  14. data/app/assets/javascripts/maquina/controllers/popup_menu_controller.js +17 -0
  15. data/app/assets/javascripts/maquina/controllers/submit_form_controller.js +11 -0
  16. data/app/assets/stylesheets/maquina/application.css +15 -0
  17. data/app/assets/stylesheets/maquina/application.tailwind.css +102 -0
  18. data/app/controllers/concerns/maquina/authenticate.rb +41 -0
  19. data/app/controllers/concerns/maquina/create.rb +27 -0
  20. data/app/controllers/concerns/maquina/destroy.rb +28 -0
  21. data/app/controllers/concerns/maquina/edit.rb +29 -0
  22. data/app/controllers/concerns/maquina/index.rb +33 -0
  23. data/app/controllers/concerns/maquina/new.rb +22 -0
  24. data/app/controllers/concerns/maquina/resourceful.rb +180 -0
  25. data/app/controllers/concerns/maquina/show.rb +27 -0
  26. data/app/controllers/concerns/maquina/update.rb +31 -0
  27. data/app/controllers/maquina/accept_invitations_controller.rb +28 -0
  28. data/app/controllers/maquina/application_controller.rb +19 -0
  29. data/app/controllers/maquina/dashboard_controller.rb +16 -0
  30. data/app/controllers/maquina/invitations_controller.rb +51 -0
  31. data/app/controllers/maquina/plans_controller.rb +56 -0
  32. data/app/controllers/maquina/sessions_controller.rb +56 -0
  33. data/app/controllers/maquina/unauthorized_controller.rb +9 -0
  34. data/app/controllers/maquina/users_controller.rb +24 -0
  35. data/app/helpers/maquina/application_helper.rb +19 -0
  36. data/app/helpers/maquina/navbar_menu_helper.rb +29 -0
  37. data/app/helpers/maquina/views_helper.rb +9 -0
  38. data/app/jobs/maquina/application_job.rb +4 -0
  39. data/app/mailers/maquina/application_mailer.rb +8 -0
  40. data/app/mailers/maquina/user_notifications_mailer.rb +16 -0
  41. data/app/models/concerns/maquina/authenticate_by.rb +33 -0
  42. data/app/models/concerns/maquina/blockeable.rb +28 -0
  43. data/app/models/concerns/maquina/multifactor.rb +80 -0
  44. data/app/models/concerns/maquina/retain_passwords.rb +32 -0
  45. data/app/models/concerns/maquina/searchable.rb +24 -0
  46. data/app/models/maquina/active_session.rb +33 -0
  47. data/app/models/maquina/application_record.rb +11 -0
  48. data/app/models/maquina/current.rb +21 -0
  49. data/app/models/maquina/invitation.rb +15 -0
  50. data/app/models/maquina/plan.rb +38 -0
  51. data/app/models/maquina/used_password.rb +17 -0
  52. data/app/models/maquina/user.rb +33 -0
  53. data/app/policies/maquina/application_policy.rb +50 -0
  54. data/app/policies/maquina/invitation_policy.rb +13 -0
  55. data/app/policies/maquina/navigation_policy.rb +13 -0
  56. data/app/policies/maquina/plan_policy.rb +49 -0
  57. data/app/policies/maquina/user_policy.rb +27 -0
  58. data/app/views/layouts/maquina/application.html.erb +26 -0
  59. data/app/views/layouts/maquina/mailer.html.erb +377 -0
  60. data/app/views/layouts/maquina/mailer.text.erb +12 -0
  61. data/app/views/layouts/maquina/sessions.html.erb +24 -0
  62. data/app/views/maquina/accept_invitations/new.html.erb +9 -0
  63. data/app/views/maquina/accept_invitations/new_view.rb +41 -0
  64. data/app/views/maquina/application/_navbar.html.erb +21 -0
  65. data/app/views/maquina/application/alert.rb +104 -0
  66. data/app/views/maquina/application/components/action_text_component.rb +20 -0
  67. data/app/views/maquina/application/components/checkbox_component.rb +21 -0
  68. data/app/views/maquina/application/components/component_base.rb +60 -0
  69. data/app/views/maquina/application/components/file_component.rb +59 -0
  70. data/app/views/maquina/application/components/input_component.rb +20 -0
  71. data/app/views/maquina/application/components/select_component.rb +44 -0
  72. data/app/views/maquina/application/create.turbo_stream.erb +11 -0
  73. data/app/views/maquina/application/edit.html.erb +9 -0
  74. data/app/views/maquina/application/edit.rb +17 -0
  75. data/app/views/maquina/application/form.rb +77 -0
  76. data/app/views/maquina/application/index.html.erb +10 -0
  77. data/app/views/maquina/application/index_header.rb +46 -0
  78. data/app/views/maquina/application/index_modal.rb +43 -0
  79. data/app/views/maquina/application/index_table.rb +121 -0
  80. data/app/views/maquina/application/new.html.erb +9 -0
  81. data/app/views/maquina/application/new.rb +18 -0
  82. data/app/views/maquina/application/sessions_header.rb +31 -0
  83. data/app/views/maquina/application/show.html.erb +1 -0
  84. data/app/views/maquina/application/update.turbo_stream.erb +11 -0
  85. data/app/views/maquina/application_view.rb +46 -0
  86. data/app/views/maquina/dashboard/index.html.erb +0 -0
  87. data/app/views/maquina/invitations/create.turbo_stream.erb +13 -0
  88. data/app/views/maquina/invitations/new.html.erb +3 -0
  89. data/app/views/maquina/navbar/menu.rb +62 -0
  90. data/app/views/maquina/navbar/menu_item_link.rb +34 -0
  91. data/app/views/maquina/navbar/mobile_button.rb +29 -0
  92. data/app/views/maquina/navbar/mobile_menu.rb +47 -0
  93. data/app/views/maquina/navbar/notification.rb +37 -0
  94. data/app/views/maquina/navbar/profile.rb +16 -0
  95. data/app/views/maquina/navbar/profile_button.rb +24 -0
  96. data/app/views/maquina/navbar/profile_menu.rb +108 -0
  97. data/app/views/maquina/navbar/profile_menu_item_link.rb +41 -0
  98. data/app/views/maquina/navbar/search.rb +40 -0
  99. data/app/views/maquina/navbar/title.rb +22 -0
  100. data/app/views/maquina/sessions/create.turbo_stream.erb +11 -0
  101. data/app/views/maquina/sessions/form.rb +56 -0
  102. data/app/views/maquina/sessions/new.html.erb +9 -0
  103. data/app/views/maquina/unauthorized/401.html.erb +1 -0
  104. data/app/views/maquina/user_notifications_mailer/invitation_email.html.erb +40 -0
  105. data/app/views/maquina/user_notifications_mailer/invitation_email.text.erb +12 -0
  106. data/config/definitions.rb +1 -0
  107. data/config/initializers/importmap.rb +17 -0
  108. data/config/initializers/money.rb +116 -0
  109. data/config/initializers/pagy.rb +235 -0
  110. data/config/locales/flash.en.yml +44 -0
  111. data/config/locales/forms.en.yml +58 -0
  112. data/config/locales/mailers.en.yml +35 -0
  113. data/config/locales/models.en.yml +34 -0
  114. data/config/locales/routes.en.yml +7 -0
  115. data/config/locales/views.en.yml +45 -0
  116. data/config/routes.rb +17 -0
  117. data/db/migrate/20221109010726_create_maquina_plans.rb +13 -0
  118. data/db/migrate/20221113000409_create_maquina_users.rb +19 -0
  119. data/db/migrate/20221113020108_create_maquina_used_passwords.rb +10 -0
  120. data/db/migrate/20221115223414_create_maquina_active_sessions.rb +15 -0
  121. data/db/migrate/20230201203922_create_maquina_invitations.rb +12 -0
  122. data/db/schema.rb +1 -0
  123. data/lib/generators/maquina/install_generator.rb +32 -0
  124. data/lib/generators/maquina/install_templates/install_templates_generator.rb +31 -0
  125. data/lib/generators/maquina/tailwind_config/tailwind_config_generator.rb +11 -0
  126. data/lib/generators/maquina/tailwind_config/templates/app/assets/config/maquina/tailwind.config.js.tt +68 -0
  127. data/lib/generators/maquina/templates/config/initializers/maquina.rb +3 -0
  128. data/lib/maquina/engine.rb +17 -0
  129. data/lib/maquina/version.rb +3 -0
  130. data/lib/maquina.rb +48 -0
  131. data/lib/tasks/install.rake +19 -0
  132. data/lib/tasks/maquina_tasks.rake +4 -0
  133. data/lib/tasks/tailwind.rake +25 -0
  134. metadata +456 -0
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Pagy initializer file (5.10.1)
4
+ # Customize only what you really need and notice that the core Pagy works also without any of the following lines.
5
+ # Should you just cherry pick part of this file, please maintain the require-order of the extras
6
+
7
+ # Pagy DEFAULT Variables
8
+ # See https://ddnexus.github.io/pagy/api/pagy#variables
9
+ # All the Pagy::DEFAULT are set for all the Pagy instances but can be overridden per instance by just passing them to
10
+ # Pagy.new|Pagy::Countless.new|Pagy::Calendar::*.new or any of the #pagy* controller methods
11
+
12
+ # Instance variables
13
+ # See https://ddnexus.github.io/pagy/api/pagy#instance-variables
14
+ # Pagy::DEFAULT[:page] = 1 # default
15
+ # Pagy::DEFAULT[:items] = 20 # default
16
+ # Pagy::DEFAULT[:outset] = 0 # default
17
+
18
+ # Other Variables
19
+ # See https://ddnexus.github.io/pagy/api/pagy#other-variables
20
+ # Pagy::DEFAULT[:size] = [1,4,4,1] # default
21
+ # Pagy::DEFAULT[:page_param] = :page # default
22
+ # The :params can be also set as a lambda e.g ->(params){ params.exclude('useless').merge!('custom' => 'useful') }
23
+ # Pagy::DEFAULT[:params] = {} # default
24
+ # Pagy::DEFAULT[:fragment] = '#fragment' # example
25
+ # Pagy::DEFAULT[:link_extra] = 'data-remote="true"' # example
26
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
27
+ # Pagy::DEFAULT[:cycle] = true # example
28
+
29
+ # Extras
30
+ # See https://ddnexus.github.io/pagy/extras
31
+
32
+ # Backend Extras
33
+
34
+ # Array extra: Paginate arrays efficiently, avoiding expensive array-wrapping and without overriding
35
+ # See https://ddnexus.github.io/pagy/extras/array
36
+ # require 'pagy/extras/array'
37
+
38
+ # Calendar extra: Add pagination filtering by calendar time unit (year, quarter, month, week, day)
39
+ # See https://ddnexus.github.io/pagy/extras/calendar
40
+ # require 'pagy/extras/calendar'
41
+ # Default for each unit
42
+ # Pagy::Calendar::Year::DEFAULT[:order] = :asc # Time direction of pagination
43
+ # Pagy::Calendar::Year::DEFAULT[:format] = '%Y' # strftime format
44
+ #
45
+ # Pagy::Calendar::Quarter::DEFAULT[:order] = :asc # Time direction of pagination
46
+ # Pagy::Calendar::Quarter::DEFAULT[:format] = '%Y-Q%q' # strftime format
47
+ #
48
+ # Pagy::Calendar::Month::DEFAULT[:order] = :asc # Time direction of pagination
49
+ # Pagy::Calendar::Month::DEFAULT[:format] = '%Y-%m' # strftime format
50
+ #
51
+ # Pagy::Calendar::Week::DEFAULT[:order] = :asc # Time direction of pagination
52
+ # Pagy::Calendar::Week::DEFAULT[:format] = '%Y-%W' # strftime format
53
+ #
54
+ # Pagy::Calendar::Day::DEFAULT[:order] = :asc # Time direction of pagination
55
+ # Pagy::Calendar::Day::DEFAULT[:format] = '%Y-%m-%d' # strftime format
56
+ #
57
+ # Uncomment the following lines, if you need calendar localization without using the I18n extra
58
+ # module LocalizePagyCalendar
59
+ # def localize(time, opts)
60
+ # ::I18n.l(time, **opts)
61
+ # end
62
+ # end
63
+ # Pagy::Calendar.prepend LocalizePagyCalendar
64
+
65
+ # Countless extra: Paginate without any count, saving one query per rendering
66
+ # See https://ddnexus.github.io/pagy/extras/countless
67
+ # require 'pagy/extras/countless'
68
+ # Pagy::DEFAULT[:countless_minimal] = false # default (eager loading)
69
+
70
+ # Elasticsearch Rails extra: Paginate `ElasticsearchRails::Results` objects
71
+ # See https://ddnexus.github.io/pagy/extras/elasticsearch_rails
72
+ # Default :pagy_search method: change only if you use also
73
+ # the searchkick or meilisearch extra that defines the same
74
+ # Pagy::DEFAULT[:elasticsearch_rails_pagy_search] = :pagy_search
75
+ # Default original :search method called internally to do the actual search
76
+ # Pagy::DEFAULT[:elasticsearch_rails_search] = :search
77
+ # require 'pagy/extras/elasticsearch_rails'
78
+
79
+ # Headers extra: http response headers (and other helpers) useful for API pagination
80
+ # See http://ddnexus.github.io/pagy/extras/headers
81
+ # require 'pagy/extras/headers'
82
+ # Pagy::DEFAULT[:headers] = { page: 'Current-Page',
83
+ # items: 'Page-Items',
84
+ # count: 'Total-Count',
85
+ # pages: 'Total-Pages' } # default
86
+
87
+ # Meilisearch extra: Paginate `Meilisearch` result objects
88
+ # See https://ddnexus.github.io/pagy/extras/meilisearch
89
+ # Default :pagy_search method: change only if you use also
90
+ # the elasticsearch_rails or searchkick extra that define the same method
91
+ # Pagy::DEFAULT[:meilisearch_pagy_search] = :pagy_search
92
+ # Default original :search method called internally to do the actual search
93
+ # Pagy::DEFAULT[:meilisearch_search] = :ms_search
94
+ # require 'pagy/extras/meilisearch'
95
+
96
+ # Metadata extra: Provides the pagination metadata to Javascript frameworks like Vue.js, react.js, etc.
97
+ # See https://ddnexus.github.io/pagy/extras/metadata
98
+ # you must require the frontend helpers internal extra (BEFORE the metadata extra) ONLY if you need also the :sequels
99
+ # require 'pagy/extras/frontend_helpers'
100
+ # require 'pagy/extras/metadata'
101
+ # For performance reasons, you should explicitly set ONLY the metadata you use in the frontend
102
+ # Pagy::DEFAULT[:metadata] = %i[scaffold_url page prev next last] # example
103
+
104
+ # Searchkick extra: Paginate `Searchkick::Results` objects
105
+ # See https://ddnexus.github.io/pagy/extras/searchkick
106
+ # Default :pagy_search method: change only if you use also
107
+ # the elasticsearch_rails or meilisearch extra that defines the same
108
+ # DEFAULT[:searchkick_pagy_search] = :pagy_search
109
+ # Default original :search method called internally to do the actual search
110
+ # Pagy::DEFAULT[:searchkick_search] = :search
111
+ # require 'pagy/extras/searchkick'
112
+ # uncomment if you are going to use Searchkick.pagy_search
113
+ # Searchkick.extend Pagy::Searchkick
114
+
115
+ # Frontend Extras
116
+
117
+ # Bootstrap extra: Add nav, nav_js and combo_nav_js helpers and templates for Bootstrap pagination
118
+ # See https://ddnexus.github.io/pagy/extras/bootstrap
119
+ # require 'pagy/extras/bootstrap'
120
+
121
+ # Bulma extra: Add nav, nav_js and combo_nav_js helpers and templates for Bulma pagination
122
+ # See https://ddnexus.github.io/pagy/extras/bulma
123
+ # require 'pagy/extras/bulma'
124
+
125
+ # Foundation extra: Add nav, nav_js and combo_nav_js helpers and templates for Foundation pagination
126
+ # See https://ddnexus.github.io/pagy/extras/foundation
127
+ # require 'pagy/extras/foundation'
128
+
129
+ # Materialize extra: Add nav, nav_js and combo_nav_js helpers for Materialize pagination
130
+ # See https://ddnexus.github.io/pagy/extras/materialize
131
+ # require 'pagy/extras/materialize'
132
+
133
+ # Navs extra: Add nav_js and combo_nav_js javascript helpers
134
+ # Notice: the other frontend extras add their own framework-styled versions,
135
+ # so require this extra only if you need the unstyled version
136
+ # See https://ddnexus.github.io/pagy/extras/navs
137
+ # require 'pagy/extras/navs'
138
+
139
+ # Semantic extra: Add nav, nav_js and combo_nav_js helpers for Semantic UI pagination
140
+ # See https://ddnexus.github.io/pagy/extras/semantic
141
+ # require 'pagy/extras/semantic'
142
+
143
+ # UIkit extra: Add nav helper and templates for UIkit pagination
144
+ # See https://ddnexus.github.io/pagy/extras/uikit
145
+ # require 'pagy/extras/uikit'
146
+
147
+ # Multi size var used by the *_nav_js helpers
148
+ # See https://ddnexus.github.io/pagy/extras/navs#steps
149
+ # Pagy::DEFAULT[:steps] = { 0 => [2,3,3,2], 540 => [3,5,5,3], 720 => [5,7,7,5] } # example
150
+
151
+ # Feature Extras
152
+
153
+ # Gearbox extra: Automatically change the number of items per page depending on the page number
154
+ # See https://ddnexus.github.io/pagy/extras/gearbox
155
+ # require 'pagy/extras/gearbox'
156
+ # set to false only if you want to make :gearbox_extra an opt-in variable
157
+ # Pagy::DEFAULT[:gearbox_extra] = false # default true
158
+ # Pagy::DEFAULT[:gearbox_items] = [15, 30, 60, 100] # default
159
+
160
+ # Items extra: Allow the client to request a custom number of items per page with an optional selector UI
161
+ # See https://ddnexus.github.io/pagy/extras/items
162
+ # require 'pagy/extras/items'
163
+ # set to false only if you want to make :items_extra an opt-in variable
164
+ # Pagy::DEFAULT[:items_extra] = false # default true
165
+ # Pagy::DEFAULT[:items_param] = :items # default
166
+ # Pagy::DEFAULT[:max_items] = 100 # default
167
+
168
+ # Overflow extra: Allow for easy handling of overflowing pages
169
+ # See https://ddnexus.github.io/pagy/extras/overflow
170
+ # require 'pagy/extras/overflow'
171
+ # Pagy::DEFAULT[:overflow] = :empty_page # default (other options: :last_page and :exception)
172
+
173
+ # Support extra: Extra support for features like: incremental, infinite, auto-scroll pagination
174
+ # See https://ddnexus.github.io/pagy/extras/support
175
+ # require 'pagy/extras/support'
176
+
177
+ # Trim extra: Remove the page=1 param from links
178
+ # See https://ddnexus.github.io/pagy/extras/trim
179
+ # require 'pagy/extras/trim'
180
+ # set to false only if you want to make :trim_extra an opt-in variable
181
+ # Pagy::DEFAULT[:trim_extra] = false # default true
182
+
183
+ # Standalone extra: Use pagy in non Rack environment/gem
184
+ # See https://ddnexus.github.io/pagy/extras/standalone
185
+ # require 'pagy/extras/standalone'
186
+ # Pagy::DEFAULT[:url] = 'http://www.example.com/subdir' # optional default
187
+
188
+ # Rails
189
+ # Enable the .js file required by the helpers that use javascript
190
+ # (pagy*_nav_js, pagy*_combo_nav_js, and pagy_items_selector_js)
191
+ # See https://ddnexus.github.io/pagy/extras#javascript
192
+
193
+ # With the asset pipeline
194
+ # Sprockets need to look into the pagy javascripts dir, so add it to the assets paths
195
+ # Rails.application.config.assets.paths << Pagy.root.join('javascripts')
196
+
197
+ # I18n
198
+
199
+ # Pagy internal I18n: ~18x faster using ~10x less memory than the i18n gem
200
+ # See https://ddnexus.github.io/pagy/api/frontend#i18n
201
+ # Notice: No need to configure anything in this section if your app uses only "en"
202
+ # or if you use the i18n extra below
203
+ #
204
+ # Examples:
205
+ # load the "de" built-in locale:
206
+ # Pagy::I18n.load(locale: 'de')
207
+ #
208
+ # load the "de" locale defined in the custom file at :filepath:
209
+ # Pagy::I18n.load(locale: 'de', filepath: 'path/to/pagy-de.yml')
210
+ #
211
+ # load the "de", "en" and "es" built-in locales:
212
+ # (the first passed :locale will be used also as the default_locale)
213
+ # Pagy::I18n.load({ locale: 'de' },
214
+ # { locale: 'en' },
215
+ # { locale: 'es' })
216
+ #
217
+ # load the "en" built-in locale, a custom "es" locale,
218
+ # and a totally custom locale complete with a custom :pluralize proc:
219
+ # (the first passed :locale will be used also as the default_locale)
220
+ # Pagy::I18n.load({ locale: 'en' },
221
+ # { locale: 'es', filepath: 'path/to/pagy-es.yml' },
222
+ # { locale: 'xyz', # not built-in
223
+ # filepath: 'path/to/pagy-xyz.yml',
224
+ # pluralize: lambda{ |count| ... } )
225
+
226
+ # I18n extra: uses the standard i18n gem which is ~18x slower using ~10x more memory
227
+ # than the default pagy internal i18n (see above)
228
+ # See https://ddnexus.github.io/pagy/extras/i18n
229
+ # require 'pagy/extras/i18n'
230
+
231
+ # Default i18n key
232
+ # Pagy::DEFAULT[:i18n_key] = 'pagy.item_name' # default
233
+
234
+ # When you are done setting your own default freeze it, so it will not get changed accidentally
235
+ Pagy::DEFAULT.freeze
@@ -0,0 +1,44 @@
1
+ en:
2
+ flash:
3
+ create:
4
+ notice:
5
+ title: Saved successfully
6
+ description: Your record has been successfully added
7
+ alert:
8
+ title: Save failed
9
+ description: Review the messages in the form to resolve the issue
10
+
11
+ update:
12
+ notice:
13
+ title: Updated successfully
14
+ description: Your record has been successfully updated
15
+ alert:
16
+ title: Update failed
17
+ description: Review the messages in the form to resolve the issue
18
+
19
+ destroy:
20
+ notice:
21
+ title: Deleted successfully
22
+ description: The record has been successfully deleted
23
+ alert:
24
+ title: Delete failed
25
+ description: Review the messages in the form to resolve the issue
26
+
27
+ maquina/invitation:
28
+ create:
29
+ notice:
30
+ title: Invitation sent
31
+ description: Invitation for %{email} expires in 3 days
32
+
33
+ sessions:
34
+ create:
35
+ notice:
36
+ title: Session started
37
+ description: Welcome back!
38
+ alert:
39
+ title: Invalid credentials
40
+ description: Email or password are invalid
41
+ destroy:
42
+ notice:
43
+ title: Session ended
44
+ description: Your sessions was terminated
@@ -0,0 +1,58 @@
1
+ en:
2
+ new:
3
+ maquina/plan:
4
+ title: Configure a plan for your customers
5
+ maquina/invitation:
6
+ title: User will receive an invitation to join this application in the provided email.
7
+
8
+ form:
9
+ sessions:
10
+ email: Email address
11
+ password: Password
12
+ forgot_password: Forgot your password?
13
+ submit: Sign in
14
+
15
+ accept_invitations:
16
+ submit: Accept invitation
17
+
18
+ placeholder:
19
+ sessions:
20
+ email: user@mail.com
21
+ password: Current password
22
+
23
+ maquina/plan:
24
+ name: Basic plan
25
+
26
+ maquina/invitation:
27
+ email: Enter user's email
28
+
29
+ maxlength:
30
+ default: 30
31
+
32
+ maquina/plan:
33
+ name: 60
34
+ trial: 3
35
+ price: 9
36
+
37
+ sessions:
38
+ email: 60
39
+ password: 60
40
+
41
+ help:
42
+ maquina/plan:
43
+ name: Descriptive plan name
44
+ trial: Number of days on trial
45
+ price: Price for not free plans
46
+ free: Check if plan is free of cost
47
+ active: Active plans are available for customers
48
+
49
+ helpers:
50
+ cancel: Cancel
51
+ submit:
52
+ maquina/plan:
53
+ create: Create %{model}
54
+ update: Update %{model}
55
+
56
+ maquina/invitation:
57
+ create: Send invitation
58
+
@@ -0,0 +1,35 @@
1
+ en:
2
+ mailers:
3
+ default_from: no-reply@maquina.org
4
+ copyright: "© 2023 Maquina. All rights reserved."
5
+ company_name: Maquina, LLC
6
+ address_1: Colima, Colima
7
+ address_2: México
8
+ product_name: Maquina Webapp Framework
9
+
10
+ invitation_email:
11
+ subject: You have an invitation to join %{org}
12
+ hello: Hi!
13
+ action: Set up account
14
+ content_1: >
15
+ %{inviteer} with %{org} has invited you to use %{product} to collaborate with them.
16
+ Use the button bellow to set up your account and get started, remember, this invitation
17
+ link is valid for 3 days:
18
+ content_1_text: >
19
+ %{inviteer} with %{org} has invited you to use %{product} to collaborate with them.
20
+ Copy and paste the URL bellow in your web browser to set up your account and get started, remember, this invitation
21
+ link is valid for 3 days:
22
+ content_2: >
23
+ If you have any questions, feel free to <a href="mailto:contact@maquina.org" class="text-blue-postmark">contact us</a> anytime.
24
+ content_2_text: >
25
+ If you have any questions, feel free to contact us anytime at contact@maquina.org.
26
+ content_3: >
27
+ Welcome aboard,
28
+ <br>The %{org} Team
29
+ content_3_1_text: Welcome aboard,
30
+ content_3_2_text: The %{org} Team
31
+ content_4: >
32
+ <strong>P.S.</strong> Do not forward this email to anyone.
33
+ content_4_text: P.S. Do not forward this email to anyone.
34
+ footer: >
35
+ If you're having trouble with the button above, copy and paste the URL below into your web browser.
@@ -0,0 +1,34 @@
1
+ en:
2
+ activerecord:
3
+ models:
4
+ maquina/plan:
5
+ one: Plan
6
+ other: Plans
7
+ maquina/user:
8
+ one: User
9
+ other: Users
10
+ maquina/invitation:
11
+ one: Invitation
12
+ other: Invitations
13
+ attributes:
14
+ maquina/plan:
15
+ name: Name
16
+ trial: Trial days
17
+ price: Price
18
+ free: Free
19
+ active: Active
20
+ maquina/user:
21
+ blocked_at: Blocked At
22
+ created_at: Created At
23
+
24
+ errors:
25
+ models:
26
+ maquina/active_session:
27
+ attributes:
28
+ user:
29
+ blocked: account is blocked
30
+ maquina/invitation:
31
+ attributes:
32
+ email:
33
+ blank: please provide an email to send invitation
34
+ invalid: user already accepted the invitation
@@ -0,0 +1,7 @@
1
+ en:
2
+ routes:
3
+ plans: plans
4
+ users: users
5
+ invitations: invitations
6
+ accept_invitation: accept_invitation
7
+ sessions: sessions
@@ -0,0 +1,45 @@
1
+ en:
2
+ application_name: Maquina
3
+ yes_value: "Yes"
4
+ no_value: "No"
5
+
6
+ index:
7
+ add_new: Add new %{model}
8
+ no_items: There are currently no %{model} to display
9
+ edit: Edit
10
+ maquina/plan:
11
+ description: List of customer's plans.
12
+ maquina/user:
13
+ add_new: Invite %{model}
14
+ description: List of users.
15
+ search: Showing results with term <span class="font-semibold text-skin-accented">%{search}</span>
16
+
17
+ pagination:
18
+ previous: Previous
19
+ next: Next
20
+ information: Showing %{from} to %{to} of %{count} results
21
+
22
+ menu:
23
+ main:
24
+ plans: Plans
25
+ users: Users
26
+ profile:
27
+ signout: Close session
28
+ signin: Login
29
+
30
+ search:
31
+ search: Search
32
+
33
+ maquina:
34
+ sessions:
35
+ new:
36
+ title: Sign in to your account
37
+ or: Or
38
+ trial: start your 14-day free trial
39
+
40
+ accept_invitations:
41
+ new:
42
+ title: Accept invitation
43
+ description: Here you can accept your invitation to collaborate with %{org}
44
+
45
+ expired: The invitation is invalid, expired, or was already accepted. If you believe this is not correct, please contact the person who sent it to you and ask for a new invitation.
data/config/routes.rb ADDED
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ Maquina::Engine.routes.draw do
4
+ resource :unauthorized, controller: :unauthorized, only: [:show]
5
+
6
+ resource :sessions, path: I18n.t("routes.sessions"), only: [:new, :create, :destroy]
7
+ resource :multifactor, only: [:new, :create]
8
+
9
+ get I18n.t("routes.accept_invitation"), to: "accept_invitations#new", as: :new_accept_invitations
10
+ patch I18n.t("routes.accept_invitation"), to: "accept_invitations#update", as: :accept_invitations
11
+
12
+ resources :plans, path: I18n.t("routes.plans"), except: [:show, :destroy]
13
+ resources :users, path: I18n.t("routes.users"), only: [:index]
14
+ resources :invitations, path: I18n.t("routes.invitations"), only: [:new, :create]
15
+
16
+ root to: "dashboard#index"
17
+ end
@@ -0,0 +1,13 @@
1
+ class CreateMaquinaPlans < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :maquina_plans do |t|
4
+ t.string :name, null: false
5
+ t.boolean :free, default: false
6
+ t.integer :trial, default: 0
7
+ t.boolean :active, default: false
8
+ t.monetize :price
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ class CreateMaquinaUsers < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :maquina_users do |t|
4
+ t.string :email, null: false
5
+ t.boolean :management, default: false
6
+ t.string :password_digest, null: false
7
+ t.timestamp :blocked_at
8
+ t.timestamp :temporary_blocked_at
9
+ t.timestamp :last_otp_at
10
+ t.timestamp :password_expires_at
11
+ t.string :otp_secret_key
12
+ t.string :otp_recovery_codes
13
+
14
+ t.timestamps
15
+ end
16
+
17
+ add_index :maquina_users, :email, unique: true
18
+ end
19
+ end
@@ -0,0 +1,10 @@
1
+ class CreateMaquinaUsedPasswords < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :maquina_used_passwords do |t|
4
+ t.string :password_digest
5
+ t.references :maquina_user, null: false, foreign_key: true
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateMaquinaActiveSessions < ActiveRecord::Migration[7.0]
4
+ def change
5
+ create_table :maquina_active_sessions do |t|
6
+ t.references :maquina_user, null: false, foreign_key: true
7
+ t.timestamp :expires_at
8
+ t.string :user_agent
9
+ t.string :remote_addr
10
+ t.string :return_url
11
+
12
+ t.timestamps
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ class CreateMaquinaInvitations < ActiveRecord::Migration[7.0]
2
+ def change
3
+ create_table :maquina_invitations do |t|
4
+ t.string :email, null: false
5
+ t.timestamp :accepted_at
6
+
7
+ t.timestamps
8
+ end
9
+
10
+ add_index :maquina_invitations, :email
11
+ end
12
+ end
data/db/schema.rb ADDED
@@ -0,0 +1 @@
1
+ ../test/dummy/db/schema.rb
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maquina
4
+ class InstallGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("../templates", __FILE__)
6
+
7
+ def create_initializer_file
8
+ template "config/initializers/maquina.rb"
9
+ end
10
+
11
+ def add_route
12
+ return if Rails.application.routes.routes.detect { |route| route.app.app == Maquina::Engine }
13
+ route %(mount Maquina::Engine => "/m")
14
+ end
15
+
16
+ def add_concerns
17
+ inject_into_file "app/controllers/application_controller.rb", after: "ActionController::Base" do
18
+ <<~EOF
19
+ \n include Maquina::Authenticate
20
+ EOF
21
+ end
22
+ end
23
+
24
+ def copy_migrations
25
+ rake "maquina:install:migrations"
26
+ end
27
+
28
+ def build_tailwind
29
+ rake "maquina:tailwindcss:build"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maquina
4
+ module Generators
5
+ class InstallTemplatesGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../../../../app/views", __FILE__)
7
+
8
+ def copy_layout
9
+ empty_directory "app/views/layouts/maquina"
10
+ directory File.join(engine_views_path, "layouts", "maquina"),
11
+ File.join(app_views_path, "layouts", "maquina")
12
+ end
13
+
14
+ def copy_views
15
+ empty_directory "app/views/maquina"
16
+ directory File.join(engine_views_path, "maquina"),
17
+ File.join(app_views_path, "maquina")
18
+ end
19
+
20
+ private
21
+
22
+ def engine_views_path
23
+ @engine_views_path ||= File.join(Maquina::Engine.root, "app", "views")
24
+ end
25
+
26
+ def app_views_path
27
+ @app_views_path ||= File.join(Rails.root, "app", "views")
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maquina
4
+ class TailwindConfigGenerator < Rails::Generators::Base
5
+ source_root File.expand_path("../templates", __FILE__)
6
+
7
+ def create_tailwind_config_file
8
+ template "app/assets/config/maquina/tailwind.config.js"
9
+ end
10
+ end
11
+ end