rails_app_generator 0.1.6 → 0.1.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.builders/generators/project-plan.rb +4 -3
  3. data/CHANGELOG.md +21 -0
  4. data/Rakefile +2 -0
  5. data/after_templates/README.md +6 -2
  6. data/after_templates/addons/rails_html_sanitizer/index.html.erb +31 -0
  7. data/after_templates/addons/rails_html_sanitizer.rb +15 -0
  8. data/after_templates/rag_devise/application.html.erb +20 -0
  9. data/after_templates/rag_devise/application_controller.rb +10 -0
  10. data/after_templates/rag_devise/config/initializers/devise_turbo.rb +30 -0
  11. data/after_templates/rag_devise/layouts/_alerts.html.erb +3 -0
  12. data/after_templates/rag_devise/layouts/_footer.html.erb +3 -0
  13. data/after_templates/rag_devise/layouts/_navbar.html.erb +14 -0
  14. data/after_templates/rag_devise/layouts/application.html.erb +24 -0
  15. data/after_templates/rag_devise/post/_post.html.erb +14 -0
  16. data/after_templates/rag_devise/post/post.rb +3 -0
  17. data/after_templates/rag_devise/post/posts_controller.rb +72 -0
  18. data/after_templates/rag_devise/seed_data.rb +8 -0
  19. data/after_templates/rag_devise/turbo_controller.rb +24 -0
  20. data/after_templates/rag_devise/user.rb +8 -0
  21. data/after_templates/rag_devise.rb +45 -0
  22. data/after_templates/rag_printspeak/application_controller.rb +22 -0
  23. data/after_templates/rag_printspeak/faq.html.erb +189 -0
  24. data/after_templates/rag_printspeak/layouts/_footer.html.erb +72 -0
  25. data/after_templates/rag_printspeak/layouts/_head.html.erb +17 -0
  26. data/after_templates/rag_printspeak/layouts/_navbar.html.erb +30 -0
  27. data/after_templates/rag_printspeak/layouts/application.html.erb +22 -0
  28. data/after_templates/rag_printspeak/page/_footer.html.erb +184 -0
  29. data/after_templates/rag_printspeak/page/architecture.html.erb +33 -0
  30. data/after_templates/rag_printspeak/page/blog.html.erb +44 -0
  31. data/after_templates/rag_printspeak/page/faq.html.erb +2 -0
  32. data/after_templates/rag_printspeak/page/home.html.erb +32 -0
  33. data/after_templates/rag_printspeak/page/page_controller.rb +27 -0
  34. data/after_templates/rag_printspeak/page/readme.html.erb +49 -0
  35. data/after_templates/rag_printspeak.rb +36 -0
  36. data/after_templates/rag_tailwind_hotwire_flash.rb +2 -1
  37. data/docs/images/tailwind.png +0 -0
  38. data/docs/images/tailwind_daisyui.png +0 -0
  39. data/docs/images/tailwind_emulating_bootstrap.png +0 -0
  40. data/docs/images/tailwind_hotwire.png +0 -0
  41. data/docs/images/tailwind_hotwire_form.png +0 -0
  42. data/docs/images/tailwind_hotwire_form_search.png +0 -0
  43. data/docs/project-plan/project.drawio +37 -40
  44. data/docs/project-plan/project_in_progress.svg +1 -1
  45. data/docs/project-plan/project_todo.svg +1 -1
  46. data/docs/videos.md +44 -0
  47. data/exe/rag +1 -12
  48. data/lib/rails_app_generator/add_on.rb +17 -2
  49. data/lib/rails_app_generator/addons/annotate.rb +5 -0
  50. data/lib/rails_app_generator/addons/devise.rb +17 -7
  51. data/lib/rails_app_generator/addons/rails_html_sanitizer.rb +14 -0
  52. data/lib/rails_app_generator/addons/xmen.rb +17 -0
  53. data/lib/rails_app_generator/app_builder.rb +3 -3
  54. data/lib/rails_app_generator/app_generator.rb +187 -3
  55. data/lib/rails_app_generator/diff/processor.rb +13 -0
  56. data/lib/rails_app_generator/formatted_gem_entry.rb +12 -0
  57. data/lib/rails_app_generator/options/rails_options.rb +4 -1
  58. data/lib/rails_app_generator/starter.rb +7 -5
  59. data/lib/rails_app_generator/version.rb +1 -1
  60. data/lib/rails_app_generator.rb +1 -0
  61. data/package-lock.json +2 -2
  62. data/package.json +1 -1
  63. data/profiles/addons/rails-html-sanitizer.json +12 -0
  64. data/profiles/rag-devise.json +12 -0
  65. data/profiles/rag-printspeak.json +11 -0
  66. data/profiles/rag-sample.json +13 -0
  67. data/tasks/addon.thor +71 -0
  68. data/tasks/profile.thor +12 -0
  69. data/templates/Gemfile-original-r7 +65 -0
  70. data/templates/Gemfile-original-schienenzeppelin.erb +151 -0
  71. data/templates/Gemfile.erb +67 -0
  72. data/templates/Gemfile.tt +68 -0
  73. data/templates/thor_task/addon/addon.tt +21 -0
  74. metadata +53 -6
  75. data/lib/rails_app_generator/notes/a1.txt +0 -86
  76. data/lib/rails_app_generator/notes/a2.txt +0 -100
  77. data/lib/rails_app_generator/notes/kw01-b.txt +0 -86
  78. data/lib/rails_app_generator/notes/kw01.txt +0 -91
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74ea402449d28be464f76e50d4f78f0e29905f7b23ab85bdb7c12a1be32337a1
4
- data.tar.gz: e6543558c80c0c27428ad863b6927ac3d5c39430b828c55feb4d4006a1295bec
3
+ metadata.gz: 96c2c0a83f21efd278ae574b7161c8b3d4522880f3b01b37d43b783ede17d7ec
4
+ data.tar.gz: 54c7745878991f2bbc49e894a205582c90dd7bda79d6b3d7de811a48622beaf5
5
5
  SHA512:
