mirror of
https://github.com/czhu12/canine.git
synced 2025-12-30 07:39:43 -06:00
onboarding
This commit is contained in:
4
TODO.md
4
TODO.md
@@ -16,4 +16,6 @@
|
||||
- [ ] Pull request preview apps
|
||||
- [ ] Update vocabulary on landing page
|
||||
- [ ] Clear our historical logs
|
||||
- [ ] log drain from application
|
||||
- [ ] log drain from application
|
||||
- [ ] clean this up - celina - app/controllers/local/pages_controller.rb
|
||||
|
||||
|
||||
5
app/controllers/local/onboarding_controller.rb
Normal file
5
app/controllers/local/onboarding_controller.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class Local::OnboardingController < ApplicationController
|
||||
layout "onboarding"
|
||||
def index
|
||||
end
|
||||
end
|
||||
@@ -36,13 +36,17 @@ class Local::PagesController < ApplicationController
|
||||
|
||||
def update_portainer_configuration
|
||||
stack_manager = current_account.stack_manager || current_account.build_stack_manager
|
||||
stack_manager.update!(provider_url: params[:provider_url])
|
||||
result = Portainer::Authenticate.execute(stack_manager:, user: current_user, auth_code: params[:password], username: params[:username])
|
||||
if result.success?
|
||||
flash[:notice] = "The Portainer configuration has been updated"
|
||||
else
|
||||
flash[:error] = result.message
|
||||
stack_manager.update!(provider_url: params[:stack_manager][:provider_url])
|
||||
# TODO: clean this up - celina
|
||||
if params[:password].present? && params[:username].present?
|
||||
result = Portainer::Authenticate.execute(stack_manager:, user: current_user, auth_code: params[:password], username: params[:username])
|
||||
if result.success?
|
||||
flash[:notice] = "The Portainer configuration has been updated"
|
||||
else
|
||||
flash[:error] = result.message
|
||||
end
|
||||
end
|
||||
flash[:notice] = "The Portainer configuration has been updated"
|
||||
redirect_to root_path
|
||||
end
|
||||
|
||||
|
||||
55
app/javascript/controllers/onboarding_controller.js
Normal file
55
app/javascript/controllers/onboarding_controller.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import { Controller } from "@hotwired/stimulus"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = [ "stepHeader", "portainerUrlForm", "githubForm", "step"]
|
||||
static values = {
|
||||
currentStep: Number
|
||||
}
|
||||
|
||||
|
||||
connect() {
|
||||
this.currentStepValue = 0
|
||||
this.activeClass = "step-primary"
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
}
|
||||
|
||||
next() {
|
||||
if (this.currentStepValue == 1) {
|
||||
this.submit(this.portainerUrlFormTarget)
|
||||
}
|
||||
if (this.currentStepValue == 2) {
|
||||
this.submit(this.githubFormTarget)
|
||||
}
|
||||
if (this.currentStepValue < 2) {
|
||||
this.currentStepValue++
|
||||
this.stepHeaderTargets.forEach(step => step.classList.remove(this.activeClass))
|
||||
this.stepHeaderTargets[this.currentStepValue].classList.add(this.activeClass)
|
||||
this.stepTargets.forEach(step => step.classList.add("hidden"))
|
||||
this.stepTargets[this.currentStepValue].classList.remove("hidden")
|
||||
}
|
||||
}
|
||||
|
||||
submit(target) {
|
||||
const formData = new FormData(target)
|
||||
|
||||
fetch(target.action, {
|
||||
method: 'PUT',
|
||||
body: formData,
|
||||
headers: {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'X-CSRF-Token': document.querySelector('[name="csrf-token"]').content
|
||||
}
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Handle success - maybe show next step or success message
|
||||
console.log('Success:', data)
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
21
app/views/layouts/onboarding.html.erb
Normal file
21
app/views/layouts/onboarding.html.erb
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html class="h-full antialiased dark" data-theme="dark" lang="en">
|
||||
<head>
|
||||
<%= render 'shared/head' %>
|
||||
</head>
|
||||
|
||||
<body data-controller="theme" data-theme-preference-value="dark">
|
||||
<div class="size-full">
|
||||
<div class="flex">
|
||||
<main class="main-wrapper overflow-x-hidden overflow-y-auto">
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="content-wrapper max-w-full lg:max-w-3/4">
|
||||
<%= yield %>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
87
app/views/local/onboarding/index.html.erb
Normal file
87
app/views/local/onboarding/index.html.erb
Normal file
@@ -0,0 +1,87 @@
|
||||
<div class="min-h-screen py-8" data-controller="onboarding">
|
||||
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<!-- Header and Navigation -->
|
||||
<div class="mb-8">
|
||||
<h1 class="text-3xl font-bold ">
|
||||
Let's get your account set up
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<!-- Progress Indicator -->
|
||||
<div class="mb-8">
|
||||
<ul aria-label="Steps" role="group" class="steps overflow-auto w-full">
|
||||
<li aria-label="Step" class="step step-primary" data-onboarding-target="stepHeader">Choose Configuration</li>
|
||||
<li aria-label="Step" class="step" data-onboarding-target="stepHeader">Setup Configuration</li>
|
||||
<li aria-label="Step" class="step" data-onboarding-target="stepHeader">Additional Login</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Plan Options -->
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-8" data-onboarding-target="step">
|
||||
<!-- Starter Plan (Selected) -->
|
||||
<div class="border-2 border-green-500 rounded-lg p-6 bg-white dark:bg-gray-800 shadow-sm">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold dark:text-white">Local</h3>
|
||||
<p class="mt-1 dark:text-gray-300">Continue with default settings</p>
|
||||
</div>
|
||||
<div class="w-6 h-6 bg-green-500 rounded-full flex items-center justify-center">
|
||||
<svg class="w-4 h-4 text-white" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pro Plan -->
|
||||
<div class="border-2 rounded-lg p-6 bg-white dark:bg-gray-800 shadow-sm">
|
||||
<div class="flex items-start justify-between mb-4">
|
||||
<div>
|
||||
<h3 class="text-xl font-semibold dark:text-white">Portainer</h3>
|
||||
<p class="mt-1 dark:text-gray-300">Use Portainer to manage your containers</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Setup Configuration -->
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-8 hidden" data-onboarding-target="step">
|
||||
<%= form_with url: portainer_configuration_path, model: current_account.stack_manager, method: :put, data: { onboarding_target: "portainerUrlForm" } do |form| %>
|
||||
<div class="form-group">
|
||||
<%= form.label :provider_url, "Portainer URL" %>
|
||||
<%= form.text_field :provider_url, class: "input input-bordered w-full max-w-xs", placeholder: "http://portainer.portainer.svc.cluster.local:9000" %>
|
||||
<label class="label">
|
||||
<span class="label-text-alt">All data is saved locally and never sent to any external servers.</span>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="grid md:grid-cols-2 gap-6 mb-8 hidden" data-onboarding-target="step">
|
||||
<%= form_with url: portainer_configuration_path, model: current_account.stack_manager, method: :put, data: { onboarding_target: "githubForm" } do |form| %>
|
||||
<div class="form-group" data-controller="toggle-password">
|
||||
<%= form.label :username, "Username" %>
|
||||
<%= form.text_field :username, class: "input input-bordered w-full max-w-xs" %>
|
||||
</div>
|
||||
<div class="form-group" data-controller="toggle-password">
|
||||
<%= form.label :password, "Password" %>
|
||||
<%= form.text_field :password, type: "password", class: "input input-bordered w-full max-w-xs", data: { toggle_password_target: "input" } %>
|
||||
<button type="button" class="btn btn-outline" data-action="toggle-password#toggle">
|
||||
<iconify-icon icon="mdi:eye"></iconify-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="text-center"> or </div>
|
||||
<div>
|
||||
<%= link_to "Connect via Github", Git::Github::UrlHelper.authorize_url, class: "btn btn-primary" %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<!-- Call to Action -->
|
||||
<div class="text-center">
|
||||
<button class="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-3 px-8 rounded-lg text-lg transition-colors" data-action="click->onboarding#next">
|
||||
Next
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -116,6 +116,9 @@ Rails.application.routes.draw do
|
||||
get "/calculator", to: "static#calculator"
|
||||
# Public marketing homepage
|
||||
if Rails.application.config.local_mode
|
||||
namespace :local do
|
||||
resources :onboarding, only: [ :index ]
|
||||
end
|
||||
get "/github_token", to: "local/pages#github_token"
|
||||
put "/github_token", to: "local/pages#update_github_token"
|
||||
get "/portainer_configuration", to: "local/pages#portainer_configuration"
|
||||
|
||||
Reference in New Issue
Block a user