1import { _ as E } from "./BaseStepper-D0zmqV0f.js"; 2import { _ as O, a as R, b as $ } from "./ServicePricingDetails-CX6H_GxJ.js"; 3import { u as j } from "./modelWrapper-BuMWMt6a.js"; 4import { j as q, o as h, c as g, e as l, f as v, u as r, d as T, t as y, a as s, F as I, r as D, C as k, i as U, N as L, b as M, J as V, k as z, K as G, l as J, y as m, z as K, x as W, n as Y, s as H, G as Q, q as X, g as Z } from "./app-BQglH-tG.js"; 5import { aS as ee, aT as te } from "./vue-tabler-icons.es-_MpZvCnK.js"; 6import { b as re } from "./consts-CUuEXtFB.js"; 7import { k as B, O as oe, E as ie, h as se } from "./radio-group-F9iT_Js4.js"; 8import { o as ae } from "./floating-ui.dom-tFJD6lOc.js"; 9import { u as ne } from "./useShepherdTour-CMJ_EriZ.js"; 10import { _ as le } from "./DashboardLayout-SjMKBVdQ.js"; 11import { k as ce, l as me, p as ue } from "./functions-DNMBuN0o.js"; 12import "./FormFooter-cMftLzxe.js"; 13import "./CheckIcon-pbR60zuN.js"; 14import "./BaseInput-1l26qd8j.js"; 15import "./TipTapEditor-Bog43iYj.js"; 16import "./index-B6o3v9Fz.js"; 17import "./popover-Blq397Xu.js"; 18import "./ModalConfirmation-DER2JDFV.js"; 19import "./LoaderIcon-BOkmnW5w.js"; 20import "./_plugin-vue_export-helper-DlAUqK2U.js"; 21import "./UserAvatar-Boyff1w9.js"; 22import "./TextareaEditable-C8CmIcMt.js"; 23import "./OrderField-D5hnYOp4.js"; 24import "./BaseButton-BF1tDvcc.js"; 25import "./BaseCounterButton-N9n2yc5e.js"; 26import "./MinusIcon-CxLG0C3a.js"; 27import "./PlusIcon-D3gltrOV.js"; 28import "./ServiceImage-BGqAo4MG.js"; 29import "./FileGroupField-ZXh_55WX.js"; 30import "./InputError-BlVrgZq_.js"; 31import "./CopyElement-ogy8d-WE.js"; 32import "./menu-DtABgxi1.js"; 33import "./use-text-value-CY-cTGmG.js"; 34import "./use-tree-walker-BR_K-2Kt.js"; 35import "./PencilIcon-DFjPMjmw.js"; 36import "./TrashIcon-Jdvm91L_.js"; 37import "./useFileUploads-BrZAO7RA.js"; 38import "./filesystem-dsA_mKt9.js"; 39import "./DatePicker-DWXQPHoH.js"; 40import "./BaseListbox-CWI9LspK.js"; 41import "./listbox--4vAmvqx.js"; 42import "./form-BicfoI4A.js"; 43import "./ChevronDownIcon-CtpQP63k.js"; 44import "./disclosure-CSRQx-WH.js"; 45import "./FileDragAndDrop-DZJ_5Jh2.js"; 46import "./FileProgress-ByaG9u8c.js"; 47import "./vue-transitions-CEGBwb15.js"; 48import "./ImageUpload-1y0MZlz8.js"; 49import "./CameraIcon-DGGvJsLb.js"; 50import "./FilterDropdown-iO0ZQ_2Z.js"; 51import "./LiveChat-Cv9P2dP9.js"; 52import "./XMarkIcon-JhKzQL4a.js"; 53import "./ApplicationLogo-BE-OKeyv.js"; 54import "./index-CQ6xcn9I.js"; 55import "./FilterOrderOptions-Dm9YydYS.js"; 56import "./EyeIcon-CRkgYch_.js"; 57import "./ArrowUpTrayIcon-BtBAo4SI.js"; 58import "./FilterRangeInput-Cjg_anRe.js"; 59import "./LinkDomainMiniTable-D4YeRbXb.js"; 60import "./ShowMoreWithNumber-zOBiU2Rj.js"; 61import "./ChevronUpDownIcon-sO2gdtzH.js"; 62import "./CheckIcon-BPYvfO2g.js"; 63import "./order-form-condition-lists-igaB_ncw.js"; 64import "./ArrowLongLeftIcon-CKSrkugp.js"; 65import "./sortable.esm-TXiFJmQw.js"; 66import "./order-form-bWtPSer5.js"; 67import "./ExtensionIconUpload-BGBEY1gA.js"; 68import "./PaperClipIcon-D-KhnEV6.js"; 69import "./ArrowsRightLeftIcon-DTdXpUBX.js"; 70import "./ServiceFormTitle-B2Y0qjAu.js"; 71import "./EyeIcon-2qi6jGlP.js"; 72import "./QuestionMarkCircleIcon-C-DsZbEB.js"; 73import "./CurrencyInput-DDy5H46y.js"; 74import "./ServiceBasedSelector-CIj64Od5.js"; 75import "./BaseModal-BE4aZshQ.js"; 76import "./HomeIcon-CD_D5QXU.js"; 77import "./ClockIcon-cut-dFbY.js"; 78const pe = { class: "mx-auto max-w-3xl px-4" }, de = { class: "w-a mt-4 grid grid-cols-1 gap-y-6 sm:grid-cols-2 sm:gap-x-4" }, fe = { class: "flex flex-1" }, ve = { class: "flex flex-col" }, _e = { class: "flex" }, he = { class: "mr-3 rounded-md bg-primary-600 p-1.5" }, xe = { class: "mt-4 flex justify-end" }, ye = { key: 0, class: "mt-1 text-sm text-red-500" }, ge = { __name: "ServiceTypeSelector", props: { modelValue: { type: [Object, String, Number], default: () => ({}) } }, emits: ["update:modelValue"], setup(u, { emit: t }) { 79 const c = j(u, t, "modelValue"), { t: e } = q(), b = [{ id: 1, title: e("One-off"), value: "one-off", description: e("Charged once for a fixed scope of work."), icon: ee }, { id: 2, title: e("Recurring"), value: "recurring", description: e("Billed every period as a
79subscription."), icon: te }]; 80 return (C, d) => (h(), g("div", pe, [l(r(se), { modelValue: r(c).type, "onUpdate:modelValue": d[0] || (d[0] = (n) => r(c).type = n) }, { default: v(() => [l(r(B), { class: "text-lg font-bold text-gray-900" }, { default: v(() => [T(y(r(e)("Service type")), 1)]), _: 1 }), s("div", de, [(h(), g(I, null, D(b, (n) => l(r(oe), { key: n.id, as: "template", value: n.value }, { default: v(({ checked: _, active: w }) => [s("div", { class: k([_ ? "border-transparent" : "border-gray-300", w ? "border-primary-500" : "", r(c).errors.type ? "border-red-500" : "", "relative cursor-pointer rounded-md border bg-white p-4 shadow-sm focus:outline-none"]) }, [s("span", fe, [s("span", ve, [s("div", _e, [s("div", null, [s("div", he, [(h(), U(L(n.icon), { class: "h-6 w-6 text-white", "aria-hidden": "true" }))])]), s("div", null, [l(r(B), { as: "span", class: "block text-sm font-medium text-gray-900" }, { default: v(() => [T(y(n.title), 1)]), _: 2 }, 1024), l(r(ie), { as: "span", class: "mt-1 flex items-center whitespace-normal break-words text-sm text-gray-500" }, { default: v(() => [T(y(n.description), 1)]), _: 2 }, 1024)])])])]), s("div", xe, [l(r(re), { class: k([_ ? "" : "invisible", "h-5 w-5 text-primary-600"]), "aria-hidden": "true" }, null, 8, ["class"])]), s("span", { class: k([_ ? "border-primary-500" : "border-transparent", "pointer-events-none absolute -inset-px rounded-md border"]), "aria-hidden": "true" }, null, 2)], 2)]), _: 2 }, 1032, ["value"])), 64))]), r(c).errors.type ? (h(), g("p", ye, y(r(c).errors.type), 1)) : M("", true)]), _: 1 }, 8, ["modelValue"])])); 81} }; 82function be(u) { 83 const { t } = q(), { initTour: p } = ne(); 84 return { startPricingTour: () => { 85 const e = p(); 86 e.addStep({ id: "service-option-default", attachTo: { element: ".service-option-default", on: "bottom" }, title: t("Flexible service packages"), text: t("Standard services let clients submit a set number of requests. You can make them one-time or recurring\u2014perfect for predictable workflows!"), buttons: [{ text: t("Next"), action: () => { 87 u.based = "timed", V(() => { 88 e.next(); 89 }); 90 } }] }), e.addStep({ id: "service-option-timed", attachTo: { element: ".service-option-timed", on: "bottom" }, title: t("Track time"), text: t("Time-based services allow you to allocate a set number of hours per client. Ideal for hourly work, consulting, or flexible projects."), buttons: [{ text: t("Next"), action: () => { 91 e.next(); 92 } }] }), e.addStep({ id: "service-option-timed-hours", attachTo: { element: "#hours", on: "bottom" }, title: t("Included hours"), text: t("Enter the total hours this service provides. Clients can use these hours for requests until they run out."), buttons: [{ text: t("Next"), action: () => { 93 u.based = "credit", V(() => { 94 e.next(); 95 }); 96 } }] }), e.addStep({ id: "service-option-credit", attachTo: { element: ".service-option-credit", on: "bottom" }, title: t("Credits"), text: t("Clients purchase credits they can spend across services. A simple way to offer on-demand work while keeping usage under control."), buttons: [{ text: t("Next"), action: () => { 97 e.next(); 98 } }] }), e.addStep({ id: "service-option-credit-credits", attachTo: { element: "#credits", on: "bottom" }, title: t("Credit allocation"), text: t("Specify how many credits clients receive with this service. They'll use these credits to request work based on your pricing model."), buttons: [{ text: t("Next"), action: () => { 99 u.based = "default", e.next(); 100 } }], floatingUIOptions: { middleware: [ae({ mainAxis: 24, crossAxis: 0 })] } }), e.on("complete", () => { 101 localStorage.setItem("service-pricing-tour", "completed"); 102 }), e.start(); 103 }, startRequestFormTour: () => { 104 const e = p(); 105 e.addStep({ id: "request-form-add-item", attachTo: { element: "#add-item", on: "top" }, scrollTo: { behavior: "smooth" }, title: t("Build your request form"), text: t('This is where clients submit their orders. Click "Add item" to add the fields you need \u2014 files, text, dropdowns and more.'), buttons: [{ text: t("Next"), action: () => { 106 e.next(); 107 } }] }), e.addStep({ id: "request-form-preview", attachTo: { element: "#preview-button", on: "left" }, scrollTo: { behavior: "smooth" }, title: t("Preview before you share"), text: t("Click 'Preview' to view your request form as your clients will see it. Make sure everything looks just right before going live."), buttons: [{ text: t("Next"), action: () => { 108 e.next(); 109 } }], when: { isOpen: () => { 110 window.scrollTo(0, 0); 111 } } }), e.addStep({ id: "request-form-menu", attachTo: { element: "#menu-button", on: "right" }, title: t("Templates"), text: t("Save this form as a template for future use, or manage existing templates to streamline your workflow."), buttons: [{ text: t("Next"), action: () => { 112 e.next(); 113 } }] }), e.addStep({ id: "request-form-conditions", attachTo: { element: "#conditions", on: "left" }, title: t("Conditional logic"), text: t("Use conditional logic to show or hide fields based on client responses\u2014keeping forms clean and relevant."), buttons: [{ text: t("Next"), action: () => { 114 e.next(); 115 } }] }), e.on("complete", () => { 116 localStorage.setItem("request-form-tour", "completed"); 117 }), e.start(); 118 } }; 119} 120const Kt = { __name: "ServiceCreate", props: { serviceType: { type: String, required: false, default: null }, periods: { type: Array, required: true }, currency: { type: String, required: true }, defaultFieldType: { type: String, required: true }, intakeFormTemplates: { type: Array, required: true }, recurringServices: { type: Array, default: () => [] } }, setup(u) { 121 const t = u, p = Q(); 122 z(() => { 123 ce(), t.serviceType && (e.type = t.serviceType, p.value.goForward()); 124 }), G(() => me()); 125 const { t: a } = q(), c = [{ label: a("Services"), url: route("services.index") }, { label: a("Create") }], e = J({ service_id: null, type: "one-off", name: null, description: null, price: null, hours: null, credits: null, variations: [{ price: null, billing_period_id: null }], max_requests_per_month: null, max_concurrent_requests: null, allocation: "fixed", allowed_requests: 1, purchase_limit: null, image: {}, form_fields: [], conditions: [], title_label: null, title_placeholder: null, intake_form_templates: t.intakeFormTemplates, has_trial: false, timed_service: false, credited_service: false, trial: { price: null, interval: "day", interval_count: null }, based: "default", set_as_default: false, rollover_enabled: false, rollover_months: null, allow_period_changes: false, allowed_swap_service_ids: [], allowed_swap_variation_ids: [], require_request_on_checkout: true, allow_quantity_selection: true, setup_fee_enabled: false, setup_fee: null }), b = [{ name: a("Service type"), component: ge }, { name: a("Service details"), component: O, validate: async () => await new Promise((o, i) => { 126 e.transform((f) =>
126 m.omitBy({ ...f, image: d() }, m.isNil)).post(route("service.second-step.validate"), { onSuccess: () => o(true), onError: () => i(false) }); 127 }) }, { name: a("Pricing details"), component: R, props: { periods: t.periods, currency: t.currency, recurringServices: t.recurringServices }, validate: async () => await new Promise((o, i) => { 128 let f = route("services.store"), N = "post"; 129 e.service_id && (f = route("services.update", e.service_id), N = "put"), e.transform((x) => m.omitBy({ ...x, draft: true, image: d(), has_trial: e.type === "one-off" ? false : x.has_trial }, m.isNil)).submit(N, f, { resetOnSuccess: false, onSuccess: (x) => { 130 const S = x.props.flash.service; 131 e.service_id = S.id, e.form_fields = S.form_fields, e.variations = S.pricing_variations.map((F) => ({ ...F, price: ue(F.price, t.currency) })), o(true); 132 }, onError: () => i(false) }); 133 }) }, { name: a("Request form"), component: $, props: { defaultFieldType: t.defaultFieldType } }], C = Z(() => !!e.type && !!e.name && !!e.description), d = () => e.image.key && e.image.uuid && e.image.extension ? { extension: e.image.extension, uuid: e.image.uuid, key: e.image.key, name: e.image.name } : null, n = () => { 134 const o = (i) => m.omitBy({ ...i, draft: true, image: d(), redirect_to_index: true, variations: e.type === "one-off" ? [] : i.variations, has_trial: e.type === "one-off" ? false : i.has_trial }, m.isNil); 135 e.service_id ? e.transform(o).put(route("services.update", e.service_id), { preserveScroll: true }) : e.transform(o).post(route("services.store"), { preserveScroll: true }); 136 }, _ = () => e.transform((o) =>
136 m.omitBy({ ...o, draft: false, image: d(), redirect_to_index: true, variations: e.type === "one-off" ? [] : o.variations, has_trial: e.type === "one-off" ? false : o.has_trial }, m.isNil)).put(route("services.update", e.service_id)), w = () => X.get(route("services.index")), { startPricingTour: P, startRequestFormTour: A } = be(e); 137 return K(() => { 138 var _a; 139 return (_a = p.value) == null ? void 0 : _a.currentStep; 140 }, (o) => { 141 var _a; 142 const i = ((_a = W().props.gettingStarted) == null ? void 0 : _a.services) === false; 143 o === 2 && !localStorage.getItem("service-pricing-tour") && i && setTimeout(P, 200), o === 3 && !localStorage.getItem("request-form-tour") && i && setTimeout(A, 200); 144 }), (o, i) => (h(), g(I, null, [l(r(Y), { title: r(a)("Create service") }, null, 8, ["title"]), l(le, { breadcrumbs: c, "show-footer": false }, { default: v(() => [l(E, { ref_key: "stepper", ref: p, modelValue: r(e), "onUpdate:modelValue": i[0] || (i[0] = (f) => H(e) ? e.value = f : null), steps: b, "show-secondary-btn": C.value, "validate-go-back": false, "content-classes": "min-h-[calc(100vh-13rem)]", onFinish: _, onExit: w, onSecondaryAction: n }, null, 8, ["modelValue", "show-secondary-btn"])]), _: 1 })], 64)); 145} }; 146export { 147 Kt as default 148};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.