6
- metadata.gz: 7311f3c9f20f306e775f1c818ef9c0ce47ab0392b4eb54fca421ffcaa023b3b1b62aedd6ee9f320a277f53da14066eb7139ed21d7695bd47a220313e97f78996
7
- data.tar.gz: dcb71902c885e49d3d6197d47f445edb3db5528cd22f0b700b9c9823a41fdd9b321cd891f9a476672fd6ddc07cd8dff94df5b30e86711fd4bddd1aaf12db36c5
6
+ metadata.gz: 8bc7eebffc7d3c2f8bc1c4a6d758d8ca826355d0e2421a01dfec5b57d3b00a8bbab37f3cb8b6eab59ef2f9d30f47bd81596dfb6b0b7d0b996f15c783aa52a22d
7
+ data.tar.gz: 4e9dc215f0574e203240817ad2b5f5aa231e0628fb7c352b2274c59612a7d88c89dda174ed19083929b9c39eae0235bdbdc878e2947e5b055c27ff26a02831cc
@@ -14,6 +14,7 @@ KManager.action :project_plan do
14
14
  grid_layout(y:90, direction: :horizontal, grid_h: 80, grid_w: 320, wrap_at: 3, grid: 0)
15
15
 
16
16
  todo(title: 'generator for new profiles')
17
+ todo(title: 'look at the sample tailwind pages in P7 and turn them into an addon')
17
18
 
18
19
  todo(title: 'add auto open flag to profile and command line')
19
20
  todo(title: 'add profile - stimulas')
@@ -22,9 +23,9 @@ KManager.action :project_plan do
22
23
  todo(title: 'add profile - vue')
23
24
  todo(title: 'add profile - svelte')
24
25
  todo(title: 'add profile - react')
25
- todo(title: 'add profile - vite')
26
- todo(title: 'add profile - docker') # https://www.youtube.com/watch?v=ZhrnqHVVo1g
27
- todo(title: 'add encryption - https://youtu.be/ZmwNzod1trk?t=701')
26
+ todo(title: 'add profile - vite') # see: /Users/davidcruwys/dev/printspeak/printspeak-r7-test1
27
+ todo(title: 'add profile - docker') # https://www.youtube.com/watch?v=ZhrnqHVVo1g
28
+ todo(title: 'add encryption') # https://youtu.be/ZmwNzod1trk?t=701
28
29
  todo(title: 'cli help support for diff')
29
30
  todo(title: 'cli support for rails new (rag new should work like rails new) - buggy, need to work through')
30
31
  todo(title: 'need an option for deleting target project path') # FileUtils.rm_rf(instance.target_path)
data/CHANGELOG.md CHANGED
@@ -1,3 +1,24 @@
1
+ ## [0.1.8](https://github.com/klueless-io/rails_app_generator/compare/v0.1.7...v0.1.8) (2022-07-31)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * add support for required gems on addons ([78bfcef](https://github.com/klueless-io/rails_app_generator/commit/78bfcef2323cdc01edb769924585d86d4ff21579))
7
+
8
+ ## [0.1.7](https://github.com/klueless-io/rails_app_generator/compare/v0.1.6...v0.1.7) (2022-07-30)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * add video documentation ([79fa9ae](https://github.com/klueless-io/rails_app_generator/commit/79fa9aeafe5d195b14cfcd1124f45dc6c30f16fc))
14
+
15
+ ## [0.1.6](https://github.com/klueless-io/rails_app_generator/compare/v0.1.5...v0.1.6) (2022-07-30)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * add profile - tailwind-emulating-bootstrap ([d79b99e](https://github.com/klueless-io/rails_app_generator/commit/d79b99ecb8448635952d6c978aea9c5e92f11a71))
21
+
1
22
  ## [0.1.5](https://github.com/klueless-io/rails_app_generator/compare/v0.1.4...v0.1.5) (2022-07-29)
