From 26959563e5b30161a88ef0d74079a8a607cf0017 Mon Sep 17 00:00:00 2001 From: Sean Hatfield <seanhatfield5@gmail.com> Date: Mon, 12 Aug 2024 11:49:53 -0700 Subject: [PATCH] Finetune ui improvements (#2053) * WIP finetune ui improvements * lint * update order details page finetuning ui * data upload, confirmation, and order placed finetune ui update * update finetune layout * remove unneeded imports * uncomment url * confirmation and data upload component ui updates * finetun main container layout fix --- .../FineTuning/Steps/Confirmation/index.jsx | 167 ++++++++------- .../FineTuning/Steps/DataUpload/index.jsx | 191 +++++++++--------- .../Steps/FulfillmentPolicy/index.jsx | 88 ++++---- .../FineTuning/Steps/Introduction/index.jsx | 75 +++---- .../FineTuning/Steps/OrderDetails/index.jsx | 120 ++++++----- .../FineTuning/Steps/OrderPlaced/index.jsx | 98 +++++---- .../pages/FineTuning/Steps/Privacy/index.jsx | 148 +++++++------- .../Steps/TermsAndConditions/index.jsx | 119 +++++------ frontend/src/pages/FineTuning/Steps/index.jsx | 18 +- frontend/src/pages/FineTuning/index.jsx | 34 ++-- 10 files changed, 540 insertions(+), 518 deletions(-) diff --git a/frontend/src/pages/FineTuning/Steps/Confirmation/index.jsx b/frontend/src/pages/FineTuning/Steps/Confirmation/index.jsx index acf4b4091..cfb8d9709 100644 --- a/frontend/src/pages/FineTuning/Steps/Confirmation/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/Confirmation/index.jsx @@ -1,9 +1,11 @@ import FineTuning from "@/models/experimental/fineTuning"; import { dollarFormat } from "@/utils/numbers"; import showToast from "@/utils/toast"; -import { CheckCircle } from "@phosphor-icons/react"; -import { useState } from "react"; +import { Check } from "@phosphor-icons/react"; +import { useState, useEffect } from "react"; import FineTuningSteps from "../index"; +import CTAButton from "@/components/lib/CTAButton"; +import Workspace from "@/models/workspace"; /** * @param {{settings: import("../index").OrderSettings}} param0 @@ -11,6 +13,18 @@ import FineTuningSteps from "../index"; */ export default function Confirmation({ settings, setSettings, setStep }) { const [loading, setLoading] = useState(false); + const [workspaces, setWorkspaces] = useState([]); + + useEffect(() => { + Workspace.all() + .then((fetchedWorkspaces) => { + setWorkspaces(fetchedWorkspaces); + }) + .catch(() => { + showToast("Failed to fetch workspaces", "error"); + }); + }, []); + async function handleCheckout() { setLoading(true); const data = await FineTuning.createOrder({ @@ -40,107 +54,124 @@ export default function Confirmation({ settings, setSettings, setStep }) { setStep(FineTuningSteps.confirmation.next()); } + const getWorkspaceName = (slug) => { + const workspace = workspaces.find((ws) => ws.slug === slug); + return workspace ? workspace.name : slug; + }; + return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4 flex flex-col justify-between"> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold">Confirm & Submit</h2> - <p> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-3 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> + Confirm & Submit + </h2> + <p className="text-white/80 text-sm"> Below are your fine-tuning order details. If you have any questions - before or after ordering your fine-tune you can{" "} + before or after ordering your fine-tune you can checkout the{" "} <a href="https://docs.useanything.com/fine-tuning/overview" target="_blank" - className="underline" + rel="noreferrer" + className="underline text-sky-400" > - checkout the fine-tuning FAQ + fine-tuning FAQ </a>{" "} or email{" "} - <a className="underline" href="mailto:team@mintplexlabs.com"> + <a + className="underline text-sky-400" + href="mailto:team@mintplexlabs.com" + > team@mintplexlabs.com </a> . </p> - <div className="p-2 bg-zinc-800 text-white font-mono flex flex-col gap-y-2 h-full rounded-lg"> - <div className="flex items-center gap-x-1 text-sm"> - <p className="">Contact e-mail:</p> - <p className="font-thin">{settings.email}</p> - </div> - <div className="flex items-center gap-x-1 text-sm"> - <p className="">Base LLM:</p> - <p className="font-thin">{settings.baseModel}</p> - </div> - <div className="flex items-center gap-x-1 text-sm"> - <p className="">Output model name:</p> - <p className="font-thin">"{settings.modelName}"</p> - </div> - <div className="flex flex-col gap-y-1 text-sm"> - <div className="flex items-center gap-x-1"> - <p className="">Training on workspaces:</p> - {settings.trainingData.slugs.map((slug, i) => { - return ( - <p key={slug} className="font-thin"> - "{slug}" - {i !== settings.trainingData.slugs.length - 1 ? "," : ""} - </p> - ); - })} + <div className="p-4 bg-zinc-900 text-white flex flex-col gap-y-2 rounded-lg mt-4"> + <div className="flex flex-col gap-y-3 text-sm"> + <div className="flex items-start gap-x-1"> + <p className="w-1/3">Contact e-mail:</p> + <p className="text-white/80 w-2/3">{settings.email}</p> </div> - {settings.trainingData.feedback === true ? ( - <p className="underline"> - training on <b>positive-feedback chats only</b>. - </p> - ) : ( - <p className="underline"> - training on <b>all chats</b>. + <div className="flex items-start gap-x-1"> + <p className="w-1/3">Base LLM:</p> + <p className="text-white/80 w-2/3">{settings.baseModel}</p> + </div> + <div className="flex items-start gap-x-1"> + <p className="w-1/3">Output model name:</p> + <p className="text-white/80 w-2/3">"{settings.modelName}"</p> + </div> + <div className="flex items-start gap-x-1"> + <p className="w-1/3">Training on workspaces:</p> + <div className="text-white/80 w-2/3 flex flex-wrap gap-1"> + {settings.trainingData.slugs.map((slug, i) => ( + <span + key={slug} + className={`rounded-full bg-white/10 px-2 py-0.5 h-[20px] text-xs font-medium text-white shadow-sm`} + > + {getWorkspaceName(slug)} + </span> + ))} + </div> + </div> + <div className="flex items-start gap-x-1"> + <p className="w-1/3">Training data:</p> + <p className="text-white/80 w-2/3"> + {settings.trainingData.feedback === true + ? "Training on positive-feedback chats only" + : "Training on all chats"} </p> - )} + </div> </div> - <br /> - <div className="flex items-center gap-x-1 text-sm"> - <CheckCircle className="text-green-300" /> - <p className="font-thin">Agreed to Terms and Conditions</p> - </div> - <div className="flex items-center gap-x-1 text-sm"> - <CheckCircle className="text-green-300" /> - <p className="font-thin">Understand privacy & data handling</p> - </div> - <div className="flex items-center gap-x-1 text-sm"> - <CheckCircle className="text-green-300" /> - <p className="font-thin">Agreed to Fulfillment terms</p> + <div className="mt-4"> + <ul className="flex flex-col gap-y-1 text-sm"> + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" /> + <p className="text-white/80"> + Agreed to Terms and Conditions + </p> + </li> + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" /> + <p className="text-white/80"> + Understand privacy & data handling + </p> + </li> + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" /> + <p className="text-white/80">Agreed to Fulfillment terms</p> + </li> + </ul> </div> - <div> - <div className="flex items-center gap-x-1 text-lg border-t-[2px] border-white/40 pt-2 mb-0"> + <div className="mt-4 border-white/40 pt-2"> + <div className="flex items-center gap-x-1 text-lg mb-0"> <p className="">Total one-time cost:</p> - <p className="font-thin"> + <p className="text-white/80"> {dollarFormat(settings.tuningInfo.pricing.usd)} <sup>*</sup> </p> </div> - <p className="m-0 p-0 text-xs text-white/60 font-mono"> + <p className="m-0 p-0 text-xs text-white/60"> <sup>*</sup> price does not include any coupons, incentives, or discounts you can apply at checkout. </p> </div> </div> - <p> + <p className="text-xs text-white/80 mt-4"> Once you proceed to checkout, if you do not complete this purchase your data will be deleted from our servers within 1 hour of abandonment of the creation of the checkout in accordance to our privacy and data handling policy. </p> + <CTAButton + disabled={loading} + onClick={handleCheckout} + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + > + {loading ? "Generating order..." : "Start Training →"} + </CTAButton> </div> - - <button - disabled={loading} - onClick={handleCheckout} - type="button" - className="mt-8 w-full py-2 text-center text-black bg-white hover:bg-white/80 border-none rounded-lg" - > - {loading ? <>Generating order...</> : <>Start Training →</>} - </button> </div> </div> ); diff --git a/frontend/src/pages/FineTuning/Steps/DataUpload/index.jsx b/frontend/src/pages/FineTuning/Steps/DataUpload/index.jsx index d4cec7ea4..6a48d5911 100644 --- a/frontend/src/pages/FineTuning/Steps/DataUpload/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/DataUpload/index.jsx @@ -1,8 +1,14 @@ import { useEffect, useState } from "react"; import FineTuning from "@/models/experimental/fineTuning"; import Workspace from "@/models/workspace"; -import { CheckCircle, Warning, X } from "@phosphor-icons/react"; +import { + CheckCircle, + Warning, + X, + MagnifyingGlass, +} from "@phosphor-icons/react"; import FineTuningSteps from ".."; +import CTAButton from "@/components/lib/CTAButton"; export default function DataUpload({ setSettings, setStep }) { const [workspaces, setWorkspaces] = useState([]); @@ -41,34 +47,29 @@ export default function DataUpload({ setSettings, setStep }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <form - onSubmit={handleSubmit} - className="flex flex-col justify-between h-full" - > - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> - Select your training dataset. - </h2> - <p> - This is the data your model will be trained and tuned on. This is - a critical step and you should always train on the exact - information you want the model to inherit. By default, AnythingLLM - will use all chats, but you can filter chats by workspace and even - limit training to chats which users have left a positive feedback - indication on (thumbs up). - </p> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-3 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> + Select your training dataset + </h2> + <p className="text-white/80 text-sm"> + This is the data your model will be trained and tuned on. This is a + critical step and you should always train on the exact information + you want the model to inherit. By default, AnythingLLM will use all + chats, but you can filter chats by workspace and even limit training + to chats which users have left a positive feedback indication on + (thumbs up). + </p> - <div className="flex flex-col pr-10"> - <div className="flex flex-col gap-y-1 mb-4"> - <label className="text-white text-sm font-bold"> - Only use positive responses - </label> - <p className="text-xs font-normal text-white/80"> - Enabling this toggle will filter your dataset to only use - "positive" responses that were marked during chatting. - </p> - </div> + <form onSubmit={handleSubmit} className="flex flex-col gap-y-6 mt-4"> + <div className="flex flex-col"> + <label className="text-white text-sm font-semibold block mb-3"> + Only use positive responses + </label> + <p className="text-xs font-normal text-white/80 mb-2"> + Enabling this toggle will filter your dataset to only use + "positive" responses that were marked during chatting. + </p> <label className="relative inline-flex cursor-pointer items-center w-fit"> <input type="checkbox" @@ -84,34 +85,33 @@ export default function DataUpload({ setSettings, setStep }) { </label> </div> - <div className="flex flex-col pr-10"> - <div className="flex flex-col gap-y-1 mb-4"> - <label className="text-white text-sm font-bold"> - Selected Workspaces - </label> - <p className="text-xs font-normal text-white/80"> - You training data will be limited to these workspaces. - </p> - </div> + <div className="flex flex-col"> + <label className="text-white text-sm font-semibold block mb-3"> + Selected Workspaces + </label> + <p className="text-xs font-normal text-white/80 mb-2"> + Your training data will be limited to these workspaces. + </p> <WorkspaceSelector workspaces={workspaces} selectedWorkspaces={dataFilters.workspaces} setDataFilters={setDataFilters} /> </div> + <DatasetSummary workspaces={dataFilters.workspaces} feedback={dataFilters.feedback} /> - </div> - <button - type="submit" - className="mt-20 w-full py-2 text-center text-white hover:bg-primary-button border-none rounded-lg" - > - Proceed to Confirmation → - </button> - </form> + <CTAButton + type="submit" + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + > + Proceed to Confirmation → + </CTAButton> + </form> + </div> </div> </div> ); @@ -155,60 +155,59 @@ function WorkspaceSelector({ } return ( - <div className="flex flex-col items-center"> - <div className="w-full h-fit"> - <div className="w-full relative z-1"> - <div className="p-1 flex border border-white/40 bg-zinc-800 rounded"> - <div className="flex flex-auto flex-wrap"> - {selectedWorkspaces.map((workspace) => { - return ( - <div - key={workspace.slug} - className="flex gap-x-1 justify-center items-center m-1 font-medium py-1 px-2 bg-zinc-800 rounded-full text-white/40 bg-white/10 border border-white/40 " - > - <div className="text-xs font-normal text-white leading-none max-w-full flex-initial"> - {workspace.name} - </div> - <div className="flex flex-auto flex-row-reverse"> + <div className="flex flex-col gap-y-2"> + <div className="min-w-[150px] max-w-[300px] h-[32px] p-[10px] rounded-lg flex items-center bg-dark-highlight mt-1"> + <MagnifyingGlass size={16} className="text-white" /> + <input + value={query} + onChange={(e) => setQuery(e.target.value)} + onFocus={() => setShowSuggestions(true)} + onBlur={() => + setTimeout(() => { + setShowSuggestions(false); + }, 500) + } + placeholder="Enter a workspace name" + className="bg-transparent p-1 px-2 appearance-none outline-none h-full w-full text-white text-xs placeholder:`text-white/50`" + /> + </div> + <div className="flex flex-col items-center -ml-2"> + <div className="w-full h-fit"> + <div className="w-full relative z-1"> + <div className="p-2 flex rounded-lg"> + <div className="flex flex-wrap gap-2 w-full"> + {selectedWorkspaces.map((workspace) => { + return ( + <div + key={workspace.slug} + className="flex items-center justify-between rounded-full h-[20px] bg-white/10 px-2 py-1 text-xs font-medium text-white shadow-sm" + > + <span className="truncate mr-1">{workspace.name}</span> <button onClick={() => handleRemoveWorkspace(workspace)} type="button" - className="hover:text-red-500" + className="hover:text-red-500 flex-shrink-0" > - <X size={14} weight="bold" /> + <X size={10} weight="bold" /> </button> </div> - </div> - ); - })} - <div className="flex-1"> - <input - value={query} - onChange={(e) => setQuery(e.target.value)} - onFocus={() => setShowSuggestions(true)} - onBlur={() => - setTimeout(() => { - setShowSuggestions(false); - }, 500) - } - placeholder="Enter a workspace name" - className="w-[200px] bg-transparent p-1 px-2 appearance-none outline-none h-full w-full text-white" - /> + ); + })} </div> </div> </div> - </div> - {showSuggestions && ( - <div className="w-full flex relative"> - <div className="w-full absolute top-0 z-20"> - <WorkspaceSuggestions - availableWorkspaces={availableWorkspaces} - addWorkspace={handleAddWorkspace} - query={query} - /> + {showSuggestions && ( + <div className="w-full flex relative"> + <div className="w-full absolute top-0 z-20"> + <WorkspaceSuggestions + availableWorkspaces={availableWorkspaces} + addWorkspace={handleAddWorkspace} + query={query} + /> + </div> </div> - </div> - )} + )} + </div> </div> </div> ); @@ -221,7 +220,7 @@ function WorkspaceSuggestions({ }) { if (availableWorkspaces.length === 0) { return ( - <div className="w-full mt-[2px] bg-zinc-800 border border-white/40 top-[45px] h-40 rounded-lg p-2 text-sm"> + <div className="w-full mt-[2px] bg-zinc-900 top-[45px] h-40 rounded-lg p-2 text-sm"> <p className="text-center text-white/40"> no workspaces available to select. </p> @@ -239,7 +238,7 @@ function WorkspaceSuggestions({ : availableWorkspaces; return ( - <div className="w-full mt-[2px] bg-zinc-800 border border-white/40 top-[45px] h-40 rounded-lg p-2 text-sm flex flex-col gap-y-1 justify-start overflow-y-scroll"> + <div className="w-full mt-[2px] bg-zinc-900 top-[45px] h-40 rounded-lg p-2 text-sm flex flex-col gap-y-1 justify-start overflow-y-scroll"> {filteredWorkspace.map((workspace) => { return ( <button @@ -271,19 +270,19 @@ function DatasetSummary({ workspaces = [], feedback = null }) { }, [workspaces, feedback]); return ( - <div className="bg-zinc-800 text-white/80 p-2 rounded-lg font-mono"> + <div className="bg-zinc-900 text-white/80 p-4 rounded-lg text-sm"> <p>Training dataset size: {stats.count ?? "Unknown"}</p> {stats.count < stats.recommendedMin ? ( - <div className="flex items-center gap-x-1 text-red-500 text-sm p-1 rounded-lg bg-red-500/20 w-fit my-2"> - <Warning /> + <div className="flex items-center gap-x-1 text-red-500 text-sm p-2 rounded-lg bg-red-500/20 w-fit my-2"> + <Warning size={14} /> <p> Your dataset is below the recommended minimum of{" "} {stats.recommendedMin}! You may see no impact from a fine-tune. </p> </div> ) : ( - <div className="flex items-center gap-x-1 text-green-500 text-sm p-1 rounded-lg bg-green-500/20 w-fit my-2"> - <CheckCircle /> + <div className="flex items-center gap-x-1 text-green-500 text-sm p-2 rounded-lg bg-green-500/20 w-fit my-2"> + <CheckCircle size={14} /> <p> Your dataset is large enough that you should see good results from a fine-tune. diff --git a/frontend/src/pages/FineTuning/Steps/FulfillmentPolicy/index.jsx b/frontend/src/pages/FineTuning/Steps/FulfillmentPolicy/index.jsx index 950668c79..e66c5672b 100644 --- a/frontend/src/pages/FineTuning/Steps/FulfillmentPolicy/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/FulfillmentPolicy/index.jsx @@ -1,3 +1,4 @@ +import CTAButton from "@/components/lib/CTAButton"; import FineTuningSteps from ".."; export default function Fulfillment({ setSettings, setStep }) { @@ -10,34 +11,29 @@ export default function Fulfillment({ setSettings, setStep }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-3 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> Fulfillment Policy </h2> - <p> + <p className="text-white/80 text-sm"> Fulfillment of a fine-tune model is straight-forward. We do not host your model. We provide you a download link to run the model in a standard format where ever you run local LLMs </p> - <div className="flex flex-col gap-y-2 text-white/75 text-sm border p-2 border-white rounded-lg font-mono h-[60vh] overflow-y-scroll"> - <h1 class="text-white/80 text-lg font-semibold"> - Fulfillment Terms - </h1> - <p> - <strong>Last updated: July 15, 2024</strong> - </p> - - <p> + <div className="flex flex-col gap-y-2 text-white/80 text-xs font-semibold rounded-lg p-4 h-[60vh] overflow-y-auto bg-dark-text mt-2"> + <div className="text-xs text-white"> + <h1>Fulfillment Terms</h1> + <p>Last updated: July 15, 2024</p> + </div> + <p className="text-white/80"> These fulfillment terms outline the agreement between Mintplex - Labs Inc. (“Company,†“we,†“us,†or “ourâ€) and the customer + Labs Inc. ("Company," "we," "us," or "our") and the customer regarding the creation and delivery of fine-tuned models. </p> - <h2 class="text-white/80 text-base font-semibold"> - Delivery of Model - </h2> - <p> + <h2 className="text-white mt-4">Delivery of Model</h2> + <p className="text-white/80"> Upon completion of a fine-tuning job, we will deliver a download link to a .gguf model file suitable for LLM text inferencing. The customer acknowledges that this exchange is strictly transactional @@ -45,17 +41,15 @@ export default function Fulfillment({ setSettings, setStep }) { is considered concluded and will be ineligible for a refund. </p> - <h2 class="text-white/80 text-base font-semibold">Support</h2> - <p> + <h2 className="text-white mt-4">Support</h2> + <p className="text-white/80"> Please note that the delivery of the model does not include any dedicated support. Customers are encouraged to refer to available documentation and resources for guidance on using the model. </p> - <h2 class="text-white/80 text-base font-semibold"> - Requesting Download Links - </h2> - <p> + <h2 className="text-white mt-4">Requesting Download Links</h2> + <p className="text-white/80"> Customers may request refreshed download links from my.mintplexlabs.com as long as the model is retained in our cloud storage. We will retain a model in our storage for a maximum of 3 @@ -63,10 +57,8 @@ export default function Fulfillment({ setSettings, setStep }) { links are valid for 24 hours. </p> - <h2 class="text-white/80 text-base font-semibold"> - Cancellation and Refunds - </h2> - <p> + <h2 className="text-white mt-4">Cancellation and Refunds</h2> + <p className="text-white/80"> Mintplex Labs Inc. reserves the right to cancel any fine-tuning job at our discretion. In the event of a cancellation, a refund may be issued. Additionally, we reserve the right to deny a @@ -74,22 +66,22 @@ export default function Fulfillment({ setSettings, setStep }) { cause or notice to the Customer. </p> - <h2 class="text-white/80 text-base font-semibold">No Guarantees</h2> - <p> + <h2 className="text-white mt-4">No Guarantees</h2> + <p className="text-white/80"> Mintplex Labs Inc. makes <strong>NO GUARANTEES</strong> regarding the resulting model's output, functionality, speed, or compatibility with your tools, infrastructure and devices. Refund requests of this nature are not eligible for refunds. </p> - <p> + <p className="text-white/80"> Models are delivered and accepted in "As-Is" condition. All delivered model and output files are deemed final and non-refundable for any reason after training is complete and a model has been generated. </p> - <h2 class="text-white/80 text-base font-semibold">Payment Terms</h2> - <p> + <h2 className="text-white mt-4">Payment Terms</h2> + <p className="text-white/80"> All payments are required prior to the commencement of the fine-tuning process. Customers are responsible for ensuring that valid payment information is provided. Checkout sessions not @@ -97,32 +89,36 @@ export default function Fulfillment({ setSettings, setStep }) { abandoned and will be deleted from our system. </p> - <h2 class="text-white/80 text-base font-semibold"> + <h2 className="text-white mt-4"> Denial of Service for Payment Reasons </h2> - <p> + <p className="text-white/80"> Mintplex Labs Inc. reserves the right to deny service to any customer with an outstanding balance or invalid payment information. If any discrepancies arise regarding payment or usage, we may suspend services until the matter is resolved. </p> - <h2 class="text-white/80 text-base font-semibold">Contact</h2> - <p> + <h2 className="text-white mt-4">Contact</h2> + <p className="text-white/80"> For any questions related to payment or fulfillment of services, please contact us at{" "} - <a href="mailto:team@mintplexlabs.com">team@mintplexlabs.com</a>. + <a + href="mailto:team@mintplexlabs.com" + className="text-blue-400 hover:underline" + > + team@mintplexlabs.com + </a> + . </p> </div> + <CTAButton + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + onClick={handleAccept} + > + Agree and continue → + </CTAButton> </div> - - <button - onClick={handleAccept} - type="button" - className="mt-8 w-full py-2 text-center text-white hover:bg-primary-button border-none rounded-lg" - > - Agree and continue → - </button> </div> </div> ); diff --git a/frontend/src/pages/FineTuning/Steps/Introduction/index.jsx b/frontend/src/pages/FineTuning/Steps/Introduction/index.jsx index 1b784d961..c60e12d64 100644 --- a/frontend/src/pages/FineTuning/Steps/Introduction/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/Introduction/index.jsx @@ -1,5 +1,6 @@ -import { CheckCircle, XCircle } from "@phosphor-icons/react"; +import { Check, X } from "@phosphor-icons/react"; import FineTuningSteps from ".."; +import CTAButton from "@/components/lib/CTAButton"; export default function Introduction({ setSettings, setStep }) { const handleAccept = () => { @@ -11,12 +12,12 @@ export default function Introduction({ setSettings, setStep }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-2 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> What is a "Fine-Tuned" model? </h2> - <div className="flex flex-col gap-y-2 text-white/80"> + <div className="flex flex-col gap-y-[25px] text-white/80 text-sm"> <p> Fine-tuned models are basically "customized" Language-Learning-Models (LLMs). These can be based on popular @@ -36,8 +37,8 @@ export default function Introduction({ setSettings, setStep }) { </p> </div> - <div className="flex flex-col gap-y-2 text-white/80"> - <h3 className="text-lg text-white font-semibold"> + <div className="flex flex-col gap-y-2 text-white/80 text-sm mt-4"> + <h3 className="text-base text-white font-semibold"> When should I get a fine-tuned model? </h3> <p> @@ -45,48 +46,49 @@ export default function Introduction({ setSettings, setStep }) { following </p> <ul className="flex flex-col gap-y-1"> - <li className="flex items-center gap-x-1"> - <CheckCircle className="text-green-300" /> Setting the style, - tone, format, or other qualitative aspects without prompting + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" /> Setting + the style, tone, format, or other qualitative aspects without + prompting </li> - <li className="flex items-center gap-x-1"> - <CheckCircle className="text-green-300" /> Improving reliability - at producing a desired output + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" />{" "} + Improving reliability at producing a desired output </li> - <li className="flex items-center gap-x-1"> - <CheckCircle className="text-green-300" /> Correcting failures - to follow complex prompts, citations, or lack of background - knowledge + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" />{" "} + Correcting failures to follow complex prompts, citations, or + lack of background knowledge </li> - <li className="flex items-center gap-x-1"> - <CheckCircle className="text-green-300" /> You want to run this - model privately or offline + <li className="flex items-center gap-x-2"> + <Check className="text-white" size={12} weight="bold" /> You + want to run this model privately or offline </li> </ul> </div> - <div className="flex flex-col gap-y-2 text-white/80"> - <h3 className="text-lg text-white font-semibold"> + <div className="flex flex-col gap-y-2 text-white/80 text-sm mt-4"> + <h3 className="text-base text-white font-semibold"> What are fine-tunes bad for? </h3> <p> - Fine-tuned models powerful, but they are not the "silver bullet" - to any issues you have with RAG currently. Some notable + Fine-tuned models are powerful, but they are not the "silver + bullet" to any issues you have with RAG currently. Some notable limitations are </p> <ul> <li className="flex items-center gap-x-1"> - <XCircle className="text-red-300" /> You need perfect recall of - some piece of literature or reference document + <X className="text-white" size={12} weight="bold" /> You need + perfect recall of some piece of literature or reference document </li> <li className="flex items-center gap-x-1"> - <XCircle className="text-red-300" /> You want your model to have - perfect memory or recollection + <X className="text-white" size={12} weight="bold" /> You want + your model to have perfect memory or recollection </li> </ul> </div> - <div className="flex flex-col gap-y-2 text-white/80"> + <div className="flex flex-col gap-y-2 text-white/80 text-sm"> <p> In summary, if you are getting good results with RAG currently, creating a fine-tune can squeeze <b>even more performance</b> out @@ -95,15 +97,14 @@ export default function Introduction({ setSettings, setStep }) { that is what RAG is for! Together, it is a powerful combination. </p> </div> + <CTAButton + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + onClick={handleAccept} + text="Create fine-tune model →" + > + Create a fine-tune model → + </CTAButton> </div> - - <button - onClick={handleAccept} - type="button" - className="mt-8 w-full py-2 text-center text-white hover:bg-primary-button border-none rounded-lg" - > - Start a fine-tune → - </button> </div> </div> ); diff --git a/frontend/src/pages/FineTuning/Steps/OrderDetails/index.jsx b/frontend/src/pages/FineTuning/Steps/OrderDetails/index.jsx index b0f44a462..657c75acc 100644 --- a/frontend/src/pages/FineTuning/Steps/OrderDetails/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/OrderDetails/index.jsx @@ -2,9 +2,11 @@ import FineTuning from "@/models/experimental/fineTuning"; import { useEffect, useState } from "react"; import FineTuningSteps from ".."; import { CircleNotch } from "@phosphor-icons/react"; +import CTAButton from "@/components/lib/CTAButton"; export default function OrderDetails({ setSettings, setStep }) { const [info, setInfo] = useState({}); + useEffect(() => { FineTuning.info() .then((res) => { @@ -32,33 +34,30 @@ export default function OrderDetails({ setSettings, setStep }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <form onSubmit={handleSubmit}> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> - Time to create your fine tune! - </h2> - <p> - Creating a model is quite simple. Currently we have a limited base - model selection, however in the future we plan to expand support - to many more foundational models. - </p> - - <div className="flex flex-col pr-10"> - <div className="flex flex-col gap-y-1 mb-4"> - <label className="text-white text-sm font-bold"> - Account e-mail - </label> - <p className="text-xs font-normal text-white/80"> - This e-mail is where you will receive all order information - and updates. This e-mail <b>must be accurate</b> or else we - won't be able to contact you with your fine-tuned model! - </p> - </div> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-3 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> + Time to create your fine tune! + </h2> + <p className="text-white/80 text-sm"> + Creating a model is quite simple. Currently we have a limited base + model selection, however in the future we plan to expand support to + many more foundational models. + </p> + <form onSubmit={handleSubmit} className="flex flex-col gap-y-6 mt-4"> + <div className="flex flex-col"> + <label className="text-white text-sm font-semibold block mb-3"> + Account e-mail + </label> + <p className="text-xs font-normal text-white/80 mb-2"> + This e-mail is where you will receive all order information and + updates. This e-mail <b>must be accurate</b> or else we won't be + able to contact you with your fine-tuned model! + </p> <input type="email" name="email" - className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" + className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full max-w-[200px] p-2.5" placeholder="jdoe@example.com" required={true} autoComplete="off" @@ -66,33 +65,29 @@ export default function OrderDetails({ setSettings, setStep }) { /> </div> - <div className="flex flex-col pr-10"> - <div className="flex flex-col gap-y-1 mb-4"> - <label className="text-white text-sm font-bold"> - Preferred Base Model - </label> - <p className="text-xs font-normal text-white/80"> - This is the foundational model your fine-tune will be based - on. We recommend Llama 3 8B. - </p> - </div> + <div className="flex flex-col"> + <label className="text-white text-sm font-semibold block mb-3"> + Preferred Base Model + </label> + <p className="text-xs font-normal text-white/80 mb-2"> + This is the foundational model your fine-tune will be based on. + We recommend Llama 3 8B. + </p> {info.hasOwnProperty("availableBaseModels") ? ( <select name="baseModel" required={true} - className="border-none bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-fit p-2.5" + className="bg-zinc-900 border-gray-500 text-white text-sm rounded-lg block w-full max-w-[200px] p-2.5" > - <option disabled="true" selected="true" value=""> + <option disabled value=""> -- select a base model -- </option> <optgroup label="Available base models"> - {(info?.availableBaseModels || []).map((model) => { - return ( - <option key={model} value={model}> - {model} - </option> - ); - })} + {(info?.availableBaseModels || []).map((model) => ( + <option key={model} value={model}> + {model} + </option> + ))} </optgroup> </select> ) : ( @@ -103,35 +98,34 @@ export default function OrderDetails({ setSettings, setStep }) { )} </div> - <div className="flex flex-col pr-10"> - <div className="flex flex-col gap-y-1 mb-4"> - <label className="text-white text-sm font-bold"> - Model name - </label> - <p className="text-xs font-normal text-white/80"> - What would you like to call your model? This has no impact on - its output or training and is only used for how we communicate - with you about the model. - </p> - </div> + <div className="flex flex-col"> + <label className="text-white text-sm font-semibold block mb-3"> + Model name + </label> + <p className="text-xs font-normal text-white/80 mb-2"> + What would you like to call your model? This has no impact on + its output or training and is only used for how we communicate + with you about the model. + </p> <input type="text" name="modelName" - className="border-none bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full p-2.5" + className="bg-zinc-900 text-white placeholder:text-white/20 text-sm rounded-lg focus:outline-primary-button active:outline-primary-button outline-none block w-full max-w-[200px] p-2.5" placeholder="My really cool model!" required={true} autoComplete="off" spellCheck={false} /> </div> - </div> - <button - type="submit" - className="mt-8 w-full py-2 text-center text-white hover:bg-primary-button border-none rounded-lg" - > - Proceed to data selection → - </button> - </form> + + <CTAButton + type="submit" + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + > + Proceed to data selection → + </CTAButton> + </form> + </div> </div> </div> ); diff --git a/frontend/src/pages/FineTuning/Steps/OrderPlaced/index.jsx b/frontend/src/pages/FineTuning/Steps/OrderPlaced/index.jsx index 018b8fba1..8d0b1f01d 100644 --- a/frontend/src/pages/FineTuning/Steps/OrderPlaced/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/OrderPlaced/index.jsx @@ -1,13 +1,15 @@ +import CTAButton from "@/components/lib/CTAButton"; +import paths from "@/utils/paths"; + export default function OrderPlaced({ settings }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-2 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> Your order is placed! </h2> - - <div className=""> + <div className="flex flex-col gap-y-[25px] text-white/80 text-xs"> <p> Your fine-tune will begin once payment is complete. If the payment window did not automatically open - your checkout link is below. @@ -15,53 +17,65 @@ export default function OrderPlaced({ settings }) { <a href={settings.checkoutUrl} target="_blank" - className="text-xs font-mono text-white/60 underline" + rel="noreferrer" + className="text-sky-400 hover:underline hover:cursor-pointer" > {new URL(settings.checkoutUrl).origin} </a> - <p className="text-xs font-mono text-white/80"> + <p className="text-xs text-white/80"> Your fine-tune does not begin until this payment is completed. </p> - </div> - <div className=""> - <p className="font-mono text-white/80 text-sm"> - Reference: {settings.jobId} - </p> - <p className="text-xs font-mono text-white/80"> - This reference id is how we will communicate with you about your - fine-tune training status. <b>Save this reference id.</b> - </p> - </div> + <div className="flex flex-col gap-y-2"> + <p className="text-white/80 font-medium"> + Reference: <span className="font-normal">{settings.jobId}</span> + </p> + <p className="text-xs text-white/80"> + This reference id is how we will communicate with you about your + fine-tune training status. <b>Save this reference id.</b> + </p> + </div> - <div className=""> - <p className="font-mono text-white/80 text-sm"> - Contact: {settings.email} - </p> - <p className="text-xs font-mono text-white/80"> - Check the email above for order confirmation, status updates, and - more. Mintplex Labs will only contact you about your order via - email. - </p> - </div> + <div className="flex flex-col gap-y-2"> + <p className="text-white/80 font-medium"> + Contact: <span className="font-normal">{settings.email}</span> + </p> + <p className="text-xs text-white/80"> + Check the email above for order confirmation, status updates, + and more. Mintplex Labs will only contact you about your order + via email. + </p> + </div> - <div className="font-mono text-white/80 text-sm flex items-center gap-x-2"> - <a - href="https://docs.useanything.com/fine-tuning/overview" - target="_blank" - className="underline" - > - Documentation - </a> - <a href="mailto:team@mintplexlabs.com" className="underline"> - Contact support - </a> + <div className="flex flex-col items-left gap-x-4 text-xs"> + <a + href="https://docs.useanything.com/fine-tuning/overview" + target="_blank" + rel="noreferrer" + className="text-sky-400 hover:underline hover:cursor-pointer" + > + Documentation + </a> + <a + href="mailto:team@mintplexlabs.com" + className="text-sky-400 hover:underline hover:cursor-pointer" + > + Contact support + </a> + </div> + + <p className="text-xs text-white/80"> + You can close this window or navigate away once you see the + confirmation email in your inbox. + </p> </div> - <p className="text-xs font-mono text-white/80"> - You can close this window or navigate away once you see the - confirmation email in your inbox. - </p> + <CTAButton + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + onClick={() => (window.location.href = paths.home())} + > + Finish + </CTAButton> </div> </div> </div> diff --git a/frontend/src/pages/FineTuning/Steps/Privacy/index.jsx b/frontend/src/pages/FineTuning/Steps/Privacy/index.jsx index 6e0d5e980..e4d711518 100644 --- a/frontend/src/pages/FineTuning/Steps/Privacy/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/Privacy/index.jsx @@ -1,3 +1,4 @@ +import CTAButton from "@/components/lib/CTAButton"; import FineTuningSteps from ".."; export default function PrivacyHandling({ setSettings, setStep }) { @@ -10,12 +11,12 @@ export default function PrivacyHandling({ setSettings, setStep }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-3 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> Data Handling Policy & Privacy </h2> - <p> + <p className="text-white/80 text-sm"> Please accept the terms and conditions to continue with creation and ordering of a fine-tune model. We take the handling of your data very seriously and will only use your uploaded data for training the @@ -23,18 +24,14 @@ export default function PrivacyHandling({ setSettings, setStep }) { completed, or canceled your information is automatically and permanently deleted. </p> - <div className="flex flex-col gap-y-2 text-white/75 text-sm border p-2 border-white rounded-lg font-mono h-[60vh] overflow-y-scroll"> - <h1 class="text-white/80 text-lg font-semibold">Privacy Policy</h1> - - <p> - <strong>Mintplex Labs Inc.</strong> - </p> - <p>Effective Date: July 15, 2024</p> - - <h2 class="text-white/80 text-base font-semibold"> - 1. Introduction - </h2> - <p> + <div className="flex flex-col gap-y-2 text-white/75 text-xs font-semibold rounded-lg p-4 h-[60vh] overflow-y-auto bg-dark-text mt-2"> + <div className="text-xs"> + <h1 className="text-white/80">Privacy Policy</h1> + <p>Mintplex Labs Inc.</p> + <p>Effective Date: July 15, 2024</p> + </div> + <h2 className="text-white mt-4">1. Introduction</h2> + <p className="text-white/80"> Welcome to Mintplex Labs Inc. ("we", "our", "us"). We are committed to protecting your privacy and ensuring the security of your personal information. This Privacy Policy describes how we @@ -42,45 +39,41 @@ export default function PrivacyHandling({ setSettings, setStep }) { services. </p> - <h2 class="text-white/80 text-base font-semibold"> - 2. Information We Collect - </h2> - <p> + <h2 className="text-white mt-4">2. Information We Collect</h2> + <p className="text-white/80"> When you place an order with us for tuning and large language model (LLM) fulfillment, we collect certain personal information from you, including but not limited to: </p> - <ul> + <ul className="list-disc pl-5 text-white/80"> <li>Email address</li> <li>Payment information</li> <li>Uploaded training data</li> </ul> - <h2 class="text-white/80 text-base font-semibold"> - 3. Use of Information - </h2> - <p>We use the information we collect for the following purposes:</p> - <ul> + <h2 className="text-white mt-4">3. Use of Information</h2> + <p className="text-white/80"> + We use the information we collect for the following purposes: + </p> + <ul className="list-disc pl-5 text-white/80"> <li>To process and fulfill your order</li> <li>To communicate with you regarding your order</li> <li>To improve our services</li> </ul> - <h2 class="text-white/80 text-base font-semibold"> - 4. Data Retention and Deletion - </h2> - <p> + <h2 className="text-white mt-4">4. Data Retention and Deletion</h2> + <p className="text-white/80"> Uploaded training data is only retained for the duration of the model training. Upon training completion, failure, or order cancellation, the user data is permanently deleted from our storage. </p> - <p> + <p className="text-white/80"> If you partially complete the order flow and do not finalize your order, any details and information associated with your order will be deleted 1 hour from abandonment. </p> - <p> + <p className="text-white/80"> After you confirm receipt of your resulting model files, you can request us to delete your model from our storage at any time. Additionally, we may proactively reach out to you to confirm that @@ -90,10 +83,8 @@ export default function PrivacyHandling({ setSettings, setStep }) { storage. </p> - <h2 class="text-white/80 text-base font-semibold"> - 5. Data Storage and Security - </h2> - <p> + <h2 className="text-white mt-4">5. Data Storage and Security</h2> + <p className="text-white/80"> Our cloud storage provider is AWS. We have implement standard encryption and protection policies to ensure the security of your data. The storage solution has no public access, and all requests @@ -104,43 +95,41 @@ export default function PrivacyHandling({ setSettings, setStep }) { e-mail you used during checkout. </p> - <h2 class="text-white/80 text-base font-semibold"> - 6. Payment Processing - </h2> - <p> + <h2 className="text-white mt-4">6. Payment Processing</h2> + <p className="text-white/80"> We use Stripe as our payment processor. Your email may be shared with Stripe for customer service and payment management purposes. </p> - <h2 class="text-white/80 text-base font-semibold"> - 7. Data Sharing - </h2> - <p> + <h2 className="text-white mt-4">7. Data Sharing</h2> + <p className="text-white/80"> We do not sell or share your personal information with third parties except as necessary to provide our services, comply with legal obligations, or protect our rights. </p> - <h2 class="text-white/80 text-base font-semibold"> - 8. Your Rights - </h2> - <p> + <h2 className="text-white mt-4">8. Your Rights</h2> + <p className="text-white/80"> You have the right to access, correct, or delete your personal information. If you wish to exercise these rights, please contact us at{" "} - <a href="mailto:team@mintplexlabs.com">team@mintplexlabs.com</a>. + <a + href="mailto:team@mintplexlabs.com" + className="text-blue-400 hover:underline" + > + team@mintplexlabs.com + </a> + . </p> - <h2 class="text-white/80 text-base font-semibold"> - 9. California Privacy Rights - </h2> - <p> + <h2 className="text-white mt-4">9. California Privacy Rights</h2> + <p className="text-white/80"> Under the California Consumer Privacy Act as amended by the - California Privacy Rights Act (the “CCPAâ€), California residents + California Privacy Rights Act (the "CCPA"), California residents have additional rights beyond what is set out in this privacy notice: </p> - <ul> + <ul className="list-disc pl-5 text-white/80"> <li> <strong>Right to Know:</strong> You have the right to request information about the categories and specific pieces of personal @@ -170,63 +159,70 @@ export default function PrivacyHandling({ setSettings, setStep }) { your CCPA rights. </li> </ul> - <p> + <p className="text-white/80"> <strong>Submitting a Request:</strong> <br /> You may submit a request to know, delete, or correct your personal information by contacting us at{" "} - <a href="mailto:team@mintplexlabs.com">team@mintplexlabs.com</a>. - We will confirm your identity before processing your request and + <a + href="mailto:team@mintplexlabs.com" + className="text-blue-400 hover:underline" + > + team@mintplexlabs.com + </a> + . We will confirm your identity before processing your request and respond within 45 days. If more time is needed, we will inform you of the reason and extension period in writing. You may make a request for your information twice every 12 months. If you are making an erasure request, please include details of the information you would like erased. </p> - <p> + <p className="text-white/80"> Please note that if you request that we remove your information, we may retain some of the information for specific reasons, such as to resolve disputes, troubleshoot problems, and as required by law. Some information may not be completely removed from our databases due to technical constraints and regular backups. </p> - <p> + <p className="text-white/80"> We will not discriminate against you for exercising any of your CCPA rights. </p> - <h2 class="text-white/80 text-base font-semibold"> - 10. Contact Us - </h2> - <p> + <h2 className="text-white mt-4">10. Contact Us</h2> + <p className="text-white/80"> If you have any questions or concerns about this Privacy Policy, please contact us at{" "} - <a href="mailto:team@mintplexlabs.com">team@mintplexlabs.com</a>. + <a + href="mailto:team@mintplexlabs.com" + className="text-blue-400 hover:underline" + > + team@mintplexlabs.com + </a> + . </p> - <h2 class="text-white/80 text-base font-semibold"> + <h2 className="text-white mt-4"> 11. Changes to This Privacy Policy </h2> - <p> + <p className="text-white/80"> We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on our website. You are advised to review this Privacy Policy periodically for any changes. </p> - <p> + <p className="text-white/80"> By using our services, you agree to the terms of this Privacy Policy. </p> </div> + <CTAButton + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + onClick={handleAccept} + > + Agree and continue → + </CTAButton> </div> - - <button - onClick={handleAccept} - type="button" - className="mt-8 w-full py-2 text-center text-white hover:bg-primary-button border-none rounded-lg" - > - Agree and continue → - </button> </div> </div> ); diff --git a/frontend/src/pages/FineTuning/Steps/TermsAndConditions/index.jsx b/frontend/src/pages/FineTuning/Steps/TermsAndConditions/index.jsx index 339c43de3..c29e500d9 100644 --- a/frontend/src/pages/FineTuning/Steps/TermsAndConditions/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/TermsAndConditions/index.jsx @@ -1,3 +1,4 @@ +import CTAButton from "@/components/lib/CTAButton"; import FineTuningSteps from ".."; export default function TermsAndConditions({ setSettings, setStep }) { @@ -10,24 +11,21 @@ export default function TermsAndConditions({ setSettings, setStep }) { return ( <div className="flex-[2] flex flex-col gap-y-[18px] mt-10"> - <div className="bg-[#303237] text-white rounded-xl flex-1 p-4"> - <div className="w-full flex flex-col gap-y-4"> - <h2 className="text-xl text-white font-semibold"> + <div className="bg-[#303237] text-white rounded-xl flex-1 p-6"> + <div className="w-full flex flex-col gap-y-3 max-w-[700px]"> + <h2 className="text-base text-white font-semibold"> Terms and Conditions </h2> - <p> + <p className="text-white/80 text-sm"> Please accept the terms and conditions to continue with creation and ordering of a fine-tune model. </p> - <div className="flex flex-col gap-y-2 text-white/75 text-sm border p-2 border-white rounded-lg font-mono h-[60vh] overflow-y-scroll"> - <h1 className="text-white/80 text-lg font-semibold"> - Mintplex Labs Inc. Fine-Tuning Terms of Service - </h1> - <p> - <strong>Last Updated:</strong> July 15, 2024 - </p> - - <p> + <div className="flex flex-col gap-y-2 text-white/80 text-xs font-semibold rounded-lg p-4 h-[60vh] overflow-y-auto bg-dark-text mt-2"> + <div className="text-xs text-white"> + <h1>Mintplex Labs Inc. Fine-Tuning Terms of Service</h1> + <p>Last Updated: July 15, 2024</p> + </div> + <p className="text-white/80"> This Agreement is between Mintplex Labs Inc. ("Company") and the customer ("Customer") accessing or using the services provided by the Company. By signing up, accessing, or using the services, @@ -35,20 +33,16 @@ export default function TermsAndConditions({ setSettings, setStep }) { be bound by the terms and conditions outlined below. </p> - <h2 className="text-white/80 text-base font-semibold"> - 1. Services Provided - </h2> - <p> + <h2 className="text-white mt-4">1. Services Provided</h2> + <p className="text-white/80"> Mintplex Labs Inc. provides model fine-tuning services for customers. The deliverable for these services is a download link to the output ".GGUF" file that can be used by the Customer for Large-Language text inferencing. </p> - <h2 className="text-white/80 text-base font-semibold"> - 2. Payment Terms - </h2> - <ul> + <h2 className="text-white mt-4">2. Payment Terms</h2> + <ul className="list-disc pl-5 text-white/80"> <li> <strong>One-Time Payment:</strong> A one-time payment is required before the execution of the training. @@ -64,10 +58,8 @@ export default function TermsAndConditions({ setSettings, setStep }) { </li> </ul> - <h2 className="text-white/80 text-base font-semibold"> - 3. Order Form - </h2> - <ul> + <h2 className="text-white mt-4">3. Order Form</h2> + <ul className="list-disc pl-5 text-white/80"> <li> <strong>Service:</strong> Model fine-tuning </li> @@ -79,88 +71,81 @@ export default function TermsAndConditions({ setSettings, setStep }) { </li> </ul> - <h2 className="text-white/80 text-base font-semibold"> - 4. Customer Responsibilities - </h2> - <p> + <h2 className="text-white mt-4">4. Customer Responsibilities</h2> + <p className="text-white/80"> The Customer must provide all necessary data and information required for model fine-tuning. </p> - <p> + <p className="text-white/80"> The Customer must ensure timely payment as per the terms mentioned above. </p> - <p> + <p className="text-white/80"> The Customer understands the data collected for tuning will be stored to a private cloud storage location temporarily while training is in progress. </p> - <p> + <p className="text-white/80"> The Customer understands the data collected for tuning will be fully deleted once the order is completed or canceled by the Company. </p> - <p> + <p className="text-white/80"> The Customer understands and has reviewed the Privacy Policy for Fine-Tuning by the Company. </p> - <h2 className="text-white/80 text-base font-semibold"> - 5. Refund Policy - </h2> - <p> + <h2 className="text-white mt-4">5. Refund Policy</h2> + <p className="text-white/80"> Refunds will be processed in the event of training failure or if the complete model file is not delivered to the Customer. Refunds will be issued to the original payment method within 30 days of the refund request. </p> - <h2 className="text-white/80 text-base font-semibold"> - 6. Governing Law - </h2> - <p> + <h2 className="text-white mt-4">6. Governing Law</h2> + <p className="text-white/80"> This Agreement shall be governed by and construed in accordance with the laws of the State of California. </p> - <h2 className="text-white/80 text-base font-semibold"> - 7. Dispute Resolution - </h2> - <p> + <h2 className="text-white mt-4">7. Dispute Resolution</h2> + <p className="text-white/80"> Any disputes arising out of or in connection with this Agreement shall be resolved in the state or federal courts located in California. </p> - <h2 className="text-white/80 text-base font-semibold"> - 8. Notices - </h2> - <p> + <h2 className="text-white mt-4">8. Notices</h2> + <p className="text-white/80"> All notices under this Agreement shall be in writing and shall be deemed given when delivered personally, sent by confirmed email, or sent by certified or registered mail, return receipt requested, and addressed to the respective parties as follows: </p> - <p> + <p className="text-white/80"> For Company:{" "} - <a href="mailto:team@mintplexlabs.com">team@mintplexlabs.com</a> + <a + href="mailto:team@mintplexlabs.com" + className="text-blue-400 hover:underline" + > + team@mintplexlabs.com + </a> + </p> + <p className="text-white/80"> + For Customer: The main email address on Customer's account </p> - <p>For Customer: The main email address on Customer's account</p> - <h2 className="text-white/80 text-base font-semibold"> - 9. Amendments - </h2> - <p> + <h2 className="text-white mt-4">9. Amendments</h2> + <p className="text-white/80"> The Company reserves the right to amend these terms at any time by providing notice to the Customer. The Customer's continued use of the services after such amendments will constitute acceptance of the amended terms. </p> - <h2 className="text-white/80 text-base font-semibold"> - 10. Indemnity - </h2> - <p> + <h2 className="text-white mt-4">10. Indemnity</h2> + <p className="text-white/80"> The Customer agrees to indemnify, defend, and hold harmless Mintplex Labs Inc., its affiliates, and their respective officers, directors, employees, agents, and representatives from and against @@ -173,15 +158,13 @@ export default function TermsAndConditions({ setSettings, setStep }) { person or entity. </p> </div> + <CTAButton + className="text-dark-text w-full mt-[18px] h-[34px] hover:bg-accent" + onClick={handleAccept} + > + Agree and continue → + </CTAButton> </div> - - <button - onClick={handleAccept} - type="button" - className="mt-8 w-full py-2 text-center text-white hover:bg-primary-button border-none rounded-lg" - > - Agree and continue → - </button> </div> </div> ); diff --git a/frontend/src/pages/FineTuning/Steps/index.jsx b/frontend/src/pages/FineTuning/Steps/index.jsx index 55ed589d8..7cf74263f 100644 --- a/frontend/src/pages/FineTuning/Steps/index.jsx +++ b/frontend/src/pages/FineTuning/Steps/index.jsx @@ -26,7 +26,7 @@ import OrderPlaced from "./OrderPlaced"; const FineTuningSteps = { intro: { - name: "Introduction to Fine-Tuning", + name: "1. Introduction to Fine-Tuning", next: () => "privacy", component: ({ settings, setSettings, setStep }) => ( <Introduction @@ -37,7 +37,7 @@ const FineTuningSteps = { ), }, privacy: { - name: "How your data is handled", + name: "2. How your data is handled", next: () => "tos", component: ({ settings, setSettings, setStep }) => ( <PrivacyPolicy @@ -48,7 +48,7 @@ const FineTuningSteps = { ), }, tos: { - name: "Terms of service", + name: "3. Terms of service", next: () => "fulfillment", component: ({ settings, setSettings, setStep }) => ( <TermsAndConditions @@ -59,7 +59,7 @@ const FineTuningSteps = { ), }, fulfillment: { - name: "Fulfillment terms", + name: "4. Fulfillment terms", next: () => "order-details", component: ({ settings, setSettings, setStep }) => ( <Fulfillment @@ -70,7 +70,7 @@ const FineTuningSteps = { ), }, "order-details": { - name: "Model details & information", + name: "5. Model details & information", next: () => "data-selection", component: ({ settings, setSettings, setStep }) => ( <OrderDetails @@ -81,7 +81,7 @@ const FineTuningSteps = { ), }, "data-selection": { - name: "Data selection", + name: "6. Data selection", next: () => "confirmation", component: ({ settings, setSettings, setStep }) => ( <DataUpload @@ -92,7 +92,7 @@ const FineTuningSteps = { ), }, confirmation: { - name: "Review and Submit", + name: "7. Review and Submit", next: () => "done", component: ({ settings, setSettings, setStep }) => ( <Confirmation @@ -103,7 +103,7 @@ const FineTuningSteps = { ), }, done: { - name: "Order placed", + name: "8. Order placed", next: () => "done", component: ({ settings }) => <OrderPlaced settings={settings} />, }, @@ -133,7 +133,7 @@ export function FineTuningCreationLayout({ setStep, children }) { return ( <div id="fine-tune-create-order-container" - className="w-screen h-screen overflow-y-auto bg-sidebar flex" + className="w-screen h-screen overflow-hidden bg-sidebar flex md:mt-0 mt-6" > <Sidebar /> <div diff --git a/frontend/src/pages/FineTuning/index.jsx b/frontend/src/pages/FineTuning/index.jsx index 4406d8310..ceb29862a 100644 --- a/frontend/src/pages/FineTuning/index.jsx +++ b/frontend/src/pages/FineTuning/index.jsx @@ -1,13 +1,13 @@ import React, { useState } from "react"; import FineTuningSteps, { FineTuningCreationLayout } from "./Steps"; -import { CheckCircle, Circle, Sparkle } from "@phosphor-icons/react"; +import { Sparkle } from "@phosphor-icons/react"; import { isMobile } from "react-device-detect"; function SideBarSelection({ setStep, currentStep }) { const currentIndex = Object.keys(FineTuningSteps).indexOf(currentStep); return ( <div - className={`bg-white/5 text-white rounded-xl ${ + className={`bg-white/5 text-white rounded-xl py-1 px-4 ${ isMobile ? "w-full" : "min-w-[360px] w-fit" }`} > @@ -21,28 +21,32 @@ function SideBarSelection({ setStep, currentStep }) { <div key={stepKey} className={[ - "py-3 px-4 flex items-center justify-between transition-all duration-300", + "py-3 flex items-center justify-between transition-all duration-300", isSelected ? "rounded-t-xl" : "", isLast ? "" : "border-b border-white/10", ].join(" ")} > - {isDone ? ( + {isDone || isSelected ? ( <button onClick={() => setStep(stepKey)} - className="border-none hover:underline text-white/40 text-sm font-light" + className="border-none hover:underline text-sm font-medium" > {props.name} </button> ) : ( - <div className="text-sm font-light">{props.name}</div> + <div className="text-sm text-white/40 font-medium"> + {props.name} + </div> )} <div className="flex items-center gap-x-2"> {isDone ? ( - <CheckCircle className={`text-green-300`} /> + <div className="w-[14px] h-[14px] rounded-full border border-[#32D583] flex items-center justify-center"> + <div className="w-[5.6px] h-[5.6px] rounded-full bg-[#6CE9A6]"></div> + </div> ) : ( - <Circle - className={`text-white-800 ${ - isSelected ? "animate-pulse" : "opacity-10" + <div + className={`w-[14px] h-[14px] rounded-full border border-white ${ + isSelected ? "animate-pulse" : "opacity-50" }`} /> )} @@ -63,15 +67,19 @@ export default function FineTuningFlow() { return ( <FineTuningCreationLayout setStep={setStep}> {(settings, setSettings, setStep) => ( - <div className="flex-1 flex gap-x-6 p-4 mt-10"> - <div className="flex flex-col gap-y-[18px]"> + <div className="flex-1 flex h-full"> + <div className="flex flex-col gap-y-[18px] p-4 mt-10 w-[360px] flex-shrink-0"> <div className="text-white flex items-center gap-x-2"> <Sparkle size={24} /> <p className="text-lg font-medium">Custom Fine-Tuned Model</p> </div> <SideBarSelection setStep={setStep} currentStep={step} /> </div> - {StepPage.component({ settings, setSettings, setStep })} + <div className="flex-1 overflow-y-auto p-4 mt-10 pb-[74px] h-screen"> + <div className=" ml-8"> + {StepPage.component({ settings, setSettings, setStep })} + </div> + </div> </div> )} </FineTuningCreationLayout> -- GitLab