vite_react 0.1.5 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/generators/v0/component_generator.rb +33 -0
- data/lib/generators/v0/install_generator.rb +0 -0
- data/lib/generators/vite_react/devise/devise.rb +16 -0
- data/lib/generators/vite_react/migration/migration.rb +3 -6
- data/lib/generators/vite_react/model_validation/model_validation_generator.rb +6 -6
- data/lib/generators/vite_react/scaffold/scaffold_generator.rb +69 -36
- data/lib/generators/vite_react/scaffold/templates/_form.html.erb.tt +43 -0
- data/lib/generators/vite_react/scaffold/templates/edit.html.erb.tt +12 -0
- data/lib/generators/vite_react/scaffold/templates/index.html.erb.tt +31 -0
- data/lib/generators/vite_react/scaffold/templates/new.html.erb.tt +11 -0
- data/lib/generators/vite_react/scaffold/templates/partial.html.erb.tt +16 -0
- data/lib/generators/vite_react/scaffold/templates/show.html.erb.tt +20 -0
- data/lib/generators/vite_react/stripe/stripe.rb +10 -0
- data/lib/install/App.tsx +3 -3
- data/lib/install/AppSSR.tsx +41 -0
- data/lib/install/Procfile.dev +6 -0
- data/lib/install/application.css +89 -60
- data/lib/install/application.jsx +15 -0
- data/lib/install/index.html.erb +1 -1
- data/lib/install/opentelemetry.rb.tt +10 -0
- data/lib/install/postcss.config.mjs +5 -0
- data/lib/install/ssr.ts +70 -0
- data/lib/install/tailwind.config.js +46 -46
- data/lib/install/tsconfig.app.json +1 -1
- data/lib/install/tsconfig.node.json +5 -1
- data/lib/install/{vite.config.js → vite.config.ts} +8 -0
- data/lib/install/vite_react.rb +55 -56
- data/lib/tasks/install.rake +0 -5
- data/lib/vite_react/configuration.rb +15 -0
- data/lib/vite_react/engine.rb +16 -0
- data/lib/vite_react/node_manager.rb +39 -0
- data/lib/vite_react/railtie.rb +112 -10
- data/lib/vite_react/version.rb +1 -1
- data/lib/vite_react.rb +9 -0
- metadata +23 -4
- /data/lib/{install/eslint.config.js → generators/devise/tailwind/tailwind_generator.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb04f854f6839acaa9de158b73ccbdb5924fe14009687b43c5d27556a8142319
|
4
|
+
data.tar.gz: ae2ce2d0ead50310a6429032f1fc0afcd848ab9006cf0c8cd62ab863b4b987d1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4912549c4a0b02cdab556be873759d95a4feb395ec928b92b27de3038b29dafc542a59627b315d35d336f66145c8985236cc71846167f95110608a4f23ff710
|
7
|
+
data.tar.gz: 4d415c5c8bb406850a94beb42c57c8de59840adfd510ff7a78265d56e8c9bba7370b34f55c86a1c5bda0b345bf92ee8fa69af0e53844341cda21638e7059e405
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "net/http"
|
2
|
+
|
3
|
+
module V0
|
4
|
+
class ComponentGenerator < Rails::Generators::NamedBase
|
5
|
+
argument :description, type: :string, default: ""
|
6
|
+
@api_url = "https://api.v0.dev"
|
7
|
+
@token = ENV["V0_API_TOKEN"]
|
8
|
+
|
9
|
+
|
10
|
+
def fetch_from_v0
|
11
|
+
url = URI(@api_url + "/chat")
|
12
|
+
|
13
|
+
http = Net.http.new(url.hot, url.port)
|
14
|
+
http.use_ssl = true
|
15
|
+
|
16
|
+
request = Net::HTTP::Post.new(url)
|
17
|
+
request["Accept"] = "application/json"
|
18
|
+
request["Content-Type"] = "application/json"
|
19
|
+
request["Authorization"] = "Bearer #{@token}"
|
20
|
+
|
21
|
+
data = {
|
22
|
+
"message": :description
|
23
|
+
}
|
24
|
+
|
25
|
+
request["body"] = data.to_json
|
26
|
+
|
27
|
+
response = http.request(request)
|
28
|
+
output = JSON.parse(response.body)
|
29
|
+
return output if response.code == "200"
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ViteReact
|
2
|
+
module Generators
|
3
|
+
class DeviseGenerator < Rails::Generators::Base
|
4
|
+
source_root File.expand_path("templates", __dir__)
|
5
|
+
|
6
|
+
def add_devise_to_gemfile
|
7
|
+
gem "devise"
|
8
|
+
gem "devise-jwt"
|
9
|
+
end
|
10
|
+
|
11
|
+
def install_devise
|
12
|
+
generate "devise:install"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -6,11 +6,12 @@ require "rails/generators/resource_helpers"
|
|
6
6
|
|
7
7
|
module ViteReact
|
8
8
|
module Generators
|
9
|
-
class MigrationGenerator <
|
9
|
+
class MigrationGenerator < Rails::Generators::NamedBase
|
10
10
|
source_root File.expand_path("templates", __dir__)
|
11
11
|
|
12
12
|
argument :migration_name, type: :string
|
13
13
|
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
14
|
+
hook_for :orm
|
14
15
|
|
15
16
|
def update_types
|
16
17
|
puts "Updating TypeScript definitions based on #{migration_name}..."
|
@@ -43,11 +44,7 @@ module ViteReact
|
|
43
44
|
|
44
45
|
<<~TS
|
45
46
|
// AUTO-GENERATED by rails g migration #{migration_name}
|
46
|
-
|
47
|
-
// if presence validations exist.
|
48
|
-
// Changes introduced by: #{migration_name}
|
49
|
-
#{attributes_lines.join("
|
50
|
-
")}
|
47
|
+
#{attributes_lines.join("\n")}
|
51
48
|
TS
|
52
49
|
end
|
53
50
|
|
@@ -1,12 +1,12 @@
|
|
1
1
|
# lib/generators/rails/tmodel_validation/model_validation_generator.rb
|
2
2
|
|
3
|
-
module
|
3
|
+
module Vite_React
|
4
4
|
module Generators
|
5
5
|
class ModelValidationGenerator < Rails::Generators::NamedBase
|
6
6
|
source_root File.expand_path("templates", __dir__)
|
7
7
|
|
8
8
|
def update_types_for_validations
|
9
|
-
require File.join(Rails.root, "app/models
|
9
|
+
require File.join(Rails.root, "app/models/#{file_path}.rb")
|
10
10
|
|
11
11
|
model_class = file_name.camelize.constantize
|
12
12
|
|
@@ -23,7 +23,7 @@ module ViteReact
|
|
23
23
|
presence_required = presence_attributes.to_set
|
24
24
|
required_belongs_tos.each do |assoc_name|
|
25
25
|
presence_required << assoc_name # e.g. user
|
26
|
-
presence_required << "
|
26
|
+
presence_required << "#{assoc_name}_id" # e.g. user_id
|
27
27
|
end
|
28
28
|
|
29
29
|
types_file_path = Rails.root.join("app/javascript/types.d.ts")
|
@@ -36,7 +36,7 @@ module ViteReact
|
|
36
36
|
brace_depth = 0
|
37
37
|
|
38
38
|
|
39
|
-
start_of_interface_regex = /^\s*(?:export\s+)?interface\s
|
39
|
+
start_of_interface_regex = /^\s*(?:export\s+)?interface\s+#{Regexp.escape(model_class.name)}\s*(\{|extends|$)/
|
40
40
|
|
41
41
|
lines.map!.with_index do |line, idx|
|
42
42
|
if !in_target_interface && line =~ start_of_interface_regex
|
@@ -59,10 +59,10 @@ module ViteReact
|
|
59
59
|
question_mark = $3 # could be "" or "?"
|
60
60
|
|
61
61
|
if presence_required.include?(attribute_name)
|
62
|
-
line = line.sub("
|
62
|
+
line = line.sub("#{attribute_name}?:", "#{attribute_name}:")
|
63
63
|
else
|
64
64
|
unless question_mark == "?"
|
65
|
-
line = line.sub("
|
65
|
+
line = line.sub("#{attribute_name}:", "#{attribute_name}?:")
|
66
66
|
end
|
67
67
|
end
|
68
68
|
end
|
@@ -1,22 +1,37 @@
|
|
1
|
-
require "rails/generators/scaffold/scaffold_generator"
|
2
1
|
require "rails/generators/resource_helpers"
|
3
|
-
|
4
|
-
# lib/generators/rails/typescript/typescript_generator.rb
|
2
|
+
require "rails/generators/rails/scaffold/scaffold_generator"
|
5
3
|
|
6
4
|
module ViteReact
|
7
5
|
module Generators
|
8
|
-
class ScaffoldGenerator <
|
6
|
+
class ScaffoldGenerator < Rails::Generators::ScaffoldControllerGenerator
|
9
7
|
include Rails::Generators::ResourceHelpers
|
10
8
|
|
11
9
|
source_root File.expand_path("templates", __dir__)
|
12
10
|
|
13
11
|
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
14
12
|
|
13
|
+
remove_hook_for :template_engine
|
14
|
+
# hook_for :controller
|
15
|
+
|
16
|
+
def create_root_folder
|
17
|
+
empty_directory File.join("app/views", controller_file_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def copy_view_files
|
21
|
+
available_views.each do |view|
|
22
|
+
formats.each do |format|
|
23
|
+
filename = filename_with_extensions(view, format)
|
24
|
+
template filename, File.join("app/views", controller_file_path, filename)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
template "partial.html.erb", File.join("app/views", controller_file_path, "_#{singular_name}.html.erb")
|
29
|
+
end
|
30
|
+
|
15
31
|
|
16
32
|
def create_or_update_types
|
17
33
|
types_file_path = Rails.root.join("app/javascript/types.d.ts")
|
18
|
-
|
19
|
-
interface_code = generate_interface_code
|
34
|
+
interface_code = generate_interface_code
|
20
35
|
|
21
36
|
if File.exist?(types_file_path)
|
22
37
|
append_to_file types_file_path, interface_code
|
@@ -25,51 +40,69 @@ module ViteReact
|
|
25
40
|
end
|
26
41
|
end
|
27
42
|
|
28
|
-
|
29
|
-
|
30
|
-
private
|
31
|
-
|
32
43
|
def generate_interface_code
|
33
44
|
attributes_lines = attributes.flat_map do |attr|
|
34
|
-
puts attr.inspect
|
35
45
|
if attr.type == :references
|
36
|
-
|
46
|
+
build_ts_reference_lines(attr)
|
37
47
|
else
|
38
|
-
[
|
48
|
+
[ build_ts_attribute_line(attr) ]
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
42
52
|
<<~TS
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
}
|
48
|
-
|
53
|
+
// AUTO-GENERATED by rails g scaffold #{file_name}
|
54
|
+
interface #{class_name} {
|
55
|
+
#{attributes_lines.join("\n\t")}
|
56
|
+
}
|
49
57
|
TS
|
50
58
|
end
|
59
|
+
private
|
60
|
+
def build_ts_attribute_line(attr)
|
61
|
+
"#{attr.name}?: #{rails_to_ts_type(attr.type)};"
|
62
|
+
end
|
51
63
|
|
64
|
+
def build_ts_reference_lines(attr)
|
65
|
+
referenced_interface_name = attr.name.camelize
|
66
|
+
[
|
67
|
+
"#{attr.name}_id: number;",
|
68
|
+
"#{attr.name}?: #{referenced_interface_name};"
|
69
|
+
]
|
70
|
+
end
|
52
71
|
|
53
|
-
def build_attribute_line(attr)
|
54
|
-
"#{attr.name}?: #{rails_to_ts_type(attr.type)};"
|
55
|
-
end
|
56
72
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
73
|
+
def rails_to_ts_type(attribute)
|
74
|
+
case attribute
|
75
|
+
when :float, :decimal, :integer
|
76
|
+
"number"
|
77
|
+
when :boolean
|
78
|
+
"boolean"
|
79
|
+
when :attachment
|
80
|
+
"{ filename: string; url: string }"
|
81
|
+
when :attachments
|
82
|
+
"{ filename: string; url: string }[]"
|
83
|
+
else
|
84
|
+
"string"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
def available_views
|
88
|
+
%w[index edit show new _form]
|
89
|
+
end
|
64
90
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
91
|
+
def formats
|
92
|
+
[ format ]
|
93
|
+
end
|
94
|
+
|
95
|
+
def format
|
96
|
+
:html
|
97
|
+
end
|
98
|
+
|
99
|
+
def handler
|
100
|
+
:erb
|
101
|
+
end
|
102
|
+
|
103
|
+
def filename_with_extensions(name, file_format = format)
|
104
|
+
[ name, file_format, handler ].compact.join(".")
|
71
105
|
end
|
72
|
-
end
|
73
106
|
end
|
74
107
|
end
|
75
108
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
<%%= form_with(model: <%= model_resource_name %>, class: "contents") do |form| %>
|
2
|
+
<%% if <%= singular_table_name %>.errors.any? %>
|
3
|
+
<div id="error_explanation" class="bg-red-50 text-red-500 px-3 py-2 font-medium rounded-md mt-3">
|
4
|
+
<h2><%%= pluralize(<%= singular_table_name %>.errors.count, "error") %> prohibited this <%= singular_table_name %> from being saved:</h2>
|
5
|
+
|
6
|
+
<ul class="list-disc ml-6">
|
7
|
+
<%% <%= singular_table_name %>.errors.each do |error| %>
|
8
|
+
<li><%%= error.full_message %></li>
|
9
|
+
<%% end %>
|
10
|
+
</ul>
|
11
|
+
</div>
|
12
|
+
<%% end %>
|
13
|
+
|
14
|
+
<% attributes.each do |attribute| -%>
|
15
|
+
<div class="my-5">
|
16
|
+
<% if attribute.password_digest? -%>
|
17
|
+
<%%= form.label :password %>
|
18
|
+
<%%= form.password_field :password, class: ["block shadow rounded-md border outline-none px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": <%= model_resource_name %>.errors[:password].none?, "border-red-400 focus:outline-red-600": <%= model_resource_name %>.errors[:password].any?}] %>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div class="my-5">
|
22
|
+
<%%= form.label :password_confirmation %>
|
23
|
+
<%%= form.password_field :password_confirmation, class: ["block shadow rounded-md border outline-none px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": <%= model_resource_name %>.errors[:password_confirmation].none?, "border-red-400 focus:outline-red-600": <%= model_resource_name %>.errors[:password_confirmation].any?}] %>
|
24
|
+
<% elsif attribute.attachments? -%>
|
25
|
+
<%%= form.label :<%= attribute.column_name %> %>
|
26
|
+
<%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, multiple: true, class: ["block shadow rounded-md border outline-none px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": <%= model_resource_name %>.errors[:password].none?, "border-red-400 focus:outline-red-600": <%= model_resource_name %>.errors[:password].any?}] %>
|
27
|
+
<% else -%>
|
28
|
+
<%%= form.label :<%= attribute.column_name %> %>
|
29
|
+
<% if attribute.field_type == :textarea || attribute.field_type == :text_area -%>
|
30
|
+
<%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, rows: 4, class: ["block shadow rounded-md border outline-none px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": <%= model_resource_name %>.errors[:<%= attribute.column_name %>].none?, "border-red-400 focus:outline-red-600": <%= model_resource_name %>.errors[:<%= attribute.column_name %>].any?}] %>
|
31
|
+
<% elsif attribute.field_type == :checkbox || attribute.field_type == :check_box -%>
|
32
|
+
<%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, class: ["block shadow rounded-md border outline-none mt-2 h-5 w-5", {"border-gray-400 focus:outline-blue-600": <%= model_resource_name %>.errors[:<%= attribute.column_name %>].none?, "border-red-400 focus:outline-red-600": <%= model_resource_name %>.errors[:<%= attribute.column_name %>].any?}] %>
|
33
|
+
<% else -%>
|
34
|
+
<%%= form.<%= attribute.field_type %> :<%= attribute.column_name %>, class: ["block shadow rounded-md border outline-none px-3 py-2 mt-2 w-full", {"border-gray-400 focus:outline-blue-600": <%= model_resource_name %>.errors[:<%= attribute.column_name %>].none?, "border-red-400 focus:outline-red-600": <%= model_resource_name %>.errors[:<%= attribute.column_name %>].any?}] %>
|
35
|
+
<% end -%>
|
36
|
+
<% end -%>
|
37
|
+
</div>
|
38
|
+
|
39
|
+
<% end -%>
|
40
|
+
<div class="inline">
|
41
|
+
<%%= form.submit class: "rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white inline-block font-medium cursor-pointer" %>
|
42
|
+
</div>
|
43
|
+
<%% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="container mx-auto mt-28 px-5 flex">
|
2
|
+
<%% content_for :title, "Editing <%= human_name.downcase %>" %>
|
3
|
+
|
4
|
+
<div class="md:w-2/3 w-full">
|
5
|
+
<h1 class="font-bold text-4xl">Editing <%= human_name.downcase %></h1>
|
6
|
+
|
7
|
+
<%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
|
8
|
+
|
9
|
+
<%%= link_to "Show this <%= human_name.downcase %>", <%= model_resource_name(prefix: "@") %>, class: "ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
|
10
|
+
<%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %>, class: "ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
|
11
|
+
</div>
|
12
|
+
</div>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<div class="container mx-auto mt-28 px-5 flex">
|
2
|
+
<%% content_for :title, "<%= human_name.pluralize %>" %>
|
3
|
+
|
4
|
+
<div class="w-full">
|
5
|
+
<%% if notice.present? %>
|
6
|
+
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block" id="notice"><%%= notice %></p>
|
7
|
+
<%% end %>
|
8
|
+
|
9
|
+
<div class="flex justify-between items-center">
|
10
|
+
<h1 class="font-bold text-4xl"><%= human_name.pluralize %></h1>
|
11
|
+
<%%= link_to "New <%= human_name.downcase %>", new_<%= singular_route_name %>_path, class: "rounded-md px-3.5 py-2.5 bg-blue-600 hover:bg-blue-500 text-white block font-medium" %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div id="<%= plural_table_name %>" class="min-w-full">
|
15
|
+
<%% if @<%= plural_table_name %>.any? %>
|
16
|
+
<div class="w-full grid grid-cols-3 gap-3">
|
17
|
+
<%% @<%= plural_table_name %>.each do |<%= singular_table_name %>| %>
|
18
|
+
<div class="border border-black w-auto mt-3 p-4 rounded-lg">
|
19
|
+
<%%= render <%= singular_table_name %> %>
|
20
|
+
<p>
|
21
|
+
<%%= link_to "Show this <%= human_name.downcase %>", <%= model_resource_name(singular_table_name) %>, class: "ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
|
22
|
+
</p>
|
23
|
+
</div>
|
24
|
+
<%% end %>
|
25
|
+
</div>
|
26
|
+
<%% else %>
|
27
|
+
<p class="text-center my-10">No <%= human_name.downcase.pluralize %> found.</p>
|
28
|
+
<%% end %>
|
29
|
+
</div>
|
30
|
+
</div>
|
31
|
+
</div>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<div class="container mx-auto mt-28 px-5 flex">
|
2
|
+
<%% content_for :title, "New <%= human_name.downcase %>" %>
|
3
|
+
|
4
|
+
<div class="md:w-2/3 w-full">
|
5
|
+
<h1 class="font-bold text-4xl">New <%= human_name.downcase %></h1>
|
6
|
+
|
7
|
+
<%%= render "form", <%= singular_table_name %>: @<%= singular_table_name %> %>
|
8
|
+
|
9
|
+
<%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper(type: :path) %>, class: "ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
|
10
|
+
</div>
|
11
|
+
<div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div id="<%%= dom_id <%= singular_name %> %>">
|
2
|
+
<% attributes.reject(&:password_digest?).each do |attribute| -%>
|
3
|
+
<p class="my-5">
|
4
|
+
<strong class="block font-medium mb-1"><%= attribute.human_name %>:</strong>
|
5
|
+
<% if attribute.attachment? -%>
|
6
|
+
<%%= link_to <%= singular_name %>.<%= attribute.column_name %>.filename, <%= singular_name %>.<%= attribute.column_name %> if <%= singular_name %>.<%= attribute.column_name %>.attached? %>
|
7
|
+
<% elsif attribute.attachments? -%>
|
8
|
+
<%% <%= singular_name %>.<%= attribute.column_name %>.each do |<%= attribute.singular_name %>| %>
|
9
|
+
<div><%%= link_to <%= attribute.singular_name %>.filename, <%= attribute.singular_name %> %></div>
|
10
|
+
<%% end %>
|
11
|
+
<% else -%>
|
12
|
+
<%%= <%= singular_name %>.<%= attribute.column_name %> %>
|
13
|
+
<% end -%>
|
14
|
+
</p>
|
15
|
+
<% end -%>
|
16
|
+
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div class="container mx-auto mt-28 px-5 flex">
|
2
|
+
<%% content_for :title, "Showing <%= human_name.downcase %>" %>
|
3
|
+
|
4
|
+
<div class="md:w-2/3 w-full">
|
5
|
+
<%% if notice.present? %>
|
6
|
+
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-md inline-block" id="notice"><%%= notice %></p>
|
7
|
+
<%% end %>
|
8
|
+
|
9
|
+
<h1 class="font-bold text-4xl">Showing <%= human_name.downcase %></h1>
|
10
|
+
|
11
|
+
<%%= render @<%= singular_table_name %> %>
|
12
|
+
|
13
|
+
<%%= link_to "Edit this <%= human_name.downcase %>", <%= edit_helper(type: :path) %>, class: "mt-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
|
14
|
+
<%%= link_to "Back to <%= human_name.pluralize.downcase %>", <%= index_helper %>_path, class: "ml-2 rounded-md px-3.5 py-2.5 bg-gray-100 hover:bg-gray-50 inline-block font-medium" %>
|
15
|
+
<div class="inline-block ml-2">
|
16
|
+
<%%= button_to "Destroy this <%= human_name.downcase %>", <%= model_resource_name(prefix: "@") %>, method: :delete, class: "mt-2 rounded-md px-3.5 py-2.5 text-white bg-red-600 hover:bg-red-500 font-medium" %>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
|
data/lib/install/App.tsx
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { useState } from "react";
|
2
2
|
|
3
|
-
export function App() {
|
3
|
+
export default function App() {
|
4
4
|
const [count, setCount] = useState(0);
|
5
5
|
|
6
6
|
return (
|
@@ -25,9 +25,9 @@ export function App() {
|
|
25
25
|
</a>
|
26
26
|
</div>
|
27
27
|
<h1 className="text-4xl font-bold">
|
28
|
-
<span className="text-[#CC0000]">Rails </span
|
28
|
+
<span className="text-[#CC0000]">Rails </span>
|
29
29
|
+ <span className="text-[#61dafb]">React </span>
|
30
|
-
+ <span className="text-[#646cff]">Vite</span
|
30
|
+
+ <span className="text-[#646cff]">Vite</span>
|
31
31
|
</h1>
|
32
32
|
<div className="card flex flex-col items-center">
|
33
33
|
<button className="mb-4 font-semibold border border-transparent hover:border-[#646cff] cursor-pointer bg-[#1a1a1a] p-1 rounded-lg p-x-8" onClick={() => setCount((count) => count + 1)}>
|
@@ -0,0 +1,41 @@
|
|
1
|
+
|
2
|
+
export default function App() {
|
3
|
+
|
4
|
+
return (
|
5
|
+
<div className="flex bg-[#242424] gap-12 text-white h-screen flex-col justify-center items-center mx-auto w-screen">
|
6
|
+
<div className="flex text-3xl">
|
7
|
+
<a href="https://guides.rubyonrails.org/index.html" target="_blank">
|
8
|
+
<img
|
9
|
+
src="/images/rails.svg"
|
10
|
+
className="logo rails"
|
11
|
+
alt="Rails logo"
|
12
|
+
/>
|
13
|
+
</a>
|
14
|
+
<a href="https://react.dev" target="_blank">
|
15
|
+
<img
|
16
|
+
src="/images/react.svg"
|
17
|
+
className="logo react"
|
18
|
+
alt="React logo"
|
19
|
+
/>
|
20
|
+
</a>
|
21
|
+
<a href="https://vite.dev" target="_blank">
|
22
|
+
<img src="/images/vite.svg" className="logo" alt="Vite logo" />
|
23
|
+
</a>
|
24
|
+
</div>
|
25
|
+
<h1 className="text-4xl font-bold">
|
26
|
+
<span className="text-[#CC0000]">Rails </span>
|
27
|
+
+ <span className="text-[#61dafb]">React </span>
|
28
|
+
+ <span className="text-[#646cff]">Vite</span>
|
29
|
+
</h1>
|
30
|
+
<div className="card flex flex-col items-center">
|
31
|
+
<p>
|
32
|
+
Edit <code>app/javascript/components/App.tsx</code> and save to test
|
33
|
+
HMR
|
34
|
+
</p>
|
35
|
+
</div>
|
36
|
+
<p className="text-[#888]">
|
37
|
+
Click on the Rails, Vite and React logos to learn more
|
38
|
+
</p>
|
39
|
+
</div>
|
40
|
+
);
|
41
|
+
}
|