2
23
 
3
24
 
data/Rakefile CHANGED
@@ -8,6 +8,8 @@ require 'bundler/gem_tasks'
8
8
  require 'rspec/core/rake_task'
9
9
  require 'rails_app_generator/version'
10
10
 
11
+ require 'pry'
12
+
11
13
  RSpec::Core::RakeTask.new(:spec)
12
14
 
13
15
  require 'rake/extensiontask'
@@ -4,11 +4,15 @@ A set of templates that can be used via the `--template` argument
4
4
 
5
5
  ## Videos
6
6
 
7
+ - profile: rag-tailwind
8
+ - Demonstrates a Tailwind homepage
9
+ - setup tailwind using --css=tailwind option
10
+ - profile: rag-tailwind-daisyui
11
+ - Tailwind, DaisyUI and Theme Changer using Stimulus
12
+ - Make sure it persists the theme change across pages
7
13
  - Bootstrap & Tailwind in same application plus Bootstrap Emulation
8
14
  - Demonstrates running bootstrap and tailwind in the same Rails 7 application
9
15
  - Demonstrates using Bootstrap CSS classes in a Tailwind project
10
16
  - Hotwire Flash Messages
11
- - Tailwind, DaisyUI and Theme Changer using Stimulus
12
- - Make sure it persists the theme change across pages
13
17
  - Tailwind, Reusing Styles
14
18
  - https://tailwindcss.com/docs/reusing-styles
