flamerb 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +25 -0
- data/README.md +59 -0
- data/bin/flame +26 -0
- data/lib/flame/app_builder.rb +26 -0
- data/lib/flame/generators/app.rb +51 -0
- data/lib/flame/generators/base.rb +28 -0
- data/lib/flame/generators/cors_generator.rb +23 -0
- data/lib/flame/generators/devise_generator.rb +88 -0
- data/lib/flame/generators/haml_generator.rb +9 -0
- data/lib/flame/generators/testing_generator.rb +12 -0
- data/lib/flame/generators/vite_generator.rb +76 -0
- data/lib/flame/version.rb +5 -0
- data/lib/flame.rb +8 -0
- data/templates/Gemfile.erb +39 -0
- data/templates/app/views/layouts/application.html.haml +14 -0
- data/templates/db/seeds.rb +5 -0
- data/templates/eslintrc.js +3 -0
- data/templates/frontend/assets/react.svg +1 -0
- data/templates/frontend/assets/stylesheets/application.sass +8 -0
- data/templates/frontend/common/components/sidebar/index.jsx +43 -0
- data/templates/frontend/common/components/sidebar/sidebar-link.jsx +32 -0
- data/templates/frontend/common/components/sidebar/sidebar.styled.jsx +0 -0
- data/templates/frontend/entrypoints/application.js +28 -0
- data/templates/frontend/entrypoints/application.jsx +27 -0
- data/templates/frontend/layouts/content.jsx +11 -0
- data/templates/frontend/layouts/main-layout.jsx +16 -0
- data/templates/frontend/layouts/page-layout.jsx +28 -0
- data/templates/frontend/pages/home/index.jsx +25 -0
- data/templates/frontend/pages/sign-in/components/login-form/index.jsx +66 -0
- data/templates/frontend/pages/sign-in/components/login-form/login-form.styled.js +14 -0
- data/templates/frontend/pages/sign-in/components/login-form/utils/index.js +11 -0
- data/templates/frontend/pages/sign-in/components/login-form/validation-schema.js +6 -0
- data/templates/frontend/pages/sign-in/index.jsx +22 -0
- data/templates/frontend/router/index.jsx +43 -0
- data/templates/frontend/services/base.js +6 -0
- data/templates/frontend/services/users-service/index.js +21 -0
- data/templates/frontend/store/index.js +8 -0
- data/templates/frontend/store/slices/userSlice.js +42 -0
- data/templates/frontend/theme/index.js +13 -0
- data/templates/jsconfig.json +8 -0
- data/templates/vite.config.js +16 -0
- metadata +129 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 27b827963415a5a78744f0ee9188375a86f7fb12ea2af70b7de692e69d005879
|
4
|
+
data.tar.gz: 2d6fc4655d6fbd865e9f65024eb10c92a12a90b924c5d9617b90424f9595c6dd
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88d0abbb6d5773d5c4c36143e290c2a83ed9d2af9c97d524306fd50a7f9362eb805f7144beb996915b4d2bbdc7c2fbefa91113c4814474480f076aaa293fe8be
|
7
|
+
data.tar.gz: 1ec41342b515ae8727d60be8146d4534c25532d86e901641957ad3baaf31faeb7a370b4319b34b7015d5388e9ebf7b28324b5677516125b4c63e8e65fcdea8c2
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.2
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
## v0.1.1 (2023-07-10)
|
2
|
+
|
3
|
+
### Fix
|
4
|
+
|
5
|
+
- conflicts with templates
|
6
|
+
|
7
|
+
## v0.1.0 (2023-07-10)
|
8
|
+
|
9
|
+
### Feat
|
10
|
+
|
11
|
+
- add frontend template with basic configuration
|
12
|
+
- some changes :p
|
13
|
+
- remove devise-jwt integration
|
14
|
+
- rename all modules
|
15
|
+
- add devise and devise-jwt at the app generator
|
16
|
+
- add pagination gems on the gemfile template
|
17
|
+
- add active_model_serializer to the gemfile.erb
|
18
|
+
- add annotate and rspec on the app generator
|
19
|
+
- add configuration for default generators in the app builder
|
20
|
+
- add gemfile template in app builder
|
21
|
+
- add commitizen configuration
|
22
|
+
|
23
|
+
### Refactor
|
24
|
+
|
25
|
+
- refactor function on app builder on generators
|
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Flame
|
2
|
+
|
3
|
+
Flame is rails app generator inspired in [Suspenders](https://github.com/thoughtbot/suspenders)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
|
10
|
+
$ gem install flame
|
11
|
+
$ flame <app_name>
|
12
|
+
|
13
|
+
## Gemfile
|
14
|
+
|
15
|
+
* [AMS](https://github.com/rails-api/active_model_serializers) for serialize json (api)
|
16
|
+
* [Devise](https://github.com/heartcombo/devise) for user authentication
|
17
|
+
* [Haml](https://github.com/haml/haml) we prefer use haml extension instead classic .erb
|
18
|
+
* [Pager API](https://github.com/IcaliaLabs/pager-api) & [Pagy](https://github.com/ddnexus/pagy) for api pagination
|
19
|
+
* [Vite](https://github.com/ElMassimo/vite_ruby) instead webpack
|
20
|
+
* [Annotate](https://github.com/ctran/annotate_models) generate comments on the model with current schema
|
21
|
+
|
22
|
+
|
23
|
+
for test environment we use:
|
24
|
+
* [FactoryBot](https://github.com/thoughtbot/factory_bot)
|
25
|
+
* [FFaker](https://github.com/ffaker/ffaker)
|
26
|
+
* [RSpec](https://github.com/rspec/rspec-rails)
|
27
|
+
* [Shoulda Matchers](https://github.com/thoughtbot/shoulda-matchers)
|
28
|
+
* [Database Cleanner](https://github.com/DatabaseCleaner/database_cleaner)
|
29
|
+
|
30
|
+
## Package.json
|
31
|
+
* [react](https://yarnpkg.com/package/react) & [react-dom](https://yarnpkg.com/package/react-dom)
|
32
|
+
* [formik](https://yarnpkg.com/package/formik) & [yup](https://yarnpkg.com/package/yup) for handle and validate forms.
|
33
|
+
* [axios](https://yarnpkg.com/package/axios) for http request
|
34
|
+
* [@reduxjs/toolkit](https://yarnpkg.com/package/@reduxjs/toolkit)
|
35
|
+
* [react-router-dom](https://yarnpkg.com/package/react-router-dom) for routing
|
36
|
+
* [@mui/material](https://yarnpkg.com/package/@mui/material) library for components
|
37
|
+
* [@mui/icons-material](https://yarnpkg.com/package/@mui/icons-material) library for icons
|
38
|
+
* [react-toastify](https://yarnpkg.com/package/react-toastify) simple and beauty notifcations.
|
39
|
+
* [sass](https://yarnpkg.com/package/sass)
|
40
|
+
|
41
|
+
for dev dependencies
|
42
|
+
* standard
|
43
|
+
* @vitejs/plugin-react-swc
|
44
|
+
* eslint-plugin-react
|
45
|
+
|
46
|
+
|
47
|
+
## Style Guide
|
48
|
+
|
49
|
+
Projects created with Flame come with [Standard](https://github.com/standardrb/standard)
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/Flame.
|
54
|
+
|
55
|
+
|
56
|
+
## License
|
57
|
+
|
58
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
59
|
+
|
data/bin/flame
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
source_path = (Pathname.new(__FILE__).dirname + '../lib').expand_path
|
5
|
+
$LOAD_PATH << source_path
|
6
|
+
|
7
|
+
require 'flame'
|
8
|
+
|
9
|
+
if ARGV.empty?
|
10
|
+
puts "Please provide a path for the new application"
|
11
|
+
puts
|
12
|
+
puts "See --help for more info"
|
13
|
+
exit 0
|
14
|
+
elsif ["-v", "--version"].include? ARGV[0]
|
15
|
+
puts Suspenders::VERSION
|
16
|
+
exit 0
|
17
|
+
end
|
18
|
+
|
19
|
+
ARGV << "--skip-javascript"
|
20
|
+
ARGV << "--skip-jbuilder"
|
21
|
+
ARGV << "--database=postgresql"
|
22
|
+
ARGV << "-T"
|
23
|
+
|
24
|
+
templates_path = File.expand_path(File.join("..", "templates"), File.dirname(__FILE__))
|
25
|
+
Flame::Generators::App.source_paths << Rails::Generators::AppGenerator.source_root << templates_path
|
26
|
+
Flame::Generators::App.start
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Flame
|
2
|
+
class AppBuilder < Rails::AppBuilder
|
3
|
+
def gemfile
|
4
|
+
template "Gemfile.erb", "Gemfile"
|
5
|
+
end
|
6
|
+
|
7
|
+
def configure_generators
|
8
|
+
config = <<-RUBY
|
9
|
+
config.generators do |generate|
|
10
|
+
generate.helper false
|
11
|
+
generate.javascripts false
|
12
|
+
generate.controller_specs false
|
13
|
+
generate.request_specs true
|
14
|
+
generate.routing_specs false
|
15
|
+
generate.stylesheets false
|
16
|
+
generate.test_framework :rspec
|
17
|
+
generate.view_specs false
|
18
|
+
generate.template_engine :haml
|
19
|
+
end
|
20
|
+
|
21
|
+
RUBY
|
22
|
+
|
23
|
+
inject_into_class "config/application.rb", "Application", config
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require "rails/generators/rails/app/app_generator"
|
3
|
+
|
4
|
+
module Flame
|
5
|
+
module Generators
|
6
|
+
class App < Rails::Generators::AppGenerator
|
7
|
+
hide!
|
8
|
+
def finish_template
|
9
|
+
invoke :custom_template
|
10
|
+
invoke :generators
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
def custom_template
|
15
|
+
build :configure_generators
|
16
|
+
end
|
17
|
+
|
18
|
+
def generators
|
19
|
+
run("spring stop > /dev/null 2>&1 || true")
|
20
|
+
run("bundle install")
|
21
|
+
invoke "flame:haml"
|
22
|
+
rails_command "db:create"
|
23
|
+
|
24
|
+
invoke "flame:testing"
|
25
|
+
invoke "flame:cors"
|
26
|
+
invoke "flame:devise"
|
27
|
+
invoke "flame:vite"
|
28
|
+
|
29
|
+
generate("annotate:install")
|
30
|
+
run("bundle exec standardrb --fix-unsafely")
|
31
|
+
run("bundle exec haml-lint app/views -A -a")
|
32
|
+
rails_command("db:migrate") if yes?("\nDo you want to run migrations? [y/n]")
|
33
|
+
rails_command("db:seed") if yes?("\nDo you want to run seed? [y/n]")
|
34
|
+
welcome_message
|
35
|
+
|
36
|
+
exit 0
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def welcome_message
|
42
|
+
say "Flame app successfully created!", :green
|
43
|
+
say "Run `foreman start -f Procfile.dev` to start the server", :green
|
44
|
+
end
|
45
|
+
|
46
|
+
def get_builder_class
|
47
|
+
Flame::AppBuilder
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
require "rails/generators/base"
|
3
|
+
|
4
|
+
module Flame
|
5
|
+
module Generators
|
6
|
+
class Base < Rails::Generators::Base
|
7
|
+
source_root File.expand_path("../../../templates", __dir__)
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# @param [Array] packages
|
12
|
+
# @return [void]
|
13
|
+
# @example
|
14
|
+
# yarn_install(["vite", "react", "react-dom"])
|
15
|
+
def yarn_install(packages)
|
16
|
+
run("yarn add #{packages.join(" ")} --silent")
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param [Array] packages
|
20
|
+
# @return [void]
|
21
|
+
# @example
|
22
|
+
# yarn_install_dev(["vite", "react", "react-dom"])
|
23
|
+
def yarn_install_dev(packages)
|
24
|
+
run("yarn add -D #{packages.join(" ")} --silent")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module Flame
|
4
|
+
class CorsGenerator < Generators::Base
|
5
|
+
CONFIG = <<~RUBY
|
6
|
+
Rails.application.config.middleware.insert_before 0, Rack::Cors do
|
7
|
+
allow do
|
8
|
+
origins Rails.env.development? ? ["localhost:5100", "127.0.0.1:5100"] : ENV["FRONTEND_URL"]
|
9
|
+
resource "*",
|
10
|
+
headers: %w[Authorization],
|
11
|
+
methods: :any,
|
12
|
+
expose: %w[Authorization],
|
13
|
+
max_age: 600,
|
14
|
+
credentials: true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
RUBY
|
18
|
+
|
19
|
+
def create_cors_file
|
20
|
+
create_file("config/initializers/cors.rb", CONFIG)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module Flame
|
4
|
+
class DeviseGenerator < Generators::Base
|
5
|
+
APP_CONTROLLER = <<~RUBY
|
6
|
+
before_action :authenticate_user!, only: [:current]
|
7
|
+
protect_from_forgery with: :exception, unless: :json_request?
|
8
|
+
|
9
|
+
def current
|
10
|
+
render json: current_user
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def json_request?
|
17
|
+
request.format.json?
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
|
21
|
+
SESSION_CONTROLLER = <<~RUBY
|
22
|
+
class SessionsController < Devise::SessionsController
|
23
|
+
respond_to :json
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def respond_with(resource, _opts = {})
|
28
|
+
render json: resource
|
29
|
+
end
|
30
|
+
|
31
|
+
def respond_to_on_destroy
|
32
|
+
head :no_content
|
33
|
+
end
|
34
|
+
end
|
35
|
+
RUBY
|
36
|
+
|
37
|
+
def install
|
38
|
+
generate("devise:install")
|
39
|
+
generate("devise", "User")
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_timeoutable
|
43
|
+
gsub_file(
|
44
|
+
"app/models/user.rb",
|
45
|
+
/^\s*devise\s*:[a-z_]+(?:,\s*:[a-z_]+)*\s*$/,
|
46
|
+
" devise :database_authenticatable, :registerable, :timeoutable, timeout_in: 1.day"
|
47
|
+
)
|
48
|
+
end
|
49
|
+
|
50
|
+
def generate_session_controller
|
51
|
+
create_file(
|
52
|
+
"app/controllers/sessions_controller.rb",
|
53
|
+
SESSION_CONTROLLER
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
def modify_session_route
|
58
|
+
gsub_file(
|
59
|
+
"config/routes.rb",
|
60
|
+
/devise_for\s*:\s*users/,
|
61
|
+
<<~RUBY
|
62
|
+
devise_for :users, defaults: {format: :json}, controllers: {sessions: "sessions"}
|
63
|
+
get "/users/current", to: "application#current", defaults: {format: :json}
|
64
|
+
|
65
|
+
get "*path", to: "pages#index", constraints: ->(request) do
|
66
|
+
!request.xhr? && request.format.html?
|
67
|
+
end
|
68
|
+
RUBY
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
72
|
+
def modify_app_controller
|
73
|
+
inject_into_class(
|
74
|
+
"app/controllers/application_controller.rb",
|
75
|
+
"ApplicationController",
|
76
|
+
APP_CONTROLLER
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
def insert_secret_key
|
81
|
+
inject_into_file(
|
82
|
+
"config/initializers/devise.rb",
|
83
|
+
" config.secret_key = Rails.application.credentials.secret_key_base\n",
|
84
|
+
after: "Devise.setup do |config|\n"
|
85
|
+
)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
module Flame
|
4
|
+
class ViteGenerator < Generators::Base
|
5
|
+
source_root File.expand_path("../../../templates", __dir__)
|
6
|
+
|
7
|
+
def install
|
8
|
+
run("rm -rf ./package.lock")
|
9
|
+
run("yarn init -y")
|
10
|
+
|
11
|
+
run("bundle exec vite install")
|
12
|
+
|
13
|
+
run("rm -rf ./package-lock.json")
|
14
|
+
run("rm -rf ./yarn.lock")
|
15
|
+
run("rm -rf ./node_modules")
|
16
|
+
end
|
17
|
+
|
18
|
+
def install_packages
|
19
|
+
packages = %w[
|
20
|
+
react
|
21
|
+
react-dom
|
22
|
+
formik
|
23
|
+
yup
|
24
|
+
axios
|
25
|
+
@reduxjs/toolkit
|
26
|
+
react-redux
|
27
|
+
react-router-dom
|
28
|
+
@mui/material
|
29
|
+
@mui/icons-material
|
30
|
+
@emotion/react
|
31
|
+
@emotion/styled
|
32
|
+
react-toastify
|
33
|
+
styled-components
|
34
|
+
sass
|
35
|
+
]
|
36
|
+
yarn_install(packages)
|
37
|
+
end
|
38
|
+
|
39
|
+
def install_dev_packages
|
40
|
+
packages = %w[
|
41
|
+
standard
|
42
|
+
@vitejs/plugin-react-swc
|
43
|
+
eslint-plugin-react
|
44
|
+
]
|
45
|
+
|
46
|
+
yarn_install_dev(packages)
|
47
|
+
end
|
48
|
+
|
49
|
+
def copy_templates
|
50
|
+
remove_file "vite.config.js"
|
51
|
+
remove_file "vite.config.ts"
|
52
|
+
template("vite.config.js", "vite.config.js")
|
53
|
+
template("jsconfig.json", "jsconfig.json")
|
54
|
+
run("rm -rf app/frontend")
|
55
|
+
run("rm -rf db/seeds.rb")
|
56
|
+
run("rm app/views/layouts/application.html.haml")
|
57
|
+
directory("frontend", "app/frontend")
|
58
|
+
template("app/views/layouts/application.html.haml", "app/views/layouts/application.html.haml")
|
59
|
+
template("db/seeds.rb", "db/seeds.rb")
|
60
|
+
end
|
61
|
+
|
62
|
+
def install_standardjs
|
63
|
+
template("eslintrc.js", ".eslintrc.js")
|
64
|
+
end
|
65
|
+
|
66
|
+
def generate_home
|
67
|
+
generate("controller", "pages", "index", "--skip-routes", "--no-test-framework")
|
68
|
+
run("echo '' > app/views/pages/index.html.haml")
|
69
|
+
append_to_file("app/views/pages/index.html.haml", "#root\n")
|
70
|
+
end
|
71
|
+
|
72
|
+
def generate_root_route
|
73
|
+
route("root to: 'pages#index'")
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/lib/flame.rb
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
require "flame/version"
|
2
|
+
require "flame/generators/cors_generator"
|
3
|
+
require "flame/generators/testing_generator"
|
4
|
+
require "flame/generators/devise_generator"
|
5
|
+
require "flame/generators/vite_generator"
|
6
|
+
require "flame/generators/haml_generator"
|
7
|
+
require "flame/generators/app"
|
8
|
+
require "flame/app_builder"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
3
|
+
|
4
|
+
ruby "<%= Flame::RUBY_VERSION %>"
|
5
|
+
|
6
|
+
gem "active_model_serializers", "~> 0.9.9"
|
7
|
+
gem "bootsnap", require: false
|
8
|
+
gem "devise"
|
9
|
+
gem "haml-rails"
|
10
|
+
gem "pager_api"
|
11
|
+
gem "pagy"
|
12
|
+
gem "pg"
|
13
|
+
gem "puma"
|
14
|
+
gem "rails", "<%= Flame::RAILS_VERSION %>"
|
15
|
+
gem "rack-cors"
|
16
|
+
gem "vite_rails"
|
17
|
+
|
18
|
+
gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby]
|
19
|
+
|
20
|
+
group :development do
|
21
|
+
gem "annotate"
|
22
|
+
gem "listen"
|
23
|
+
gem "spring"
|
24
|
+
gem "standard"
|
25
|
+
gem "html2haml" # Remove this gem!
|
26
|
+
gem "haml_lint", require: false
|
27
|
+
end
|
28
|
+
|
29
|
+
group :development, :test do
|
30
|
+
gem "byebug", platforms: %i[mri mingw x64_mingw]
|
31
|
+
gem "factory_bot_rails", "~> 6.2"
|
32
|
+
gem "ffaker", "~> 2.21"
|
33
|
+
gem "rspec-rails", "~> 6.0.0"
|
34
|
+
gem "shoulda-matchers", "~> 5.0"
|
35
|
+
end
|
36
|
+
|
37
|
+
group :test do
|
38
|
+
gem "database_cleaner-active_record", "2.1"
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
!!!
|
2
|
+
%html
|
3
|
+
%head
|
4
|
+
%meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
|
5
|
+
%title TestLast
|
6
|
+
%meta{:content => "width=device-width,initial-scale=1", :name => "viewport"}/
|
7
|
+
= csrf_meta_tags
|
8
|
+
= csp_meta_tag
|
9
|
+
= stylesheet_link_tag 'application', media: 'all'
|
10
|
+
= vite_client_tag
|
11
|
+
= vite_react_refresh_tag
|
12
|
+
= vite_javascript_tag 'application.jsx'
|
13
|
+
%body
|
14
|
+
= yield
|
@@ -0,0 +1 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { List, ListSubheader } from '@mui/material/'
|
2
|
+
|
3
|
+
import { Home as HomeIcon } from '@mui/icons-material/'
|
4
|
+
import { styled } from '@mui/system'
|
5
|
+
import { SidebarLink } from './sidebar-link'
|
6
|
+
|
7
|
+
const Sidebar = () => {
|
8
|
+
const SidebarContainer = styled('nav')({
|
9
|
+
display: 'flex',
|
10
|
+
padding: 10,
|
11
|
+
pr: 0,
|
12
|
+
flex: 1
|
13
|
+
})
|
14
|
+
|
15
|
+
const SidebarSubHeader = styled(ListSubheader)(({ theme }) => ({
|
16
|
+
fontSize: 18,
|
17
|
+
fontWeight: 'bold',
|
18
|
+
pl: 0,
|
19
|
+
backgroundColor: theme.palette.background.default
|
20
|
+
}))
|
21
|
+
|
22
|
+
return (
|
23
|
+
<SidebarContainer>
|
24
|
+
<List
|
25
|
+
sx={{
|
26
|
+
width: '100%',
|
27
|
+
maxWidth: '100%',
|
28
|
+
fontSize: '1.5rem'
|
29
|
+
}}
|
30
|
+
component='nav'
|
31
|
+
subheader={
|
32
|
+
<SidebarSubHeader>
|
33
|
+
General
|
34
|
+
</SidebarSubHeader>
|
35
|
+
}
|
36
|
+
>
|
37
|
+
<SidebarLink to='/' label='Home' icon={<HomeIcon />} />
|
38
|
+
|
39
|
+
</List>
|
40
|
+
</SidebarContainer>
|
41
|
+
)
|
42
|
+
}
|
43
|
+
export default Sidebar
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { ListItemText, ListItemButton, ListItemIcon } from '@mui/material'
|
2
|
+
import PropTypes from 'prop-types'
|
3
|
+
import { Link } from 'react-router-dom'
|
4
|
+
|
5
|
+
export const SidebarLink = ({ label, icon, route }) => {
|
6
|
+
return (
|
7
|
+
<ListItemButton
|
8
|
+
component={Link}
|
9
|
+
to={route}
|
10
|
+
sx={{ py: 0, px: 1 }}
|
11
|
+
>
|
12
|
+
<ListItemIcon
|
13
|
+
sx={{
|
14
|
+
minWidth: 30
|
15
|
+
}}
|
16
|
+
>
|
17
|
+
{icon}
|
18
|
+
</ListItemIcon>
|
19
|
+
<ListItemText
|
20
|
+
primaryTypographyProps={{ fontSize: 14, fontWeight: 'medium' }}
|
21
|
+
primary={label}
|
22
|
+
/>
|
23
|
+
</ListItemButton>
|
24
|
+
|
25
|
+
)
|
26
|
+
}
|
27
|
+
|
28
|
+
SidebarLink.propTypes = {
|
29
|
+
label: PropTypes.string,
|
30
|
+
icon: PropTypes.node,
|
31
|
+
to: PropTypes.string
|
32
|
+
}
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
// To see this message, add the following to the `<head>` section in your
|
2
|
+
// views/layouts/application.html.erb
|
3
|
+
//
|
4
|
+
// <%= vite_client_tag %>
|
5
|
+
// <%= vite_javascript_tag 'application' %>
|
6
|
+
console.log('Vite ⚡️ Rails')
|
7
|
+
|
8
|
+
// If using a TypeScript entrypoint file:
|
9
|
+
// <%= vite_typescript_tag 'application' %>
|
10
|
+
//
|
11
|
+
// If you want to use .jsx or .tsx, add the extension:
|
12
|
+
// <%= vite_javascript_tag 'application.jsx' %>
|
13
|
+
|
14
|
+
console.log('Visit the guide for more information: ', 'https://vite-ruby.netlify.app/guide/rails')
|
15
|
+
|
16
|
+
// Example: Load Rails libraries in Vite.
|
17
|
+
//
|
18
|
+
// import * as Turbo from '@hotwired/turbo'
|
19
|
+
// Turbo.start()
|
20
|
+
//
|
21
|
+
// import ActiveStorage from '@rails/activestorage'
|
22
|
+
// ActiveStorage.start()
|
23
|
+
//
|
24
|
+
// // Import all channels.
|
25
|
+
// const channels = import.meta.globEager('./**/*_channel.js')
|
26
|
+
|
27
|
+
// Example: Import a stylesheet in app/frontend/index.css
|
28
|
+
// import '~/index.css'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import '@/assets/stylesheets/application.sass'
|
2
|
+
import 'react-toastify/dist/ReactToastify.css'
|
3
|
+
|
4
|
+
import React from 'react'
|
5
|
+
import { ToastContainer } from 'react-toastify'
|
6
|
+
import { CssBaseline, ThemeProvider } from '@mui/material'
|
7
|
+
import { createRoot } from 'react-dom/client'
|
8
|
+
import { RouterProvider } from 'react-router-dom'
|
9
|
+
import router from '@/router'
|
10
|
+
import { Provider } from 'react-redux'
|
11
|
+
import { store } from '@/store'
|
12
|
+
import { theme } from '@/theme'
|
13
|
+
|
14
|
+
const container = document.getElementById('root')
|
15
|
+
const root = createRoot(container)
|
16
|
+
|
17
|
+
root.render(
|
18
|
+
<React.StrictMode>
|
19
|
+
<CssBaseline />
|
20
|
+
<ToastContainer />
|
21
|
+
<Provider store={store}>
|
22
|
+
<ThemeProvider theme={theme}>
|
23
|
+
<RouterProvider router={router} />
|
24
|
+
</ThemeProvider>
|
25
|
+
</Provider>
|
26
|
+
</React.StrictMode>
|
27
|
+
)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Stack } from '@mui/material'
|
2
|
+
import Content from './content'
|
3
|
+
import Sidebar from '@/common/components/sidebar'
|
4
|
+
|
5
|
+
const MainLayout = ({ children }) => {
|
6
|
+
return (
|
7
|
+
<Stack sx={{ width: '100%', height: '100%' }} direction='row' justifyContent='flex-start' gap={1}>
|
8
|
+
<Sidebar />
|
9
|
+
<Content>
|
10
|
+
{children}
|
11
|
+
</Content>
|
12
|
+
</Stack>
|
13
|
+
)
|
14
|
+
}
|
15
|
+
|
16
|
+
export default MainLayout
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import { Box, Divider, Stack, Typography } from '@mui/material'
|
2
|
+
import PropTypes from 'prop-types'
|
3
|
+
|
4
|
+
const PageLayout = ({ title, children }) => {
|
5
|
+
return (
|
6
|
+
<Stack>
|
7
|
+
<Box sx={{mb:2}}>
|
8
|
+
<Typography gutterBottom variant='h5' sx={{ fontWeight: 'bold' }}>{title}</Typography>
|
9
|
+
<Divider />
|
10
|
+
</Box>
|
11
|
+
|
12
|
+
<div>
|
13
|
+
{children}
|
14
|
+
</div>
|
15
|
+
</Stack>
|
16
|
+
)
|
17
|
+
}
|
18
|
+
|
19
|
+
PageLayout.propTypes = {
|
20
|
+
title: PropTypes.string,
|
21
|
+
children: PropTypes.node
|
22
|
+
}
|
23
|
+
|
24
|
+
PageLayout.defaultProps = {
|
25
|
+
title: 'Custom'
|
26
|
+
}
|
27
|
+
|
28
|
+
export default PageLayout
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { Button, Typography } from '@mui/material'
|
2
|
+
import { useNavigate } from 'react-router-dom'
|
3
|
+
import { usersService } from '@/services/users-service'
|
4
|
+
import PageLayout from '@/layouts/page-layout'
|
5
|
+
|
6
|
+
const Home = () => {
|
7
|
+
const navigate = useNavigate()
|
8
|
+
const handleLogout = async () => {
|
9
|
+
try {
|
10
|
+
await usersService.signOut()
|
11
|
+
navigate('/sign_in')
|
12
|
+
} catch (e) {
|
13
|
+
/* handle error */
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
return (
|
18
|
+
<PageLayout>
|
19
|
+
<Typography variant='h4'>Home</Typography>
|
20
|
+
<Button variant='contained' onClick={() => handleLogout()}>Log out</Button>
|
21
|
+
</PageLayout>
|
22
|
+
)
|
23
|
+
}
|
24
|
+
|
25
|
+
export default Home
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { Button, TextField, Typography } from '@mui/material'
|
2
|
+
import { CardLogin, Form } from './login-form.styled'
|
3
|
+
import { useFormik } from 'formik'
|
4
|
+
import { usersService } from '@/services/users-service'
|
5
|
+
import validationSchema from './validation-schema'
|
6
|
+
import { toast } from 'react-toastify'
|
7
|
+
import { useNavigate } from 'react-router-dom'
|
8
|
+
|
9
|
+
const LoginForm = () => {
|
10
|
+
const navigate = useNavigate()
|
11
|
+
const handleLogin = async (values) => {
|
12
|
+
try {
|
13
|
+
await usersService.signIn({ user: values })
|
14
|
+
navigate('/')
|
15
|
+
} catch ({ response }) {
|
16
|
+
toast.error(response.data.error)
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
const { touched, errors, handleBlur, handleSubmit, handleChange, values } = useFormik({
|
21
|
+
initialValues: { email: 'admin@example.com', password: 'admin123' },
|
22
|
+
validationSchema,
|
23
|
+
onSubmit: handleLogin
|
24
|
+
})
|
25
|
+
|
26
|
+
return (
|
27
|
+
<CardLogin>
|
28
|
+
<Form onSubmit={handleSubmit}>
|
29
|
+
<Typography variant='h5' align='center'>
|
30
|
+
Sign in to your account
|
31
|
+
</Typography>
|
32
|
+
<TextField
|
33
|
+
fullWidth
|
34
|
+
name='email'
|
35
|
+
placeholder='john.doe@example.com'
|
36
|
+
onChange={handleChange}
|
37
|
+
value={values.email}
|
38
|
+
error={touched.email && Boolean(errors.email)}
|
39
|
+
onBlur={handleBlur}
|
40
|
+
/>
|
41
|
+
|
42
|
+
<TextField
|
43
|
+
fullWidth
|
44
|
+
name='password'
|
45
|
+
type='password'
|
46
|
+
placeholder='********'
|
47
|
+
onChange={handleChange}
|
48
|
+
value={values.password}
|
49
|
+
error={touched.email && Boolean(errors.email)}
|
50
|
+
onBlur={handleBlur}
|
51
|
+
/>
|
52
|
+
<Button
|
53
|
+
type='submit'
|
54
|
+
variant='contained'
|
55
|
+
>
|
56
|
+
Sign in
|
57
|
+
</Button>
|
58
|
+
<Typography variant='subtitle2' align='center'>
|
59
|
+
Forgot your password?
|
60
|
+
</Typography>
|
61
|
+
</Form>
|
62
|
+
</CardLogin>
|
63
|
+
)
|
64
|
+
}
|
65
|
+
|
66
|
+
export default LoginForm
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { styled } from '@mui/system'
|
2
|
+
import { Card } from '@mui/material'
|
3
|
+
|
4
|
+
export const CardLogin = styled(Card)({
|
5
|
+
width: '100%',
|
6
|
+
maxWidth: '31.25rem',
|
7
|
+
padding: '2rem'
|
8
|
+
})
|
9
|
+
|
10
|
+
export const Form = styled('form')({
|
11
|
+
display: 'flex',
|
12
|
+
flexDirection: 'column',
|
13
|
+
gap: '1rem'
|
14
|
+
})
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import usersService from '@/services/users-service'
|
2
|
+
/**
|
3
|
+
* Handle login request for login-form
|
4
|
+
* @param {object} params
|
5
|
+
* @param {string} params.email - user email
|
6
|
+
* @param {string} params.password - user password
|
7
|
+
* @returns {void}
|
8
|
+
*/
|
9
|
+
export const handleLogin = async (params) => {
|
10
|
+
const response = await usersService.login(params)
|
11
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import { styled } from '@mui/system'
|
2
|
+
import LoginForm from './components/login-form'
|
3
|
+
|
4
|
+
const SignIn = () => {
|
5
|
+
const LayoutLogin = styled('div')({
|
6
|
+
width: '100%',
|
7
|
+
height: '100%',
|
8
|
+
maxWidth: '31.25rem',
|
9
|
+
padding: '1rem',
|
10
|
+
margin: '0 auto',
|
11
|
+
display: 'flex',
|
12
|
+
alignItems: 'center'
|
13
|
+
})
|
14
|
+
|
15
|
+
return (
|
16
|
+
<LayoutLogin>
|
17
|
+
<LoginForm />
|
18
|
+
</LayoutLogin>
|
19
|
+
)
|
20
|
+
}
|
21
|
+
|
22
|
+
export default SignIn
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import Home from '@/pages/home'
|
2
|
+
import SignIn from '@/pages/sign-in'
|
3
|
+
import { Navigate, Outlet, createBrowserRouter } from 'react-router-dom'
|
4
|
+
import { useSelector } from 'react-redux'
|
5
|
+
import { validateCurrentUser } from '@/store/slices/userSlice'
|
6
|
+
import { store } from '@/store'
|
7
|
+
import MainLayout from '@/layouts/main-layout'
|
8
|
+
|
9
|
+
const PrivateRoute = () => {
|
10
|
+
const user = useSelector(state => state.user)
|
11
|
+
console.log(user)
|
12
|
+
return (
|
13
|
+
user.isLogged ? <MainLayout><Outlet /></MainLayout> : <Navigate to='/sign_in' />
|
14
|
+
)
|
15
|
+
}
|
16
|
+
|
17
|
+
const router = createBrowserRouter([
|
18
|
+
{
|
19
|
+
element: <PrivateRoute />,
|
20
|
+
loader: () => {
|
21
|
+
return store.dispatch(validateCurrentUser())
|
22
|
+
},
|
23
|
+
children: [
|
24
|
+
{
|
25
|
+
path: '/',
|
26
|
+
element: <Home />,
|
27
|
+
exact: true
|
28
|
+
},
|
29
|
+
{
|
30
|
+
path: '/home',
|
31
|
+
element: <Home />,
|
32
|
+
exact: true
|
33
|
+
}
|
34
|
+
]
|
35
|
+
},
|
36
|
+
{
|
37
|
+
path: '/sign_in',
|
38
|
+
element: <SignIn />
|
39
|
+
|
40
|
+
}
|
41
|
+
])
|
42
|
+
|
43
|
+
export default router
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import api from '@/services/base'
|
2
|
+
|
3
|
+
export const usersService = {
|
4
|
+
/**
|
5
|
+
* Sign in request
|
6
|
+
* @param {object} params
|
7
|
+
* @param {string} params.user.email - user email
|
8
|
+
* @param {string} params.user.password - user password
|
9
|
+
* @returns {Promise<object>} - response
|
10
|
+
* @example
|
11
|
+
* const response = await usersService.signIn({
|
12
|
+
* user: {
|
13
|
+
* email: 'admin@example.com',
|
14
|
+
* password: 'password'
|
15
|
+
* }
|
16
|
+
* })
|
17
|
+
*/
|
18
|
+
signIn: (params) => api.post('/users/sign_in', params),
|
19
|
+
currentUser: () => api.get('/users/current'),
|
20
|
+
signOut: () => api.delete('/users/sign_out')
|
21
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
|
2
|
+
import { usersService } from '@/services/users-service'
|
3
|
+
import { toast } from 'react-toastify'
|
4
|
+
|
5
|
+
const validateCurrentUser = createAsyncThunk(
|
6
|
+
'user/current-user',
|
7
|
+
async (_, { rejectWithValue }) => {
|
8
|
+
try {
|
9
|
+
const response = await usersService.currentUser()
|
10
|
+
return response
|
11
|
+
} catch ({ response }) {
|
12
|
+
throw rejectWithValue(response.data)
|
13
|
+
}
|
14
|
+
}
|
15
|
+
)
|
16
|
+
|
17
|
+
const initialState = {
|
18
|
+
isLogged: false
|
19
|
+
}
|
20
|
+
|
21
|
+
export const userSlice = createSlice({
|
22
|
+
name: 'user',
|
23
|
+
initialState,
|
24
|
+
reducers: {},
|
25
|
+
extraReducers: (builder) => {
|
26
|
+
builder.addCase(validateCurrentUser.fulfilled, (state, action) => {
|
27
|
+
state.isLogged = true
|
28
|
+
})
|
29
|
+
|
30
|
+
builder.addCase(validateCurrentUser.rejected, (state, action) => {
|
31
|
+
state.isLogged = false
|
32
|
+
toast.error(action.payload.error)
|
33
|
+
})
|
34
|
+
}
|
35
|
+
})
|
36
|
+
|
37
|
+
// export const { increment, decrement, incrementByAmount } = userSlice.actions
|
38
|
+
|
39
|
+
export {
|
40
|
+
validateCurrentUser
|
41
|
+
}
|
42
|
+
export default userSlice.reducer
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { defineConfig } from 'vite'
|
2
|
+
import path from 'path'
|
3
|
+
import RubyPlugin from 'vite-plugin-ruby'
|
4
|
+
import react from '@vitejs/plugin-react-swc'
|
5
|
+
|
6
|
+
export default defineConfig({
|
7
|
+
plugins: [
|
8
|
+
RubyPlugin(),
|
9
|
+
react()
|
10
|
+
],
|
11
|
+
resolve: {
|
12
|
+
alias: [
|
13
|
+
{ find: '@', replacement: path.resolve(__dirname, 'app/frontend') }
|
14
|
+
]
|
15
|
+
}
|
16
|
+
})
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flamerb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- n0tbot
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-07-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 6.1.7
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 6.1.7
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.12'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.12'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: standard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.29'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.29'
|
55
|
+
description: Flame is a powerful Ruby gem designed to simplify and streamline application
|
56
|
+
development by providing a comprehensive set of tools and functionalities.
|
57
|
+
email:
|
58
|
+
- wilber.garcia@outlook.es
|
59
|
+
executables:
|
60
|
+
- flame
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- ".ruby-version"
|
65
|
+
- CHANGELOG.md
|
66
|
+
- README.md
|
67
|
+
- bin/flame
|
68
|
+
- lib/flame.rb
|
69
|
+
- lib/flame/app_builder.rb
|
70
|
+
- lib/flame/generators/app.rb
|
71
|
+
- lib/flame/generators/base.rb
|
72
|
+
- lib/flame/generators/cors_generator.rb
|
73
|
+
- lib/flame/generators/devise_generator.rb
|
74
|
+
- lib/flame/generators/haml_generator.rb
|
75
|
+
- lib/flame/generators/testing_generator.rb
|
76
|
+
- lib/flame/generators/vite_generator.rb
|
77
|
+
- lib/flame/version.rb
|
78
|
+
- templates/Gemfile.erb
|
79
|
+
- templates/app/views/layouts/application.html.haml
|
80
|
+
- templates/db/seeds.rb
|
81
|
+
- templates/eslintrc.js
|
82
|
+
- templates/frontend/assets/react.svg
|
83
|
+
- templates/frontend/assets/stylesheets/application.sass
|
84
|
+
- templates/frontend/common/components/sidebar/index.jsx
|
85
|
+
- templates/frontend/common/components/sidebar/sidebar-link.jsx
|
86
|
+
- templates/frontend/common/components/sidebar/sidebar.styled.jsx
|
87
|
+
- templates/frontend/entrypoints/application.js
|
88
|
+
- templates/frontend/entrypoints/application.jsx
|
89
|
+
- templates/frontend/layouts/content.jsx
|
90
|
+
- templates/frontend/layouts/main-layout.jsx
|
91
|
+
- templates/frontend/layouts/page-layout.jsx
|
92
|
+
- templates/frontend/pages/home/index.jsx
|
93
|
+
- templates/frontend/pages/sign-in/components/login-form/index.jsx
|
94
|
+
- templates/frontend/pages/sign-in/components/login-form/login-form.styled.js
|
95
|
+
- templates/frontend/pages/sign-in/components/login-form/utils/index.js
|
96
|
+
- templates/frontend/pages/sign-in/components/login-form/validation-schema.js
|
97
|
+
- templates/frontend/pages/sign-in/index.jsx
|
98
|
+
- templates/frontend/router/index.jsx
|
99
|
+
- templates/frontend/services/base.js
|
100
|
+
- templates/frontend/services/users-service/index.js
|
101
|
+
- templates/frontend/store/index.js
|
102
|
+
- templates/frontend/store/slices/userSlice.js
|
103
|
+
- templates/frontend/theme/index.js
|
104
|
+
- templates/jsconfig.json
|
105
|
+
- templates/vite.config.js
|
106
|
+
homepage: https://github.com/notb0t/flame
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
metadata: {}
|
110
|
+
post_install_message:
|
111
|
+
rdoc_options: []
|
112
|
+
require_paths:
|
113
|
+
- lib
|
114
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 3.2.2
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
requirements: []
|
125
|
+
rubygems_version: 3.4.10
|
126
|
+
signing_key:
|
127
|
+
specification_version: 4
|
128
|
+
summary: Generate a Rails app with best practices
|
129
|
+
test_files: []
|