File: /home/xedaptot/ai.naniguide.com/app/Http/Controllers/Refactor/FunnelStepController.php
<?php
namespace App\Http\Controllers\Refactor;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Model\Funnel;
use App\Model\FunnelStep;
use App\Model\FunnelStepTemplate;
use App\Model\Template;
class FunnelStepController extends Controller
{
public function create(Request $request, $funnelUid)
{
$funnel = Funnel::ofCustomer($request->user()->customer)
->notTemplate()
->where('uid', $funnelUid)->first();
if (!$funnel) {
return $this->notAuthorized();
}
$stepTypes = FunnelStep::stepTypes();
return view('refactor.pages.funnels.steps.create', [
'funnel' => $funnel,
'stepTypes' => $stepTypes,
]);
}
public function templatesByTag(Request $request)
{
$tag = $request->tag;
$templates = FunnelStepTemplate::query();
if ($tag) {
$templates->byTag($tag);
}
return view('refactor.pages.funnels.steps._templates', [
'templates' => $templates->get(),
]);
}
public function store(Request $request, $funnelUid)
{
$funnel = Funnel::ofCustomer($request->user()->customer)
->notTemplate()
->where('uid', $funnelUid)->first();
if (!$funnel) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
$step = new FunnelStep();
$step->funnel_id = $funnel->id;
$step->sort_order = $funnel->steps()->count();
$validator = $step->saveFromParams($request->all());
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'errors' => $validator->errors()->toArray(),
], 422);
}
// Apply step template if selected
if ($request->template_uid) {
$stepTemplate = FunnelStepTemplate::findByUid($request->template_uid);
if ($stepTemplate && $stepTemplate->template) {
$step->setTemplate($stepTemplate->template, $step->name);
}
}
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.flash.step_created'),
]);
}
public function edit(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return $this->notAuthorized();
}
return view('refactor.pages.funnels.steps.edit', [
'step' => $step,
'funnel' => $step->funnel,
]);
}
public function update(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
$validator = $step->saveFromParams($request->all());
if ($validator->fails()) {
return response()->json([
'status' => 'error',
'errors' => $validator->errors()->toArray(),
], 422);
}
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.flash.step_updated'),
]);
}
/**
* Step 2: Template — show assigned template card + gallery prompt.
*/
public function template(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return $this->notAuthorized();
}
return view('refactor.pages.funnels.steps.template', [
'step' => $step,
'funnel' => $step->funnel,
]);
}
/**
* Template gallery — AJAX paginated template thumbnails.
* Tab "system" → FunnelStepTemplate filtered by step type.
* Tab "mine" → customer's builder templates (CustomerEmailTemplate).
*/
public function templateGallery(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return $this->notAuthorized();
}
$customer = $request->user()->customer;
if ($request->from === 'mine') {
$templates = $customer->customerEmailTemplates()
->orderBy('created_at', 'desc')
->paginate(12);
} else {
$templates = FunnelStepTemplate::query()
->byTag($step->type)
->orderBy('id', 'asc')
->paginate(12);
}
return view('refactor.pages.funnels.steps._template_gallery', [
'step' => $step,
'templates' => $templates,
]);
}
/**
* Choose a template — AJAX POST. Clones template and assigns to step.
*/
public function templateChoose(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
// Try user template first, then funnel step template
$template = Template::findByUid($request->template_uid);
if (!$template) {
$stepTemplate = FunnelStepTemplate::findByUid($request->template_uid);
if ($stepTemplate) {
$template = $stepTemplate->template;
}
}
// Also accept CustomerEmailTemplate wrappers
if (!$template) {
$customerTemplate = \App\Model\CustomerEmailTemplate::findByUid($request->template_uid);
if ($customerTemplate) {
$template = $customerTemplate->template;
}
}
if (!$template) {
return response()->json([
'status' => 'error',
'message' => trans('refactor/funnels.wizard.template_not_found'),
], 404);
}
$step->setTemplate($template, $step->name);
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.wizard.template_selected'),
'redirect' => route('refactor.funnels.step_template', $step->uid),
]);
}
/**
* Remove the step template — AJAX POST.
*/
public function templateRemove(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
$step->removeTemplate();
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.wizard.template_removed'),
]);
}
/**
* Preview the step's rendered page — returns raw HTML for iframe/new tab.
*/
public function preview(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return $this->notAuthorized();
}
if (!$step->hasTemplate()) {
return response(
'<!doctype html><meta charset="utf-8"><title>' . e($step->name) . '</title>'
. '<body style="font:14px system-ui;color:#666;padding:40px;text-align:center">'
. e(trans('refactor/funnels.wizard.template_not_found'))
. '</body>'
);
}
return response($step->template->getPreviewContent());
}
/**
* BuilderJS visual editor.
* GET → render builder shell (redirect to template picker if no template).
* POST → save content + json from builder.
*/
public function builder(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
if ($request->isMethod('post')) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
return $this->notAuthorized();
}
if ($request->isMethod('post')) {
$rules = [
'content' => 'required',
'json' => 'required',
];
$validator = \Validator::make($request->all(), $rules);
if ($validator->fails()) {
return response()->json([
'message' => $validator->errors()->first(),
], 400);
}
$step->setTemplateContent($request->content, $request->json);
return response()->json(['status' => 'success']);
}
// Must have a template before entering the builder
if (!$step->hasTemplate()) {
return redirect()->route('refactor.funnels.step_template', $step->uid);
}
return view('refactor.pages.funnels.steps.builder', [
'step' => $step,
'funnel' => $step->funnel,
'template' => $step->template,
'templates' => $request->user()->customer->getBuilderTemplates(),
'list' => $step->funnel->mailList,
]);
}
public function reorder(Request $request, $funnelUid)
{
$funnel = Funnel::ofCustomer($request->user()->customer)
->notTemplate()
->where('uid', $funnelUid)->first();
if (!$funnel) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
$order = $request->order; // array of step UIDs in order
if (is_array($order)) {
foreach ($order as $index => $stepUid) {
FunnelStep::where('funnel_id', $funnel->id)
->where('uid', $stepUid)
->update(['sort_order' => $index]);
}
}
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.flash.reordered'),
]);
}
public function duplicate(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
$step->duplicateTo($step->funnel);
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.flash.step_duplicated'),
]);
}
public function delete(Request $request, $uid)
{
$step = FunnelStep::findByUid($uid);
if (!$step || $step->funnel->customer_id !== $request->user()->customer->id) {
return response()->json(['status' => 'error', 'message' => 'Not found'], 404);
}
$step->deleteAndCleanup();
return response()->json([
'status' => 'success',
'message' => trans('refactor/funnels.flash.step_deleted'),
]);
}
}