@@ -0,0 +1,31 @@
1
+ <h1>Testing HTML Sanitizer</h1>
2
+
3
+ <p>Read more here <a href="https://github.com/rails/rails-html-sanitizer">rails-html-sanitizer</a></p>
4
+
5
+ <textarea rows="4" cols="200">
6
+ full_sanitizer = Rails::Html::FullSanitizer.new
7
+ full_sanitizer.sanitize("<b>Bold</b> no more! <a href='more.html'>See more here</a>...")
8
+ </textarea>
9
+
10
+ <hr>
11
+ <%=
12
+ Rails::Html::FullSanitizer
13
+ .new
14
+ .sanitize("<b>Bold</b> no more! <a href='more.html'>See more here</a>...")
15
+ %>
16
+
17
+ <br/><br/><br/>
18
+
19
+ <hr>
20
+
21
+ <textarea rows="4" cols="200">
22
+ link_sanitizer = Rails::Html::LinkSanitizer.new
23
+ link_sanitizer.sanitize('<a href="example.com">Only the link text will be kept.</a>')
24
+ # => Only the link text will be kept.
25
+ </textarea>
26
+
27
+ <%=
28
+ Rails::Html::LinkSanitizer
29
+ .new
30
+ .sanitize('<a href="example.com">Only the link text will be kept.</a>')
31
+ %>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Rails HTML Sanitizer is responsible for sanitizing HTML fragments in Rails applications, i.e. in the sanitize, sanitize_css, strip_tags and strip_links methods.
4
+ require 'pry'
5
+
6
+ self.local_template_path = local_template_base(__FILE__)
7
+
8
+ gac 'base rails 7 image created'
9
+
10
+ add_controller('home', 'index')
11
+ route("root 'home#index'")
12
+
13
+ force_copy
14
+
15
+ copy_file 'index.html.erb', 'app/views/home/index.html.erb'
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Devise</title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%= csrf_meta_tags %>
7
+ <%= csp_meta_tag %>
8
+
9
+ <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
10
+ </head>
11
+
12
+ <body>
13
+ <%= render 'layouts/navbar' %>
14
+ <main>
15
+ <%= render 'layouts/alerts' %>
16
+ <%= yield %>
17
+ </main>
18
+ <%= render 'layouts/footer' %>
19
+ </body>
20
+ </html>
@@ -0,0 +1,10 @@
1
+ class ApplicationController < ActionController::Base
2
+ # THIS is being handled by the generate devise:controller users
3
+ # before_action :configure_permitted_parameters, if: :devise_controller?
4
+
5
+ # protected
6
+
7
+ # def configure_permitted_parameters
8
+ # devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
9
+ # end
10
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Having issues with devise/turbo.
4
+ # See: https://gorails.com/episodes/devise-hotwire-turbo
5
+ class TurboFailureApp < Devise::FailureApp
6
+ def respond
7
+ if request_format == :turbo_stream
8
+ redirect
9
+ else
10
+ super
11
+ end
12
+ end
13
+
14
+ def skip_format?
15
+ %w(html turbo_stream */*).include? request_format.to_s
16
+ end
17
+ end
18
+
19
+ Devise.setup do |config|
20
+ # ==> Controller configuration
21
+ # Configure the parent class to the devise controllers.
22
+ config.parent_controller = 'TurboController'
23
+
24
+ config.navigational_formats = ['*/*', :html, :turbo_stream]
25
+
26
+ # ==> Warden configuration
27
+ config.warden do |manager|
28
+ manager.failure_app = TurboFailureApp
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ <% if notice %><p class="notice"><%= notice %></p><% end %>
2
+ <% if alert %><p class="alert"><%= alert %></p><% end %>
3
+
@@ -0,0 +1,3 @@
1
+ <footer>
2
+ <hr />
3
+ </footer>
@@ -0,0 +1,14 @@
1
+ <header>
2
+ <h1>Devise</h1>
3
+ <%=link_to 'Posts', posts_path %> |
4
+
5
+ <% if current_user %>
6
+ <span>(<%= current_user.name %>)</span>
7
+ <%= link_to "Log out", destroy_user_session_path, method: :delete, data: { turbo_method: :delete } %>
8
+ <%= link_to "My Profile", edit_user_registration_path %>
9
+ <% else %>
10
+ <%=link_to 'Sign Up', new_user_registration_path %> |
11
+ <%=link_to 'Login', new_user_session_path %>
12
+ <% end %>
13
+ <hr />
14
+ </header>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= camelized %></title>
5
+ <meta name="viewport" content="width=device-width,initial-scale=1">
6
+ <%%= csrf_meta_tags %>
7
+ <%%= csp_meta_tag %>
8
+
9
+ <%- if options[:skip_hotwire] || options[:skip_javascript] -%>
10
+ <%%= stylesheet_link_tag "application" %>
11
+ <%- else -%>
12
+ <%%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
13
+ <%- end -%>
14
+ </head>
15
+
16
+ <body>
17
+ <%%= render 'layouts/navbar' %>
18
+ <main>
19
+ <%%= render 'layouts/alerts' %>
20
+ <%%= yield %>
21
+ </main>
22
+ <%%= render 'layouts/footer' %>
23
+ </body>
24
+ </html>
@@ -0,0 +1,14 @@
1
+ <div id="<%= dom_id post %>">
2
+ <h4>posted by <%= post.user.email %></h4>
3
+
4
+ <p>
5
+ <strong>Title:</strong>
6
+ <%= post.title %>
7
+ </p>
8
+
9
+ <p>
10
+ <strong>Body:</strong>
11
+ <%= post.body %>
12
+ </p>
13
+
14
+ </div>
@@ -0,0 +1,3 @@
1
+ class Post < ApplicationRecord
2
+ belongs_to :user
3
+ end
@@ -0,0 +1,72 @@
1
+ class PostsController < ApplicationController
2
+ before_action :authenticate_user!, except: %i[show index]
3
+ before_action :set_post, only: %i[ show edit update destroy ]
4
+
5
+ # GET /posts or /posts.json
6
+ def index
7
+ @posts = Post.all
8
+ end
9
+
10
+ # GET /posts/1 or /posts/1.json
11
+ def show
12
+ end
13
+
14
+ # GET /posts/new
15
+ def new
16
+ @post = Post.new
17
+ end
18
+
19
+ # GET /posts/1/edit
20
+ def edit
21
+ end
22
+
23
+ # POST /posts or /posts.json
24
+ def create
25
+ @post = Post.new(post_params)
26
+ @post.user = current_user
27
+
28
+ respond_to do |format|
29
+ if @post.save
30
+ format.html { redirect_to post_url(@post), notice: "Post was successfully created." }
31
+ format.json { render :show, status: :created, location: @post }
32
+ else
33
+ format.html { render :new, status: :unprocessable_entity }
34
+ format.json { render json: @post.errors, status: :unprocessable_entity }
35
+ end
36
+ end
37
+ end
38
+
39
+ # PATCH/PUT /posts/1 or /posts/1.json
40
+ def update
41
+ respond_to do |format|
42
+ if @post.update(post_params)
43
+ format.html { redirect_to post_url(@post), notice: "Post was successfully updated." }
44
+ format.json { render :show, status: :ok, location: @post }
45
+ else
46
+ format.html { render :edit, status: :unprocessable_entity }
47
+ format.json { render json: @post.errors, status: :unprocessable_entity }
48
+ end
49
+ end
50
+ end
51
+
52
+ # DELETE /posts/1 or /posts/1.json
53
+ def destroy
54
+ @post.destroy
55
+
56
+ respond_to do |format|
57
+ format.html { redirect_to posts_url, notice: "Post was successfully destroyed." }
58
+ format.json { head :no_content }
59
+ end
60
+ end
61
+
62
+ private
63
+ # Use callbacks to share common setup or constraints between actions.
64
+ def set_post
65
+ @post = Post.find(params[:id])
66
+ end
67
+
68
+ # Only allow a list of trusted parameters through.
69
+ def post_params
70
+ params.require(:post).permit(:title, :body)
71
+ end
72
+ end
@@ -0,0 +1,8 @@
1
+
2
+ david = User.create(email: 'david@site.com', name: 'david', password: 'password')
3
+ bob = User.create(email: 'bob@site.com', name: 'bob', password: 'password')
4
+ lisa = User.create(email: 'lisa@site.com', name: 'lisa', password: 'password')
5
+
6
+ 10.times do |i|
7
+ Post.create(title: "Post #{i}", body: "This is the body of post #{i}", user: User.all.sample)
8
+ end
@@ -0,0 +1,24 @@
1
+ class TurboController < ApplicationController
2
+
3
+ # This is required for Devise to work.
4
+ # See: https://youtu.be/m3uhldUGVes?t=1432
5
+ #
6
+ # Having issues with devise/turbo.
7
+ # See: https://gorails.com/episodes/devise-hotwire-turbo
8
+ class Responder < ActionController::Responder
9
+ def to_turbo_stream
10
+ controller.render(options.merge(formats: :html))
11
+ rescue ActionView::MissingTemplate => error
12
+ if get?
13
+ raise error
14
+ elsif has_errors? && default_action
15
+ render rendering_options.merge(formats: :html, status: :unprocessable_entity)
16
+ else
17
+ redirect_to navigation_location
18
+ end
19
+ end
20
+ end
21
+
22
+ self.responder = Responder
23
+ respond_to :html, :turbo_stream
24
+ end
@@ -0,0 +1,8 @@
1
+ class User < ApplicationRecord
2
+ # Include default devise modules. Others available are:
3
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
4
+ devise :database_authenticatable, :registerable,
5
+ :recoverable, :rememberable, :validatable
6
+
7
+ has_many :posts
8
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Rails 7 - Intro to Devise
4
+ # https://www.youtube.com/watch?v=m3uhldUGVes
5
+
6
+ require 'pry'
7
+
8
+ self.local_template_path = local_template_base(__FILE__)
9
+
10
+ gac 'base rails 7 image created'
11
+
12
+ # generate('devise:views')
13
+
14
+ add_scaffold('post', 'title', 'body:text')
15
+ route("root 'posts#index'")
16
+
17
+ force_copy
18
+
19
+ copy_file 'application_controller.rb' , 'app/controllers/application_controller.rb'
20
+ copy_file 'turbo_controller.rb' , 'app/controllers/turbo_controller.rb'
21
+
22
+ copy_file 'layouts/_alerts.html.erb' , 'app/views/layouts/_alerts.html.erb'
23
+ copy_file 'layouts/_navbar.html.erb' , 'app/views/layouts/_navbar.html.erb'
24
+ copy_file 'layouts/_footer.html.erb' , 'app/views/layouts/_footer.html.erb'
25
+ template 'layouts/application.html.erb' , 'app/views/layouts/application.html.erb'
26
+
27
+ copy_file 'config/initializers/devise_turbo.rb' , 'config/initializers/devise_turbo.rb'
28
+
29
+ copy_file 'post/posts_controller.rb' , 'app/controllers/posts_controller.rb'
30
+ copy_file 'post/_post.html.erb' , 'app/views/posts/_post.html.erb'
31
+ copy_file 'post/post.rb' , 'app/models/post.rb'
32
+
33
+ copy_file 'user.rb' , 'app/models/user.rb'
34
+
35
+ copy_file 'application.html.erb' , 'app/views/layouts/application.html.erb'
36
+ copy_file 'application_controller.rb' , 'app/controllers/application_controller.rb'
37
+
38
+ add_migration('add_user_to_posts', 'user:belongs_to')
39
+
40
+ after_bundle do
41
+ db_migrate
42
+
43
+ append_to_file('db/seeds.rb', read_template('seed_data.rb'))
44
+ db_seed
45
+ end
@@ -0,0 +1,22 @@
1
+ class ApplicationController < ActionController::Base
2
+ def navbar_partial(partial = nil)
3
+ @partial_navbar = partial if partial
4
+ return @partial_navbar if defined? @partial_navbar
5
+ @partial_navbar = 'layouts/navbar'
6
+ end
7
+ helper_method :navbar_partial
8
+
9
+ def head_partial(partial = nil)
10
+ @partial_head = partial if partial
11
+ return @partial_head if defined? @partial_head
12
+ @partial_head = 'layouts/head'
13
+ end
14
+ helper_method :head_partial
15
+
16
+ def footer_partial(partial = nil)
17
+ @partial_footer = partial if partial
18
+ return @partial_footer if defined? @partial_footer
19
+ @partial_footer = 'layouts/footer'
20
+ end
21
+ helper_method :footer_partial
22
+ end
@@ -0,0 +1,189 @@
1
+ <section>
2
+ <div class="container">
3
+ <div class="flex flex-wrap -mx-4">
4
+ <div class="w-full px-4">
5
+ <div class="text-center mx-auto mb-[60px] lg:mb-20 max-w-[520px]">
6
+ <span class="font-semibold text-lg text-primary mb-2 block"> FAQ </span>
7
+ <h2 class="font-bold text-3xl sm:text-4xl md:text-[40px] text-dark mb-4">Any Questions? Look Here</h2>
8
+ <p class="text-base text-body-color">
9
+ There are many variations of passages of Lorem Ipsum available but the majority have suffered alteration in
10
+ some form.
11
+ </p>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ <div class="flex flex-wrap -mx-4">
16
+ <div class="w-full lg:w-1/2 px-4">
17
+ <div class="single-faq w-full bg-white border border-[#F3F4FE] rounded-lg p-4 sm:p-8 lg:px-6 xl:px-8 mb-8">
18
+ <button class="faq-btn flex w-full text-left" @click="openFaq1 = !openFaq1">
19
+ <div
20
+ class="w-full max-w-[40px] h-10 flex items-center justify-center rounded-lg bg-primary text-primary bg-opacity-5 mr-5"
21
+ >
22
+ <svg width="17" height="10" viewBox="0 0 17 10" class="fill-current icon">
23
+ <path
24
+ d="M7.28687 8.43257L7.28679 8.43265L7.29496 8.43985C7.62576 8.73124 8.02464 8.86001 8.41472 8.86001C8.83092 8.86001 9.22376 8.69083 9.53447 8.41713L9.53454 8.41721L9.54184 8.41052L15.7631 2.70784L15.7691 2.70231L15.7749 2.69659C16.0981 2.38028 16.1985 1.80579 15.7981 1.41393C15.4803 1.1028 14.9167 1.00854 14.5249 1.38489L8.41472 7.00806L2.29995 1.38063L2.29151 1.37286L2.28271 1.36548C1.93092 1.07036 1.38469 1.06804 1.03129 1.41393L1.01755 1.42738L1.00488 1.44184C0.69687 1.79355 0.695778 2.34549 1.0545 2.69659L1.05999 2.70196L1.06565 2.70717L7.28687 8.43257Z"
25
+ fill="#3056D3"
26
+ stroke="#3056D3"
27
+ />
28
+ </svg>
29
+ </div>
30
+ <div class="w-full">
31
+ <h4 class="text-lg font-semibold text-black">How long we deliver your first blog post?</h4>
32
+ </div>
33
+ </button>
34
+ <div x-show="openFaq1" class="faq-content pl-[62px]">
35
+ <p class="text-base text-body-color leading-relaxed py-3">
36
+ It takes 2-3 weeks to get your first blog post ready. That includes the in-depth research & creation of
37
+ your monthly content marketing strategy that we do before writing your first blog post, Ipsum available .
38
+ </p>
39
+ </div>
40
+ </div>
41
+ <div class="single-faq w-full bg-white border border-[#F3F4FE] rounded-lg p-4 sm:p-8 lg:px-6 xl:px-8 mb-8">
42
+ <button class="faq-btn flex w-full text-left" @click="openFaq2 = !openFaq2">
43
+ <div
44
+ class="w-full max-w-[40px] h-10 flex items-center justify-center rounded-lg bg-primary text-primary bg-opacity-5 mr-5"
45
+ >
46
+ <svg width="17" height="10" viewBox="0 0 17 10" class="fill-current icon">
47
+ <path
48
+ d="M7.28687 8.43257L7.28679 8.43265L7.29496 8.43985C7.62576 8.73124 8.02464 8.86001 8.41472 8.86001C8.83092 8.86001 9.22376 8.69083 9.53447 8.41713L9.53454 8.41721L9.54184 8.41052L15.7631 2.70784L15.7691 2.70231L15.7749 2.69659C16.0981 2.38028 16.1985 1.80579 15.7981 1.41393C15.4803 1.1028 14.9167 1.00854 14.5249 1.38489L8.41472 7.00806L2.29995 1.38063L2.29151 1.37286L2.28271 1.36548C1.93092 1.07036 1.38469 1.06804 1.03129 1.41393L1.01755 1.42738L1.00488 1.44184C0.69687 1.79355 0.695778 2.34549 1.0545 2.69659L1.05999 2.70196L1.06565 2.70717L7.28687 8.43257Z"
49
+ fill="#3056D3"
50
+ stroke="#3056D3"
51
+ />
52
+ </svg>
53
+ </div>
54
+ <div class="w-full">
55
+ <h4 class="text-lg font-semibold text-black">How long we deliver your first blog post?</h4>
56
+ </div>
57
+ </button>
58
+ <div x-show="openFaq2" class="faq-content pl-[62px]">
59
+ <p class="text-base text-body-color leading-relaxed py-3">
60
+ It takes 2-3 weeks to get your first blog post ready. That includes the in-depth research & creation of
61
+ your monthly content marketing strategy that we do before writing your first blog post, Ipsum available .
62
+ </p>
63
+ </div>
64
+ </div>
65
+ <div class="single-faq w-full bg-white border border-[#F3F4FE] rounded-lg p-4 sm:p-8 lg:px-6 xl:px-8 mb-8">
66
+ <button class="faq-btn flex w-full text-left" @click="openFaq3 = !openFaq3">
67
+ <div
68
+ class="w-full max-w-[40px] h-10 flex items-center justify-center rounded-lg bg-primary text-primary bg-opacity-5 mr-5"
69
+ >
70
+ <svg width="17" height="10" viewBox="0 0 17 10" class="fill-current icon">
71
+ <path
72
+ d="M7.28687 8.43257L7.28679 8.43265L7.29496 8.43985C7.62576 8.73124 8.02464 8.86001 8.41472 8.86001C8.83092 8.86001 9.22376 8.69083 9.53447 8.41713L9.53454 8.41721L9.54184 8.41052L15.7631 2.70784L15.7691 2.70231L15.7749 2.69659C16.0981 2.38028 16.1985 1.80579 15.7981 1.41393C15.4803 1.1028 14.9167 1.00854 14.5249 1.38489L8.41472 7.00806L2.29995 1.38063L2.29151 1.37286L2.28271 1.36548C1.93092 1.07036 1.38469 1.06804 1.03129 1.41393L1.01755 1.42738L1.00488 1.44184C0.69687 1.79355 0.695778 2.34549 1.0545 2.69659L1.05999 2.70196L1.06565 2.70717L7.28687 8.43257Z"
73
+ fill="#3056D3"
74
+ stroke="#3056D3"
75
+ />
76
+ </svg>
77
+ </div>
78
+ <div class="w-full">
79
+ <h4 class="text-lg font-semibold text-black">How long we deliver your first blog post?</h4>
80
+ </div>
81
+ </button>
82
+ <div x-show="openFaq3" class="faq-content pl-[62px]">
83
+ <p class="text-base text-body-color leading-relaxed py-3">
84
+ It takes 2-3 weeks to get your first blog post ready. That includes the in-depth research & creation of
85
+ your monthly content marketing strategy that we do before writing your first blog post, Ipsum available .
86
+ </p>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ <div class="w-full lg:w-1/2 px-4">
91
+ <div class="single-faq w-full bg-white border border-[#F3F4FE] rounded-lg p-4 sm:p-8 lg:px-6 xl:px-8 mb-8">
92
+ <button class="faq-btn flex w-full text-left" @click="openFaq4 = !openFaq4">
93
+ <div
94
+ class="w-full max-w-[40px] h-10 flex items-center justify-center rounded-lg bg-primary text-primary bg-opacity-5 mr-5"
95
+ >
96
+ <svg width="17" height="10" viewBox="0 0 17 10" class="fill-current icon">
97
+ <path
98
+ d="M7.28687 8.43257L7.28679 8.43265L7.29496 8.43985C7.62576 8.73124 8.02464 8.86001 8.41472 8.86001C8.83092 8.86001 9.22376 8.69083 9.53447 8.41713L9.53454 8.41721L9.54184 8.41052L15.7631 2.70784L15.7691 2.70231L15.7749 2.69659C16.0981 2.38028 16.1985 1.80579 15.7981 1.41393C15.4803 1.1028 14.9167 1.00854 14.5249 1.38489L8.41472 7.00806L2.29995 1.38063L2.29151 1.37286L2.28271 1.36548C1.93092 1.07036 1.38469 1.06804 1.03129 1.41393L1.01755 1.42738L1.00488 1.44184C0.69687 1.79355 0.695778 2.34549 1.0545 2.69659L1.05999 2.70196L1.06565 2.70717L7.28687 8.43257Z"
99
+ fill="#3056D3"
100
+ stroke="#3056D3"
101
+ />
102
+ </svg>
103
+ </div>
104
+ <div class="w-full">
105
+ <h4 class="text-lg font-semibold text-black">How long we deliver your first blog post?</h4>
106
+ </div>
107
+ </button>
108
+ <div x-show="openFaq4" class="faq-content pl-[62px]">
109
+ <p class="text-base text-body-color leading-relaxed py-3">
110
+ It takes 2-3 weeks to get your first blog post ready. That includes the in-depth research & creation of
111
+ your monthly content marketing strategy that we do before writing your first blog post, Ipsum available .
112
+ </p>
113
+ </div>
114
+ </div>
115
+ <div class="single-faq w-full bg-white border border-[#F3F4FE] rounded-lg p-4 sm:p-8 lg:px-6 xl:px-8 mb-8">
116
+ <button class="faq-btn flex w-full text-left" @click="openFaq5 = !openFaq5">
117
+ <div
118
+ class="w-full max-w-[40px] h-10 flex items-center justify-center rounded-lg bg-primary text-primary bg-opacity-5 mr-5"
119
+ >
120
+ <svg width="17" height="10" viewBox="0 0 17 10" class="fill-current icon">
121
+ <path
122
+ d="M7.28687 8.43257L7.28679 8.43265L7.29496 8.43985C7.62576 8.73124 8.02464 8.86001 8.41472 8.86001C8.83092 8.86001 9.22376 8.69083 9.53447 8.41713L9.53454 8.41721L9.54184 8.41052L15.7631 2.70784L15.7691 2.70231L15.7749 2.69659C16.0981 2.38028 16.1985 1.80579 15.7981 1.41393C15.4803 1.1028 14.9167 1.00854 14.5249 1.38489L8.41472 7.00806L2.29995 1.38063L2.29151 1.37286L2.28271 1.36548C1.93092 1.07036 1.38469 1.06804 1.03129 1.41393L1.01755 1.42738L1.00488 1.44184C0.69687 1.79355 0.695778 2.34549 1.0545 2.69659L1.05999 2.70196L1.06565 2.70717L7.28687 8.43257Z"
123
+ fill="#3056D3"
124
+ stroke="#3056D3"
125
+ />
126
+ </svg>
127
+ </div>
128
+ <div class="w-full">
129
+ <h4 class="text-lg font-semibold text-black">How long we deliver your first blog post?</h4>
130
+ </div>
131
+ </button>
132
+ <div x-show="openFaq5" class="faq-content pl-[62px]">
133
+ <p class="text-base text-body-color leading-relaxed py-3">
134
+ It takes 2-3 weeks to get your first blog post ready. That includes the in-depth research & creation of
135
+ your monthly content marketing strategy that we do before writing your first blog post, Ipsum available .
136
+ </p>
137
+ </div>
138
+ </div>
139
+ <div class="single-faq w-full bg-white border border-[#F3F4FE] rounded-lg p-4 sm:p-8 lg:px-6 xl:px-8 mb-8">
140
+ <button class="faq-btn flex w-full text-left" @click="openFaq6 = !openFaq6">
141
+ <div
142
+ class="w-full max-w-[40px] h-10 flex items-center justify-center rounded-lg bg-primary text-primary bg-opacity-5 mr-5"
143
+ >
144
+ <svg width="17" height="10" viewBox="0 0 17 10" class="fill-current icon">
145
+ <path
146
+ d="M7.28687 8.43257L7.28679 8.43265L7.29496 8.43985C7.62576 8.73124 8.02464 8.86001 8.41472 8.86001C8.83092 8.86001 9.22376 8.69083 9.53447 8.41713L9.53454 8.41721L9.54184 8.41052L15.7631 2.70784L15.7691 2.70231L15.7749 2.69659C16.0981 2.38028 16.1985 1.80579 15.7981 1.41393C15.4803 1.1028 14.9167 1.00854 14.5249 1.38489L8.41472 7.00806L2.29995 1.38063L2.29151 1.37286L2.28271 1.36548C1.93092 1.07036 1.38469 1.06804 1.03129 1.41393L1.01755 1.42738L1.00488 1.44184C0.69687 1.79355 0.695778 2.34549 1.0545 2.69659L1.05999 2.70196L1.06565 2.70717L7.28687 8.43257Z"
147
+ fill="#3056D3"
148
+ stroke="#3056D3"
149
+ />
150
+ </svg>
151
+ </div>
152
+ <div class="w-full">
153
+ <h4 class="text-lg font-semibold text-black">How long we deliver your first blog post?</h4>
154
+ </div>
155
+ </button>
156
+ <div x-show="openFaq6" class="faq-content pl-[62px]">
157
+ <p class="text-base text-body-color leading-relaxed py-3">
158
+ It takes 2-3 weeks to get your first blog post ready. That includes the in-depth research & creation of
159
+ your monthly content marketing strategy that we do before writing your first blog post, Ipsum available .
160
+ </p>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ <div class="absolute bottom-0 right-0 z-[-1]">
167
+ <svg width="1440" height="886" viewBox="0 0 1440 886" fill="none" xmlns="http://www.w3.org/2000/svg">
168
+ <path
169
+ opacity="0.5"
170
+ d="M193.307 -273.321L1480.87 1014.24L1121.85 1373.26C1121.85 1373.26 731.745 983.231 478.513 729.927C225.976 477.317 -165.714 85.6993 -165.714 85.6993L193.307 -273.321Z"
171
+ fill="url(#paint0_linear)"
172
+ />
173
+ <defs>
174
+ <linearGradient
175
+ id="paint0_linear"
176
+ x1="1308.65"
177
+ y1="1142.58"
178
+ x2="602.827"
179
+ y2="-418.681"
180
+ gradientUnits="userSpaceOnUse"
181
+ >
182
+ <stop stop-color="#3056D3" stop-opacity="0.36" />
183
+ <stop offset="1" stop-color="#F5F2FD" stop-opacity="0" />
184
+ <stop offset="1" stop-color="#F5F2FD" stop-opacity="0.096144" />
185
+ </linearGradient>
186
+ </defs>
187
+ </svg>
188
+ </div>
189
+ </section>