feature - added theming

This commit is contained in:
James Wyndham 2024-02-21 15:55:54 +08:00
parent 7d27741840
commit 72932f3d50
63 changed files with 991 additions and 1988 deletions

View File

@ -4,6 +4,8 @@ import { headers } from "next/headers";
import React from "react";
import Spacer from "@/components/Utilities/Spacer";
import pb from "@/lib/pocketbase";
import Footer from "@/components/Footer";
import Background from "@/components/Utilities/Background";
export async function generateMetadata({
params,
@ -43,10 +45,19 @@ const PostPage = async (props: any) => {
requestKey: "post",
});
return (
<div className="flex flex-col h-full w-full bg-white dark:bg-black px-8 md:max-w-3xl md:mx-auto">
<Spacer className="pt-32" />
<BlogContent post={post} />
</div>
<main
id="content"
role="main"
className="h-full flex-grow flex flex-col bg-base-100"
>
<Background>
<div className="flex flex-col h-full w-full md:max-w-3xl md:mx-auto">
<Spacer className="pt-32" />
<BlogContent post={post} />
</div>
<Footer />
</Background>
</main>
);
};

View File

@ -3,6 +3,7 @@ import BlogCard from "@/components/BlogCard";
import getPostMetadata from "@/utils/getPostMetaData";
import React from "react";
import Background from "@/components/Utilities/Background";
import Footer from "@/components/Footer";
export default async function BlogsPage() {
const postMetadata = await getPostMetadata();
@ -14,7 +15,7 @@ export default async function BlogsPage() {
<main
id="content"
role="main"
className="h-full flex-grow flex flex-col bg-white dark:bg-black"
className="h-full flex-grow flex flex-col bg-base-100"
>
<Background>
{/* Page sections */}
@ -23,7 +24,7 @@ export default async function BlogsPage() {
subtitle={
<>
{" "}
<h2 className="text-black dark:text-white font-bold text-2xl lg:text-3xl text-center max-w-5xl mx-auto px-6">
<h2 className="text-base-content font-bold text-2xl lg:text-3xl text-center max-w-5xl mx-auto px-6">
Join us for the journey as we make great food. Learn and grow
together
</h2>
@ -31,10 +32,11 @@ export default async function BlogsPage() {
}
/>
<div className="max-w-6xl mx-auto mb-24 h-full w-full py-12 px-8">
<div className="w-full flex items-start justify-center flex-row flex-wrap gap-x-8 gap-y-8 md:gap-8 text-black dark:text-white">
<div className="w-full flex items-start justify-center flex-row flex-wrap gap-x-8 gap-y-8 md:gap-8 text-base-content ">
{postPreviews}
</div>
</div>
<Footer />
</Background>
</main>
);

View File

@ -6,12 +6,12 @@ import React from "react";
const page = () => {
return (
<div className="flex flex-col h-full w-full bg-white dark:bg-black">
<div className="flex flex-col h-full w-full bg-base-100 ">
<Background>
<Spacer className="pt-28" />
<FormLeftDescriptionRightContactUs />
<Spacer className="mt-auto" />
<Footer />
<Spacer className="pt-16" />
</Background>
</div>
);

View File

@ -11,18 +11,22 @@ import { createCheckoutSession, isAuthenticated } from "@/app/(auth)/actions";
import { toast } from "react-toastify";
import { useRouter } from "next/navigation";
import Background from "@/components/Utilities/Background";
import Footer from "@/components/Footer";
export default function PricingPage() {
const [isAnnual, setIsAnnual] = useState(false);
const [products, setProducts] = useState<Product[]>([]);
const [isLoading, setIsLoading] = useState(true);
const handleToggle = () => {
setIsAnnual((prev) => !prev);
};
useEffect(() => {
setIsLoading(true);
(async () => {
const resposeProducts: Product[] = await apiPrices();
setProducts(resposeProducts);
setIsLoading(false);
})();
}, []);
@ -30,7 +34,7 @@ export default function PricingPage() {
<main
id="content"
role="main"
className="h-full flex flex-col min-h-screen mx-auto w-screen overflow-hidden bg-white dark:bg-black"
className="h-full flex flex-col min-h-screen mx-auto w-screen overflow-hidden bg-base-100 "
>
<Background>
<PageHeader
@ -38,7 +42,7 @@ export default function PricingPage() {
subtitle={
<>
{" "}
<h2 className="h3 text-black dark:text-white content text-center max-w-6xl mx-auto px-6">
<h2 className="text-base-content content text-center max-w-6xl mx-auto px-6">
Are you ready for fresh South West produce to be delivered to
your door?
</h2>
@ -52,12 +56,21 @@ export default function PricingPage() {
<div
className={`w-screen lg:w-full flex gap-x-4 lg:justify-center gap-y-8 px-6 pt-12 overflow-x-scroll`}
>
{products.map((x, i) => (
<PriceCard key={i} product={x} isAnnual={isAnnual} />
))}
{isLoading ? (
<>
<PriceCard loading={isLoading} />
<PriceCard loading={isLoading} />
<PriceCard loading={isLoading} />
</>
) : (
products.map((x, i) => (
<PriceCard key={i} product={x} isAnnual={isAnnual} />
))
)}
</div>
</div>
<Newsletter />
<Footer />
</Background>
</main>
);
@ -66,9 +79,11 @@ export default function PricingPage() {
function PriceCard({
product,
isAnnual,
loading,
}: {
product: Product;
isAnnual: boolean;
product?: Product;
isAnnual?: boolean;
loading?: boolean;
}) {
const router = useRouter();
const openSignUpModalOnPriceClick = (price: Price) => {
@ -108,7 +123,11 @@ function PriceCard({
}
};
return (
<div className="relative w-64 sm:w-80 bg-gray-100 dark:bg-gray-800 p-6">
<div
className={`relative w-64 sm:w-80 bg-base-100 rounded-lg p-6 ${
loading ? "animate-pulse h-[20rem]" : ""
}`}
>
<div className="flex flex-col h-full">
<div className="mb-12 relative">
{false && (
@ -117,20 +136,20 @@ function PriceCard({
</p>
)}
<h1 className="text-center text-3xl font-inter font-bold pt-6 text-black dark:text-white">
{product.name}
<h1 className="text-center text-3xl font-inter font-bold pt-6 text-base-content ">
{product?.name}
</h1>
<h3 className="text-center pt-4 text-black dark:text-white">
{product.description}
<h3 className="text-center pt-4 text-base-content ">
{product?.description}
</h3>
</div>
<div className="pb-12">
<ul className="flex flex-col gap-y-3 mx-12">
{product.metadata?.benefits?.map((x, i) => (
{product?.metadata?.benefits?.map((x, i) => (
<li key={i} className="flex items-center gap-x-4 flex-nowrap">
<Check className=" self-start" color="#FF0DCA" size={24} />
<p className="w-40 text-black dark:text-white overflow-clip text-ellipsis">
<p className="w-40 text-base-content overflow-clip text-ellipsis">
{x}
</p>
</li>
@ -138,25 +157,31 @@ function PriceCard({
</ul>
</div>
<div className="flex flex-col mx-auto mt-auto">
<div className="flex flex-row mx-auto gap-x-4 justify-center items-center mb-2">
<h1 className="h2 text-black dark:text-white">
$
{isAnnual
? product.yearlyPrice.unit_amount / 100
: product.monthlyPrice.unit_amount / 100}
</h1>
<p className="w-16 leading-5 text-sm text-black dark:text-white">
per user per {isAnnual ? "year" : "month"}
</p>
</div>
<button
onClick={() =>
submitForm(isAnnual ? product.yearlyPrice : product.monthlyPrice)
}
className=" mx-auto flex text-sm font-semibold py-2 px-20 m-2 text-white bg-gradient-to-r from-primary to-secondary rounded-full mb-4 cursor-pointer group-hover:animate-bounce"
>
Try it!
</button>
{!loading && (
<div className="flex flex-row mx-auto gap-x-4 justify-center items-center mb-2">
<h1 className="text-base-content ">
$
{isAnnual
? (product?.yearlyPrice?.unit_amount ?? 0) / 100
: (product?.monthlyPrice?.unit_amount ?? 0) / 100}
</h1>
<p className="w-16 leading-5 text-sm text-base-content ">
per user per {isAnnual ? "year" : "month"}
</p>
</div>
)}
{product && (
<button
onClick={() =>
submitForm(
isAnnual ? product.yearlyPrice : product.monthlyPrice
)
}
className=" mx-auto flex text-sm font-semibold py-2 px-20 m-2 bg-gradient-to-r from-primary to-secondary rounded-full mb-4 cursor-pointer group-hover:animate-bounce"
>
Try it!
</button>
)}
</div>
</div>
</div>
@ -172,7 +197,7 @@ function PriceToggle({
}) {
return (
<>
<label className="themeSwitcherTwo shadow-card relative inline-flex cursor-pointer select-none items-center justify-center rounded-sm dark:bg-gray-550 p-1">
<label className="shadow-card relative inline-flex cursor-pointer select-none items-center justify-center rounded-lg bg-base-100 p-1">
<input
type="checkbox"
className="sr-only"
@ -181,14 +206,14 @@ function PriceToggle({
/>
<span
className={`flex items-center space-x-[6px] rounded py-2 px-[18px] text-sm font-medium ${
!isAnnual ? "text-white bg-secondary" : "text-body-color"
!isAnnual ? " bg-secondary" : "text-secondary-content"
}`}
>
Monthly Billing
</span>
<span
className={`flex items-center space-x-[6px] rounded py-2 px-[18px] text-sm font-medium ${
isAnnual ? "text-white bg-secondary" : "text-body-color"
isAnnual ? " bg-secondary" : "text-secondary-content"
}`}
>
Yearly Billing

View File

@ -18,7 +18,7 @@ export default async function AccountPage() {
<main
id="content"
role="main"
className="h-full flex flex-col min-h-screen mx-auto w-screen overflow-hidden bg-white dark:bg-black"
className="h-full flex flex-col min-h-screen mx-auto w-screen overflow-hidden bg-base-100 "
>
<PageHeader title="Account" subtitle={<></>} />

View File

@ -4,11 +4,10 @@ import "@/styles/style.css";
import { Arimo, Raleway } from "next/font/google";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import Footer from "@/components/Footer";
import Header from "@/components/Header";
import { cookies } from "next/headers";
import { isAuthenticated } from "@/lib/auth";
import { GTagProvider, PHProvider } from "./providers";
import { GTagProvider, PHProvider, ThemeProvider } from "./providers";
import PrelineScript from "@/components/Utilities/PrelineScript";
const raleway = Raleway({
@ -32,25 +31,28 @@ export default async function RootLayout({
children: React.ReactNode;
}) {
const isUserLoggedIn = await isAuthenticated(cookies());
return (
<html lang="en" className="h-full">
<html lang="en" className="h-full" suppressHydrationWarning>
<PHProvider>
<GTagProvider />
<body className={`${arimo.className} bg-black flex`}>
<Header isUserLoggedIn={isUserLoggedIn} />
{children}
<ToastContainer
position="bottom-left"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="colored"
/>
<body className={`${arimo.className} bg-base-100 flex`}>
<ThemeProvider>
<Header isUserLoggedIn={isUserLoggedIn} />
{children}
<ToastContainer
position="bottom-left"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="colored"
/>
</ThemeProvider>
</body>
<PrelineScript />
</PHProvider>

View File

@ -2,6 +2,7 @@
import posthog from 'posthog-js'
import { PostHogProvider } from 'posthog-js/react'
import GoogleAnalytics from "@/components/GoogleAnalytics";
import { ThemeProvider as NTThemeProvider } from 'next-themes'
if (typeof window !== 'undefined') {
@ -18,4 +19,8 @@ export function GTagProvider() {
return process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS ? (
<GoogleAnalytics ga_id={process.env.NEXT_PUBLIC_GOOGLE_ANALYTICS} />
) : <></>
}
export function ThemeProvider({ children }) {
return <NTThemeProvider>{children}</NTThemeProvider>
}

View File

@ -1,30 +0,0 @@
---
title: "A Founder Message To Group Training Organisations"
subtitle: "Are you tired of the endless paperwork and manual processes that come with managing documents in your organization? It's time to revolutionize the way we handle these tasks and focus on what truly matters growing your business and nurturing your apprentices."
date: "2024-02-3"
image: "/images/a-founders-message-to-group-training-organisations-0.png"
---
Are you tired of the endless paperwork and manual processes that come with managing documents in your organization? It's time to revolutionize the way we handle these tasks and focus on what truly matters growing your business and nurturing your apprentices.
<div align="left">
<a href="https://youtu.be/mptgQKLQxFc">
<img src="https://img.youtube.com/vi/mptgQKLQxFc/0.jpg" style="width:75%;margin:0 auto;">
</a>
</div>
At Sign 365, we're on a mission to transform the document management landscape. We understand the struggles that Group Training Organizations (GTOs) across Australia face daily. The busy work of collecting apprentice information, scanning documents, and dealing with cumbersome contract signing processes can be overwhelming. That's why we're here to streamline these tasks and give you back your valuable time.
Imagine a world where supervisors can easily gather data on-site without the hassle of offline issues or complicated software. Where admin staff no longer spend countless hours inputting data into systems like Workforce One or various CRM and payroll systems. That's the world Sign 365 is creating.
# Built for Group Training Orginisations
Our first client, a medium-sized GTO with about 300 apprentices, faced these exact challenges. They needed a solution that was not only effective but simple for their supervisors to use. By working closely with them, we were able to automate their paper flow and reduce the time spent on manual data entry by an astounding 80%. That's turning 20 hours of work into just 4 hours a true game-changer.
Sign 365 isn't just an app; it's a powerful software designed to automate your systems, ensuring accuracy and eliminating the need for double-handling data. With our solution, information entered by supervisors on-site will seamlessly integrate into your existing systems, such as Workforce One or Xero.
# Upgraded Workflows
If you're interested in upgrading your workflow and freeing up time to focus on what's important, Sign 365 is the answer. Contact us at [hello@sign365.com.au](mailto:hello@sign365.com.au) to discuss how we can help you automate your paperwork and create a more efficient workflow for your organization. to discuss how we can help you automate your paperwork and create a more efficient workflow for your organization.
Let's work smarter, not harder, and let Sign 365 take the burden of paperwork off your shoulders. Reach out today and take the first step towards a more streamlined and productive future. Cheers to less paperwork and more progress!

View File

@ -1,42 +0,0 @@
---
title: "Adobe Fill and Sign vs Docusign"
subtitle: "Adobe Fill and Sign vs Docusign comparison"
date: "2021-08-14"
image: "/images/blog/adobedocusign.png"
---
In the digital age, eSignature solutions have become a necessity for businesses of all sizes. Two of the leading players in this field are Adobe Fill And Sign and DocuSign. This blog post will provide a comprehensive comparison of these two platforms, focusing on their features, document generation and management, security and compliance, integrations, and customer support.
## Features
Adobe Fill And Sign is a simple, straightforward tool that enables users to fill, sign, and send forms from their desktop or mobile device. It supports PDF, Word, and Excel formats, and allows users to create their own signature.
On the other hand, DocuSign offers a more robust set of features. In addition to eSignature capabilities, it provides advanced form tooling, which is particularly beneficial for small businesses. Users can create custom fields, set up automatic reminders, and track document status in real-time.
## Document Generation and Management Features
Adobe Fill And Sign allows users to upload documents from their device or cloud storage, fill them out, and sign them. However, it lacks advanced document management features.
DocuSign, in contrast, offers a comprehensive document management system. Users can generate, send, and manage documents from one central location. They can also set up workflows to automate the signing process, saving time and reducing errors.
## Security and Compliance
Both Adobe Fill And Sign and DocuSign prioritize security. They use encryption to protect documents and comply with global eSignature laws. However, DocuSign goes a step further by offering advanced security features like secure fields, audit trails, and multi-factor authentication.
## Integrations
Adobe Fill And Sign integrates with Adobe's own suite of products. DocuSign, however, offers a wider range of integrations, including popular business tools like Salesforce, Google Drive, and Microsoft Office 365. This makes it easier for small businesses to streamline their workflows and improve efficiency.
## Customer Support
Both platforms offer customer support, but DocuSign's support is more comprehensive. It includes 24/7 phone and email support, a knowledge base, and community forums.
## So Which eSignature Solution is Right for You?
While both Adobe Fill And Sign and DocuSign offer valuable eSignature solutions, DocuSign stands out for its advanced features, comprehensive document management, robust security, and wide range of integrations. It's particularly beneficial for small businesses that need better form tooling.
## Ready to Switch from Adobe Fill And Sign to DocuSign?
If you're a small business looking to streamline your document management and improve efficiency, DocuSign is the clear choice. Its advanced features and integrations make it a powerful tool for businesses of all sizes.
In conclusion, while Adobe Fill And Sign is a solid eSignature solution, DocuSign offers more comprehensive features that can help small businesses thrive in the digital age.

View File

@ -1,36 +0,0 @@
---
title: "Adobe Fill and Sign vs Sign Now"
subtitle: "I used GPT-3 to generate poetry and other creative content."
date: "2021-08-27"
image: "/images/blog/adobesignnow.png"
---
When it comes to digital document management and eSignature solutions, Adobe Fill And Sign and signNow are two of the leading contenders. But which one is the best fit for your small business? Let's delve into a detailed comparison to help you make an informed decision.
## Features
Adobe Fill And Sign offers a basic set of features, including form filling and signing, sending for signature, and tracking. However, signNow goes beyond the basics, providing advanced features like bulk sending, document groups, and conditional fields. These features make signNow a more robust and flexible solution, particularly for small businesses that need better form tooling.
## Document Generation and Management Features
Both Adobe Fill And Sign and signNow offer document generation and management features. However, signNow stands out with its superior form tooling capabilities. It allows users to create complex forms with ease, thanks to its intuitive and user-friendly interface. signNow's document management system is also more comprehensive, enabling users to organize, track, and store documents efficiently.
## Security and Compliance
Security is paramount in any eSignature solution. Both Adobe Fill And Sign and signNow offer robust security measures, including SSL encryption and compliance with global eSignature laws. However, signNow takes security a step further with its SOC 2 Type II certification, ensuring your documents are secure and your data is protected.
## Integrations
While Adobe Fill And Sign integrates with Adobe's suite of products, signNow offers a broader range of integrations. It seamlessly integrates with popular business tools like Salesforce, Google Suite, and Office 365, making it a more versatile solution for small businesses.
## Customer Support
Customer support is another critical factor to consider. While Adobe Fill And Sign offers basic support options, signNow offers 24/7 customer support, ensuring you get the help you need, whenever you need it.
## So Which eSignature Solution is Right for You?
When it comes to choosing the right eSignature solution for your small business, it's clear that signNow offers more advanced features, better form tooling, superior security, more integrations, and better customer support. It's a comprehensive solution designed to meet the unique needs of small businesses.
## Ready to Switch from Adobe Fill And Sign to signNow?
If you're ready to take your document management to the next level, it's time to switch to signNow. With its robust features, superior form tooling, and excellent customer support, signNow is the ideal eSignature solution for small businesses. Make the switch today and experience the signNow difference for yourself.

View File

@ -1,42 +0,0 @@
---
title: "Creating Custom Forms: A Step-by-Step Guide"
subtitle: "Creating custom forms for your day-to-day occupation in different industries particularly in businesses can be a valuable skill, yet many businesses struggle to find the right software to develop and use these forms effectively. In this blog post, we are going to dive into a powerful tool called Wondershare PDFelement that allows you to instantly create and customize your own PDF forms. Follow along as we break down the process step-by-step."
date: "2024-01-16"
image: "/images/creating-custom-forms-a-step-by-step-guide-0.png"
---
Creating custom forms for your day-to-day occupation in different industries particularly in businesses can be a valuable skill, yet many businesses struggle to find the right software to develop and use these forms effectively. In this blog post, we are going to dive into a powerful tool called Wondershare PDFelement that allows you to instantly create and customize your own PDF forms. Follow along as we break down the process step-by-step.
# Step 1: Downloading Wondershare PDFelement
To begin, search for "Wondershare PDFelement" on your preferred search engine. Visit the official website and click on the "Free Download" button. The software is available for both Mac and Windows systems. Once the download is complete, follow the prompts to install PDFelement on your computer.
![Step 1](/images/creating-custom-forms-a-step-by-step-guide-1.png)
# Step 2: Opening the PDF in PDFelement
Now that you successfully download the software. You can proceed to Open PDFelement, click on "Open a PDF," and locate the desired PDF you wanted to customize. Open the PDF in PDFelement and make any necessary adjustments to the layout or formatting.
![Step 2](/images/creating-custom-forms-a-step-by-step-guide-2.png)
# Step 3: Adding Form Elements
To make your PDF form fillable, you need to add form elements such as text fields and checkboxes. In PDFelement, select the form element you want to add, such as a checkbox, and overlay it onto your form. Adjust the sizing and position until it meets your requirements. Copy and paste the form element to add more fields as needed.
![Step 3](/images/creating-custom-forms-a-step-by-step-guide-3.png)
# Step 4: Customizing Form Elements and Naming Fields
To ensure each form element is unique and identifiable, customize the appearance and name of each field. Renaming fields is especially important if you plan to collect data using a form processing application like Sign 365. Double-check that each checkbox or text field has a unique name under the "General" tab in PDFelement.
![Step 4](/images/creating-custom-forms-a-step-by-step-guide-4.png)
# Step 5: Preview and Finalize Your Form
Once you have added all the necessary form elements, preview your form to ensure everything is functioning correctly. Make any additional adjustments to the layout or appearance if needed. Save your customized form in PDF format.
![Step 5](/images/creating-custom-forms-a-step-by-step-guide-5.png)
# Conclusion
Creating custom forms for your business or work doesn't have to be a daunting task. With tools like Wondershare PDFelement you can develop professional and user-friendly PDF forms. By following the steps outlined in this blog post, youll be able do well on your way to customs such forms that bring further value to your business.

View File

@ -1,40 +0,0 @@
---
title: "Docusign vs. signNow"
subtitle: "Docusign vs. signNow comparison"
date: "2021-08-14"
image: "/images/blog/docusignsignnow.png"
---
In the digital age, eSignature solutions have become a necessity for businesses of all sizes. Today, we're comparing two popular platforms: Adobe Fill And Sign and Sign365.
## Features
Adobe Fill And Sign offers a straightforward, user-friendly interface for signing documents. It allows users to fill, sign, and send forms quickly. However, it lacks advanced features like document tracking and custom branding.
On the other hand, Sign365 provides a comprehensive suite of features, including document tracking, custom branding, and bulk sending. It also offers a unique feature called 'conditional fields,' which allows you to customize your documents based on the recipient's responses.
## Document Generation and Management Features
Adobe Fill And Sign allows users to create and manage documents, but it lacks the advanced document generation and management features offered by Sign365. With Sign365, you can generate documents from templates, organize them into folders, and track their status in real-time.
## Security and Compliance
Both Adobe Fill And Sign and Sign365 prioritize security. Adobe uses Adobe Document Cloud to store documents, while Sign365 uses a secure cloud storage system. However, Sign365 goes a step further by offering advanced security features like two-factor authentication and audit trails.
## Integrations
Adobe Fill And Sign integrates with Adobe's suite of products but lacks integration with other business tools. Conversely, Sign365 integrates with a wide range of business tools, including Salesforce, Google Drive, and Dropbox, making it a more versatile solution.
## Customer Support
While Adobe offers customer support, some users have reported slow response times. Sign365, however, is known for its excellent customer support, offering 24/7 assistance via phone, email, and live chat.
## So Which eSignature Solution is Right for You?
If you're looking for a simple, user-friendly solution, Adobe Fill And Sign may be the right choice. However, if you need advanced features, integrations, and excellent customer support, Sign365 is the superior option.
## Ready to Switch from Adobe Fill And Sign to Sign365?
If you're ready to make the switch, Sign365 offers a seamless transition process. With its robust features, excellent customer support, and advanced security measures, Sign365 is a powerful eSignature solution that can meet the needs of any business.
In conclusion, while Adobe Fill And Sign offers a simple solution for signing documents, Sign365 provides a more comprehensive and versatile platform for businesses.

View File

@ -1,36 +0,0 @@
---
title: "Does Microsoft Forms Work Offline?"
subtitle: "CodeHouse is a leading provider of services for group training organizations in Australia, handling around 80% of these groups. Their expertise helps ensure that apprenticeship training is high quality and effective. "
date: "2024-02-6"
image: "/images/does-microsoft-forms-work-offline-0.png"
---
Microsoft Forms, previously known as Microsoft InfoPath, allows users to create and distribute forms that can be filled out online. However, Microsoft Forms itself does not have native offline capabilities. The service is designed to work in conjunction with other services like SharePoint and SQL databases, allowing forms to be filled out online and then synced back to the central database once an internet connection is restored.
# Microsoft Forms Doesn't Support Offline Data Collection
For scenarios where offline capabilities are needed, InfoPath, which is now deprecated, allowed users to design templates that could be filled out offline. These templates contained secondary data connections that provided data from an external database, and the forms could be filled out and later submitted when the user returned to a networked environment. The data required to fill out the forms had to be available locally, either within the form template or in a cache on the user's computer 1.
If you require offline functionality similar to what InfoPath offered, you would need to implement custom solutions or explore third-party tools that can replicate this behavior. As of my knowledge cutoff in April 2023, Microsoft has not released a successor to InfoPath with built-in offline capabilities. Therefore, for modern applications requiring offline form functionality, developers typically build mobile apps or web applications that sync data when online.
## What are some offline form options:
### Jotform:
Jotform emerges as a versatile solution, boasting an extensive array of templates that cater to diverse data collection needs. Its kiosk mode enhances user-friendliness in offline scenarios, ensuring that data collection remains unhindered. The platform supports both offline and online modes, allowing for seamless transitions between connectivity states. Jotform offers a free version that accommodates up to 5 forms, while more advanced features come at a cost of $39 USD/user/month. Additionally, the platform provides responsive chat and email support, enhancing its appeal for users seeking a comprehensive solution.
### Clappia:
Clappia takes a unique approach by offering users the ability to create custom apps tailored to their specific requirements. Beyond just forms, Clappia expands its utility by providing additional app options. This flexibility ensures that users can design solutions that go beyond standard form functionalities. Clappia's pricing structure includes a free option for a single form, with more advanced features available at $6 USD/user/month. The platform distinguishes itself further by offering responsive chat and email support, emphasizing its commitment to user satisfaction.
### Google Forms Synchronise:
For users deeply ingrained in the Google ecosystem, the Google Forms Synchronise option provides a bridge between the familiarity of Google Forms and the need for offline functionality. While this solution may serve adequately for those with moderate offline data collection requirements, its capabilities may not match the dedicated offline solutions offered by other alternatives.
### Sign365:
Sign365 stands out for its simplicity in user interface and customization options, making it a user-friendly choice for those seeking efficiency. By enabling the creation of custom forms using PDFs, Sign365 provides a straightforward integration step for transmitting data to systems once internet connectivity is restored. Priced at $5 AUD/user/month, the platform offers the enticing feature of unlimited forms, accompanied by the added advantage of phone support. This combination of simplicity, unlimited forms, and phone support positions Sign365 as an attractive choice for users seeking a cost-effective and well-supported solution.
## What Option is Best:
The decision-making process among these alternatives revolves around a careful consideration of specific needs, preferences, and constraints. Jotform, with its extensive templates, is an ideal choice for those seeking a feature-rich solution. On the other hand, Clappia appeals to users valuing the ability to create custom apps beyond traditional forms. Google Forms Synchronise caters to individuals deeply integrated into the Google ecosystem, offering a bridge between familiarity and offline functionality. Sign365, with its simplicity, unlimited forms, and phone support, presents a compelling choice for users looking for a cost-effective solution.

View File

@ -1,59 +0,0 @@
---
title: "Free Group Training Forms"
subtitle: "In the dynamic landscape of labor hire, efficiency is paramount, and innovation is the key to staying ahead. As forward-thinking pioneers in the industry, your commitment to streamlining processes is crucial. One way to achieve this is by leveraging the power of free templates and creating customized forms that meet the unique needs of your labor hire company. If you are interested in doing this keep reading and we will give you a special template to help you get started in your form filling."
date: "2024-01-19"
image: "/images/example-training-form-template-0.png"
---
In the dynamic landscape of labor hire, efficiency is paramount, and innovation is the key to staying ahead. As forward-thinking pioneers in the industry, your commitment to streamlining processes is crucial. One way to achieve this is by leveraging the power of free templates and creating customized forms that meet the unique needs of your labor hire company. If you are interested in doing this keep reading and we will give you a special template to help you get started in your form filling.
## The Power of Free Templates:
Free templates are invaluable resources for labor hire companies seeking simplicity and effectiveness in their operations. Whether you're onboarding new hires, conducting training sessions, or managing workforce logistics, having ready-made templates can significantly boost your efficiency. They serve as a solid foundation, allowing you to focus on what matters most your workforce.
## Building Templates on Canva: A Simple Guide:
1. **Accessing Canva:**
- Begin by visiting Canva's user-friendly platform.
- Sign in or create a new account to get started.
2. **Selecting a Template:**
- Explore Canva's extensive template library.
- Choose a category or use the search bar to find templates relevant to your labor hire business.
3. **Customizing Your Template:**
- Click on the chosen template to enter the editing interface.
- Replace placeholder text with your labor hire company's details.
- Add your logo for a branded touch.
4. **Incorporating Elements:**
- Enhance your template by adding elements such as images, icons, or dividers.
- Ensure the design aligns with your company's aesthetic.
5. **Saving and Sharing:**
- Once satisfied with your template, save it.
- Share the template link with your team or download it for future use.
## Seamless Workflow, Empowered Workforce:
By harnessing the capabilities of Canva, you're not just creating forms; you're paving the way for a more streamlined workflow. Imagine a process where onboarding and training become seamless, allowing you to focus on the growth and development of your workforce. Canva's intuitive interface ensures that you don't need to be a design expert simplicity is at the core of their platform. If you are a visual person you should also check out a video tutorial to do it:
<div align="left">
<a href="https://youtu.be/VbHeItF1N7M?si=U8Czc5lPi01-vHfy">
<img src="https://img.youtube.com/vi/VbHeItF1N7M/0.jpg" style="width:75%;margin:0 auto;">
</a>
</div>
## A Template Offer for You:
As a gesture of support to fellow labor hire companies, we are excited to offer a free group training form template on Canva. This template is crafted with simplicity and functionality in mind, designed to make your training sessions more efficient. To access this complimentary template, simply [right click this link > save link as](/assets/training-form.pdf) and download it.
<img src="/images/example-training-form-template-1.png" alt="Example Form" width="200" style="margin:0 auto;"/>
## In Conclusion:
As pioneers in the labor hire industry, embracing innovation is the pathway to success. Utilizing free templates on Canva is a step towards a more efficient and streamlined operation. Empower your labor hire business by simplifying your processes and focusing on what truly matters building a skilled and motivated workforce. Your journey to seamless operations begins with a template. Try Canva today and experience the transformative power of simplicity in design.

View File

@ -1,38 +0,0 @@
---
title: "How we reduced supervisor paperwork by 80% "
subtitle: "For Group Training Organizations (GTOs) across Regional Australia, the challenge of managing surveys and site visits, and collecting information, has never been more pressing. Amidst rising employee costs and growing administrative overhead, Sign365 has emerged as a forward-thinking solution to automate and digitise your document and signing process, propelling businesses towards a future where document workflows are not just streamlined, but seamless."
date: "2024-02-01"
image: "/images/how-sign365-reduced-supervisor-form-processing-by-80-percent-0.png"
---
For Group Training Organizations (GTOs) across Regional Australia, the challenge of managing surveys and site visits, and collecting information, has never been more pressing. Amidst rising employee costs and growing administrative overhead, Sign365 has emerged as a forward-thinking solution to automate and digitise your document and signing process, propelling businesses towards a future where document workflows are not just streamlined, but seamless.
# Context and Challenge
In 2018 we saw that many organisations were struggling with the amount of paperwork they were doing. With offline Google forms and related offline form software lagging behind in the ability to provide an easy custom form experience, we looked to make a system to reduce time in how GTOs performed administrative tasks. Our encounters with clients revealed a single, glaring constraint: the exponential time drained in transmuting information from offline forms into payroll systems, a fundamental operation for the continued functioning of these organizations.
This complexity translated into an incessant cycle of validating, checking, and locating documents, encapsulating precious time in tasks that, although crucial to the business's heartbeat, did not require the expertise of its workforce. The rising post-COVID employee costs predicted for the coming years only intensified the need for a sustainable resolution.
# Solution: Sign365 at Your Service
The inception of Sign365 was to address these exact predicaments. It sprung forth as a data entry automation tool specifically designed for iPadOS, offering a triad of benefits: error management, document tracking, and cross-system document administration. By allowing the creation of customized, actionable forms that directly feed into business applications in defined ways, Sign365 streamlined the once-tedious workflow, liberating administrators from the clutches of mundane, repetitive tasks.
The statistics were evident, with studies showcasing that 59% to 60% of knowledge workers craved automation in day-to-day operations like data input and email management. Sign365's philosophy pivoted on transitioning administrators from data processors to data overseers. This strategic repurposing saw a significant reduction in time spent on data entry tasks, with clients reclaiming 1-2 hours per day that traditionally squandered on manual form management.
# Business Impact and Results
Our implementation of Sign365 within a prominent GTO marked a turning point. By seamlessly integrating into their hefty payroll management system, we mitigated the arduous process of onboarding and assessing trainees through offline forms, promoting the effortless migration of documents. The augmentation enabled by Sign365s robust reporting tools granted unparalleled visibility into the client's informational flow.
Furthermore, the data substantiates the transformative power of transitioning from human to machine-processed data—the reduction in error rates from 40% to a mere 1% alone echoes the magnitude of this shift, not to mention the curtailing of costs associated to human error, which could accrue to an average of $3000 per incident.
# Looking to the Future
The trajectory of staff employment costs rings a bell of impending challenges—with the Conference Board forecasting a steep rise in wages, the highest since 2008, the onus is on businesses to wield tools like Sign365 to recoup their investments in human capital.
Sign365 has laid the groundwork for a paradigm shift in processing offline forms. By extricating workers from the shackles of redundant tasks and enabling direct transmission of documented information to business apps, the platform has catalyzed a significant contraction in overhead, leading to monumental savings in time and financial resources.
# Invitation to Action
Is your document workflow streamlined? Is it seamless? As pioneers in the industry, we invite you to experience the world where offline form automation is not just a possibility but a reality. Try Sign365 and join a myriad of organizations in Regional Australia redefining their administrative landscape, making every second count, every form process matter—seamlessly.
Sited Sources [Refer to provided text]

View File

@ -1,26 +0,0 @@
---
title: "How to Electronically Fill A Document"
subtitle: "Are you tired of the endless cycle of printing, signing, and scanning documents? Do you find yourself spending more time on paperwork than on the tasks that truly matter to your business? If so, it's time to discover the game-changing solution that is Sign365."
date: "2024-01-25"
image: "/images/how-to-electronically-fill-a-document-0.png"
---
Are you tired of the endless cycle of printing, signing, and scanning documents? Do you find yourself spending more time on paperwork than on the tasks that truly matter to your business? If so, it's time to discover the game-changing solution that is Sign365.
Sign365 is an innovative app designed to simplify and expedite the document signing process. With Sign365, you can easily upload and sign documents, ensuring a smooth and efficient workflow that saves you time and resources. This powerful tool is perfect for businesses looking to secure that all-important AAA client and streamline their administrative tasks.
The user-friendly interface of Sign365 welcomes you with a prompt to add a form, making it straightforward to get started. Once you've added a form, filling it out is a breeze. The app guides you through each section, ensuring that every box is ticked and every signature is captured accurately.
One of the standout features of Sign365 is its customization options. Supervisors can rename forms to better suit their needs, making organization a snap. Additionally, Sign365 integrates seamlessly with popular Group Training software like Workforce One, which is widely used in Australia for payroll management. This integration means that completed forms can be sent directly to the relevant area, be it an apprentice's file or a host client's records, with minimal effort on your part.
<div align="left">
<a href="https://youtu.be/O8P_bkinn-A">
<img src="https://img.youtube.com/vi/O8P_bkinn-A/0.jpg" style="width:75%;margin:0 auto;">
</a>
</div>
But it's not just about convenience. Sign365 is also about significant time and cost savings. One of our Group Training Organizations (GTOs) reported an astonishing 80% reduction in administrative processing time. This translates to a considerable amount of money saved, allowing businesses to reinvest in areas that truly impact their growth, such as acquiring more apprentices.
In summary, Sign365 is more than just a document signing app—it's a comprehensive solution that alleviates the administrative burden, enhances efficiency, and ultimately contributes to the success of your business. Say goodbye to the hassle of traditional document handling and embrace the simplicity and effectiveness of Sign365.
Experience the difference for yourself and take the first step towards a more productive and profitable future. With Sign365, you're not just signing documents; you're signing up for success.

View File

@ -1,28 +0,0 @@
---
title: "Streamlining Apprenticeship Training with CodeHouse Workforce One"
subtitle: "CodeHouse is a leading provider of services for group training organizations in Australia, handling around 80% of these groups. Their expertise helps ensure that apprenticeship training is high quality and effective. "
date: "2024-02-6"
image: "/images/how-to-setup-supervisor-forms-with-workforce-one-0.png"
---
CodeHouse is a leading provider of services for group training organizations in Australia, handling around 80% of these groups. Their expertise helps ensure that apprenticeship training is high quality and effective.
# Payroll Management Simplified
[Workforce One](https://www.workforceone.com.au/) is a service provided by CodeHouse that makes managing payroll for apprentices easier. It's a tool that helps keep track of money spent on apprenticeship training, allowing organizations to focus on teaching and learning.
# Creating Surveys and Questionnaires
[Workforce One](https://www.workforceone.com.au/) lets you create your own surveys and questionnaires right inside the system. This is useful for getting feedback from supervisors and apprentices, helping to make sure that the training is going well. It is able to do this online with it's own in built systems that directly link to Workforce One
# Offline Solutions
If you need to work without an internet connection, CodeHouse has partnered with Sign365. It's a tool that works like paper but is easier to use and safer. It keeps important information safe and organized, no matter if you're connected to the internet or not. It does this by using your iPhone or iPad to store your forms until you get back online where it will automatically send those forms to Workforce One
# Automating Tasks
Sign365 can also connect with other systems, making it easier to work with different tools. This helps save time and reduce mistakes, making everything run more smoothly. Most tasks that you do to get useful documents are not necessary with Sign365's automation tools. You will be able to save 20 hours or more per staff member per week
# Conclusion
Choosing the right payroll management system is important for running successful apprenticeship programs. CodeHouse [Workforce One](https://www.workforceone.com.au/), along with Sign365, gives organizations the tools they need to manage payroll, collect feedback, and work efficiently. This helps ensure that apprentices get the best training possible.

View File

@ -1,62 +0,0 @@
---
title: "How to use Google Forms offline?"
subtitle: "We'll explore the various solutions available for offline data collection in Google Forms. We'll delve into the intricacies of Google Forms, including its limitations and how to overcome them. We'll also explore the various alternatives available for offline data collection."
date: "2024-01-15"
image: "https://images2.imgbox.com/91/e5/zDzlf3s5_o.png"
---
In today's data-driven landscape, the seamless collection of information is a critical component for individuals and organizations. However, the omnipresence of internet connectivity is not guaranteed, leading to challenges in situations where offline data collection becomes necessary. In this article, we delve into the complexities of offline data collection, exploring solutions beyond the limitations of popular tools like Google Forms. From understanding the nature of offline and online forms to evaluating various alternatives, we aim to provide a comprehensive guide for those seeking efficient methods of data gathering regardless of their connectivity status.
## Can Google Forms be used offline?
Google Forms, a widely utilized platform for creating surveys and forms, has earned its popularity for its ease of use and integration with other Google services. However, its Achilles' heel lies in its dependency on internet connectivity. When faced with the need for offline data collection, Google Forms may not be the most reliable solution. This limitation prompts us to explore alternative avenues that specifically cater to the challenges of offline environments.
## What is an offline form?
Before we delve into alternatives, it's essential to understand what constitutes an offline form. In essence, an offline form is a digital or physical document designed to collect information in environments where a stable internet connection cannot be guaranteed. These forms empower users to capture and store data locally, providing a workaround for situations where real-time online interactions are not feasible.
## What is an online form?
In contrast, an online form relies on consistent internet connectivity to capture and transmit data in real-time. While effective in connected environments, these forms face limitations when deployed in offline scenarios. Understanding the distinction between online and offline forms is crucial for selecting the right tool for the job.
## What are some offline form options:
### Jotform:
Jotform emerges as a versatile solution, boasting an extensive array of templates that cater to diverse data collection needs. Its kiosk mode enhances user-friendliness in offline scenarios, ensuring that data collection remains unhindered. The platform supports both offline and online modes, allowing for seamless transitions between connectivity states. Jotform offers a free version that accommodates up to 5 forms, while more advanced features come at a cost of $39 USD/user/month. Additionally, the platform provides responsive chat and email support, enhancing its appeal for users seeking a comprehensive solution.
### Clappia:
Clappia takes a unique approach by offering users the ability to create custom apps tailored to their specific requirements. Beyond just forms, Clappia expands its utility by providing additional app options. This flexibility ensures that users can design solutions that go beyond standard form functionalities. Clappia's pricing structure includes a free option for a single form, with more advanced features available at $6 USD/user/month. The platform distinguishes itself further by offering responsive chat and email support, emphasizing its commitment to user satisfaction.
### Google Forms Synchronise:
For users deeply ingrained in the Google ecosystem, the Google Forms Synchronise option provides a bridge between the familiarity of Google Forms and the need for offline functionality. While this solution may serve adequately for those with moderate offline data collection requirements, its capabilities may not match the dedicated offline solutions offered by other alternatives.
### Sign365:
Sign365 stands out for its simplicity in user interface and customization options, making it a user-friendly choice for those seeking efficiency. By enabling the creation of custom forms using PDFs, Sign365 provides a straightforward integration step for transmitting data to systems once internet connectivity is restored. Priced at $5 AUD/user/month, the platform offers the enticing feature of unlimited forms, accompanied by the added advantage of phone support. This combination of simplicity, unlimited forms, and phone support positions Sign365 as an attractive choice for users seeking a cost-effective and well-supported solution.
## What Option is Best:
The decision-making process among these alternatives revolves around a careful consideration of specific needs, preferences, and constraints. Jotform, with its extensive templates, is an ideal choice for those seeking a feature-rich solution. On the other hand, Clappia appeals to users valuing the ability to create custom apps beyond traditional forms. Google Forms Synchronise caters to individuals deeply integrated into the Google ecosystem, offering a bridge between familiarity and offline functionality. Sign365, with its simplicity, unlimited forms, and phone support, presents a compelling choice for users looking for a cost-effective solution.
### Digging Deeper into Alternatives:
Beyond the outlined options, it's essential to consider additional factors that might influence the decision-making process. Integration capabilities, scalability, and security features are crucial aspects to evaluate.
### Integration Capabilities:
Jotform and Clappia offer integrations that enhance their capabilities. The ability to seamlessly connect with other tools and systems can significantly streamline workflows, providing a more comprehensive solution for users with complex data management needs.
### Scalability:
Consideration of scalability is paramount, especially for organizations experiencing growth. Clappia, with its custom app creation feature, may provide a scalable solution tailored to evolving requirements. Jotform's diverse template library also contributes to its scalability, accommodating a range of data collection needs.
### Security Features:
As data security becomes an increasingly important concern, examining the security features of each platform is crucial. Users handling sensitive information may prioritize platforms that offer robust security measures. Ensuring compliance with data protection regulations is imperative, and understanding how each platform handles data encryption and storage is essential.
## Conclusion:
In conclusion, the quest for the best offline data collection solution requires a nuanced understanding of individual needs and preferences. The alternatives explored - Jotform, Clappia, Google Forms Synchronise, and Sign365 - each bring unique strengths to the table. The decision-making process involves a delicate balance between functionality, pricing, and support. Additionally, factors such as integration capabilities, scalability, and security features contribute to the overall suitability of each platform for diverse use cases. As technology continues to evolve, users can expect more innovative solutions that further enhance the efficiency and effectiveness of offline data collection.

View File

@ -1,59 +0,0 @@
---
title: "Sign365 vs Adobe Fill and Sign"
subtitle: "Sign365 vs Adobe Fill and Sign comparison"
date: "2020-12-27"
image: "/images/blog/sign365adobe.png"
---
Over the last few years, Adobe has been pushing for a new way to sign documents. Called fill and Sign. This is 100% free and is a fantastic way to sign documents. The problem is for admin staff there is no way to manage the documents that are coming through in a centralized way. Furthermore offline signing and management isn't well supported in Adobe fill and sign.
In the digital age, eSignature solutions have become an essential tool for businesses. Two popular options are Adobe Fill And Sign and Sign365. But which one is the best offline, in-person document signing tool for businesses? Let's delve into the details.
# Features
Adobe Fill And Sign offers a simple and intuitive interface that allows users to fill, sign, and send forms quickly. It supports various file formats and enables users to create personalized signatures. However, it lacks advanced features like document tracking and multi-user collaboration.
✅ Electronic document signing
✅ In-person signature collection via a mobile device
✅ Easy-to-use fillable forms
✅ Basic PDF editing tools
✅ Mobile-friendly signing
On the other hand, Sign365 stands out with its robust features. It offers offline, in-person signing, document tracking, multi-user collaboration, and more. It also supports a wide range of file formats and allows users to create personalized signatures.
✅ Electronic document signing
✅ Offline signing and document routing
✅ Configuring document routing
✅ In-person signature collection via a mobile device
✅ Automatic reminders and notifications
✅ Easy-to-use fillable forms
✅ Data validation for fillable fields
✅ Basic PDF editing tools
✅ Managing documents in the cloud
✅ Reusable templates
✅ Audit Trail and document history
✅ Mobile-friendly signing (iOS only for Sign365)
# Document Generation and Management Features
Adobe Fill And Sign provides basic document generation and management features. It allows users to fill and sign documents but lacks advanced document management features like version control and document tracking.
Sign365, however, offers comprehensive document generation and management features. It not only allows users to fill and sign documents but also provides version control, document tracking, and multi-user collaboration. These features make it easier for businesses to manage their documents efficiently.
# Security and Compliance
Both Adobe Fill And Sign and Sign365 prioritize security and compliance. Adobe Fill And Sign uses Adobe's secure cloud services to store documents, while Sign365 uses Microsoft's secure cloud services. Both solutions comply with major regulations like GDPR and HIPAA.
# Integrations
Adobe Fill And Sign integrates with Adobe's suite of products, but it lacks integration with other popular business tools. Sign365, however, integrates seamlessly with a wide range of business tools, including Microsoft Office, Google Workspace, and more.
# Customer Support
Adobe Fill And Sign offers customer support via email and community forums. Sign365, however, provides Perth based customer services with a focus on client relations ensuring that your needs are personally dealt with.
# So Which eSignature Solution is Right for You?
While both Adobe Fill And Sign and Sign365 offer valuable features, Sign365 stands out as the best offline, in-person document signing tool for businesses. Its robust document generation and management features, seamless integrations, and excellent customer support make it a superior choice for businesses of all sizes.
# Ready to Switch from Adobe Fill And Sign to Sign365?
If you're ready to switch from Adobe Fill And Sign to Sign365, you're making a wise decision. Sign365 offers more advanced features, better integrations, and superior customer support. Plus, its offline, in-person signing capability makes it the perfect tool for businesses that need to sign documents in person. Make the switch today and take your document signing process to the next level with Sign365.

View File

@ -1,132 +0,0 @@
---
title: "Sign365 vs Docusign"
subtitle: "Sign365 vs Docusign comparison"
date: "2023-01-27"
image: "/images/blog/sign365docusign.png"
author: "Samuel Wyndham"
---
When it comes to eSignatures, Sign365 stands out as a top-notch solution, which while not comparable to industry giants like DocuSign. Offers a robust alternative, catering more to small and medium-sized businesses who need to sign documents offline and need a simple user interface to do it
Sign365 excels in delivering powerful eSignature capabilities at competitive prices, making it a strong contender against DocuSign for businesses who just need simplicity. Particularly suited for daily business needs, its offline functionality on iOS, coupled with streamlined data integration and rapid data input, positions it as a favorable choice.
**Note:** Seeking an efficient eSignature solution for your business? Explore Sign365, a compelling alternative to DocuSign.
# Product overview: DocuSign vs. Sign365
✅ DocuSign, an established player since 2003, has solidified its position as a leading eSignature solution with a massive global user base. Widely adopted in finance, healthcare, life sciences, and real estate, DocuSign boasts a refined interface and robust functionalities, albeit at a premium price point compared to competitors, often charging extra for advanced features.
✅ Sign365 emerges as a strong contender, especially tailored for the GTO (Group Training Organisation) market seeking modern PDF solutions. Built from the ground up as a modern PDF app, Sign365 caters specifically to businesses aiming to capture, report, and automate their data seamlessly. Positioned as an efficient tool for businesses looking to digitize their document workflows and streamline operations, Sign365 marks a purpose-driven approach towards facilitating efficient data handling for modern enterprises.
In the battle between eSignature solutions, while DocuSign reigns with its established reputation and features, Sign365 offers a focused, tailor-made approach for businesses seeking optimized data management solutions within the GTO landscape.
# Pricing
Sign365 simplifies its pricing into three tiers: Business Basic, Business Premium, and Business Ultimate. Business Basic suits small teams with its app-based document signing, fillable fields, and customizable templates. Business Premium adds advanced reporting and prebuilt automation, while Business Ultimate includes everything in Premium, along with tailored custom automations for complex needs. Sign365 permits allowing additional user seats taylored to your business growth (think as many as possible), allowing scalability for growing teams.
Contrastingly, DocuSign provides four subscription tiers with limited publicly available information and allows up to 5 user seats per subscription, starting from the Standard plan. However, DocuSign lacks transparent pricing for its highest-tier subscription, determining costs on a per-customer basis.
![Sign365 vs SignNow pricing](https://images2.imgbox.com/95/b0/oph3L49U_o.png)
# Features
In terms of technology, DocuSign is rightfully considered the industry leader. Over 20 years of continuous development and innovations allowed the product to grow into an advanced contract management platform suited to the largest of enterprises.
Meanwhile, Sign365 isnt lagging far behind. Users across multiple review platforms confirm that Sign365 has everything they need to get documents signed electronically at a much lower price than DocuSign. Furthermore where Sign365 shines is in its ability to do offline signing and workflow tagging to ensure your data reaches the right places
eSignature features
Both Sign365 and DocuSign offer all the standard features you would expect from an eSignature app:
✅ Electronic document signing
✅ Configuring document routing
✅ In-person signature collection via a mobile device
✅ Automatic reminders and notifications
✅ Easy-to-use fillable forms
✅ Data validation for fillable fields
✅ Basic PDF editing tools
✅ Managing documents in the cloud
✅ Reusable templates
✅ Audit Trail and document history
✅ Mobile-friendly signing (iOS only for Sign365)
Both products support an array of enterprise-grade features, including:
✅ Admin dashboard for managing multiple user accounts
✅ Collaboration tools and asset sharing
✅ Custom branding
✅ Rich API for seamless integration with any stack
On top of that, DocuSign boasts some features that Sign365 is currently lacking:
✅ Sending documents for eSignature to one or multiple recipients
✅ Payment collection
✅ Bulk-sending documents for signature
✅ Signature collection via shareable links
✅ Real-time signature tracking
✅ Signing groups
✅ Setting a signing order
✅ Assigning and configuring signer roles
✅ Business fields
✅ Document markup and collaborative fields
✅ Smart sections
✅ Self-service web forms
✅ Signer identity verification
✅ Cloud signatures
✅ Requesting attachments
✅ QES (qualified electronic signatures)
Enhanced capabilities for digital signature make DocuSign a more suitable solution for highly regulated industries and countries where specific methods of identity validation are required. However, Sign365 is already taking steps toward closing that gap by introducing PKI-based digital signatures (AES). Therefore, if you are looking to collect authentic digital signatures verified by unique ID certificates and have offline functionality, you may find Sign365 to be a viable alternative to DocuSign.
# Document generation and management features
Both Sign365 and DocuSign enable users to upload documents from various sources, preparing them for signatures using basic editing tools and a range of fillable fields. These platforms allow easy modification of documents by adding elements like text, date, checkmarks, signatures, initials, stamps, and fillable fields. Furthermore, users can convert a fillable form into a reusable template, store it within their account, or export it to the cloud.
However, if advanced document generation and management tools are required, the options differ between Sign365 and DocuSign. Unlike DocuSign, Sign365 does not include document generation capabilities in any of its subscription plans. Both platforms, however, offer additional solutions for enhanced document management, available at an additional cost.
DocuSign provides intelligent automation systems specifically designed for agreement generation and management:
✅ DocuSign CLM: A contract lifecycle management system for generating, negotiating, and automating agreement workflows, along with centralized agreement storage and searches.
✅ DocuSign Negotiate: A solution automating the generation, negotiation, and approval of agreements within your CRM.
✅ DocuSign Gen: Automation of agreement generation within your CRM.
✅ DocuSign Click: Enables embedding consent capture to agreement terms on websites and apps.
✅ Intelligent Insights by Seal Software: AI-driven concept searching, clause identification, and analytics.
✅ Guided Forms by Intelledox: A user-friendly “wizard-style” experience replacing complex forms.
In summary, Sign365 primarily focuses on eSignature capabilities. DocuSign, however, incorporates intelligent automation systems tailored for agreement generation and management purposes.
# Security and compliance
Is Sign365 as legitimate as DocuSign? Absolutely. Both Sign365 and DocuSign provide legally-binding electronic signatures that hold up in courts within the US, Europe, and other regions globally where eSignatures are accepted. Sign365 and DocuSign adhere to the following standards and regulations:
✅ ESIGN (Electronic Signatures in Global and National Commerce Act)
✅ UETA (Uniform Electronic Transactions Act)
✅ eIDAS (electronic IDentification, Authentication and trust Services)
✅ GDPR (General Data Protection Regulation)
✅ CCPA (California Consumers Protection Act of 2018)
# Integrations
Integrations are crucial for constructing efficient and seamless eSignature workflows within various software environments, and both Sign365 and DocuSign recognize this significance.
Throughout its extensive history, DocuSign has amassed a relatively wider array of pre-built integrations. Nevertheless, Sign365 integrations are well-suited for the most popular CRM systems, productivity applications, and cloud storage services.
In addition to their off-the-shelf integrations, both companies provide robust APIs and connections via Zapier. This implies virtually limitless possibilities for constructing customized eSignature workflows.
# Customer support
Customer support is key for both Sign365 and Docusign with Docusign offering various self-service options.
In terms of support options, both DocuSign and Sign365 offer live chat and ticket-based assistance. Sign365 distinguishes itself by providing phone support and personal integration support specifically catered to customers with its top-tier subscription.
Notably, the key distinction between DocuSign and Sign365 lies in their customer service approach. Sign365 has all customer service operations located in Australia, emphasizing in-person service and prioritizing the customer experience as a primary focus. This approach aligns with Sign365's belief that placing the customer first is paramount. Conversely, DocuSign has transformed its customer service into a separate paid product, offering enhanced support plans featuring additional channels and improved response times for an extra fee.
# So which eSignature solution is right for you?
Both Sign365 and DocuSign serve as excellent tools that streamline daily operations and reduce the time spent on paperwork. DocuSign caters best to larger companies seeking its innovative features and willing to make substantial investments. Enterprises stand to gain from DocuSign's AI-driven contract management solutions, advanced compliances, and a wide array of pre-built integrations.
While DocuSign remains at the forefront of the market, Sign365 is steadily broadening its scope within the enterprise segment. The company is continually enhancing its value-added features tailored for organizations of all sizes and refining its API, facilitating integration with a broader range of products into its eSignature software.
For those seeking a more cost-effective alternative to DocuSign, Sign365 offers significant value at a reduced cost. With robust eSignature functionality, high standards of security and compliance, and transparent pricing, Sign365 boasts numerous success stories from satisfied customers
# Ready to switch from DocuSign to Sign365?
Sign365 ensures a painless transition. You can migrate from DocuSign to Sign365 hassle-free by contacting our customer support today

View File

@ -1,133 +0,0 @@
---
title: "Sign365 vs signNow"
subtitle: "Sign365 vs signNow comparison"
date: "2023-01-27"
image: "/images/blog/sign365signnow.png"
author: "Samuel Wyndham"
---
When it comes to eSignatures, Sign365 stands out as a top-notch solution, comparable to industry giants like signNow. While signNow has long dominated the field, especially among enterprise clients, Sign365 offers a robust alternative, catering more to small and medium-sized businesses.
Sign365 excels in delivering powerful eSignature capabilities at competitive prices, making it a strong contender against signNow. Particularly suited for daily business needs, its offline functionality on iOS, coupled with streamlined data integration and rapid data input, positions it as a favorable choice.
**Note:** Seeking an efficient eSignature solution for your business? Explore Sign365, a compelling alternative to signNow.
# Product overview: signNow vs. Sign365
✅ signNow: Established as an eSignature solution, signNow has gained prominence for its intuitive interface and ease of use. It's well-suited for businesses of varying sizes and industries, providing a comprehensive range of features to streamline document signing processes. signNow's platform emphasizes seamless integrations, document management, and user-friendly functionalities.
✅ Sign365: Tailored for Group Training Organizations (GTOs), Sign365 focuses on modern PDF solutions, aiming to capture, report, and automate data efficiently. It caters specifically to businesses seeking to digitize document workflows and streamline operations. Sign365's core strength lies in its data management capabilities and offline functionality on iOS devices, facilitating efficient document handling.
In comparing Sign365 and signNow, while both offer eSignature solutions, Sign365 targets a niche market with specialized features, whereas signNow caters to a broader audience, emphasizing its ease of use and integrations.
# Pricing
Sign365 Offers three pricing tiers - Business Basic, Business Premium, and Business Ultimate, each with varying features catering to different business needs. The plans are designed for scalability, allowing additional user seats taylored to your business growth (think as many as possible), making it suitable for growing teams within the GTO landscape.
signNow: signNow offers a tiered pricing model based on user requirements, catering to individual users, small businesses, and larger enterprises. The pricing structure includes features such as document sending, templates, and custom branding. signNow allows for an additional 10 seats.
![Sign365 vs signNow pricing](https://images2.imgbox.com/91/69/xUj8Oa8o_o.png)
# Features
In terms of technology, signNow is rightfully considered the more comprehensive e-signature soltion. Over years of continuous development and innovation, signNow has evolved into an advanced contract management platform suitable for enterprises of all sizes.
Meanwhile, Sign365 isnt lagging far behind. Users across multiple review platforms confirm that Sign365 has everything they need to get documents signed electronically at a much lower price than signNow. Furthermore, where Sign365 shines is in its ability to perform offline signing and workflow tagging to ensure data reaches the right places.
Both Sign365 and signNow offer all the standard features you would expect from an eSignature app:
✅ Electronic document signing
✅ Configuring document routing
✅ In-person signature collection via a mobile device
✅ Automatic reminders and notifications
✅ Easy-to-use fillable forms
✅ Data validation for fillable fields
✅ Basic PDF editing tools
✅ Managing documents in the cloud
✅ Reusable templates
✅ Audit Trail and document history
✅ Mobile-friendly signing (iOS only for Sign365)
Both products support an array of enterprise-grade features, including:
✅ Admin dashboard for managing multiple user accounts
✅ Collaboration tools and asset sharing
✅ Custom branding
✅ Rich API for seamless integration with any stack
On top of that, signNow boasts some features that Sign365 is currently lacking:
✅ Bulk-sending documents for signature
✅ Real-time signature tracking
✅ Sending documents for eSignature to one or multiple recipients
✅ Signature collection via shareable links
✅ Signing groups
✅ Setting a signing order
✅ Payment collection
✅ Assigning and configuring signer roles
✅ Business fields
✅ Document markup and collaborative fields
✅ Smart sections
✅ Self-service web forms
✅ Signer identity verification
✅ Cloud signatures
✅ Requesting attachments
✅ QES (qualified electronic signatures)
Enhanced capabilities for digital signature make signNow a more suitable solution for highly regulated industries and countries where specific methods of identity validation are required. However, Sign365 is already taking steps toward closing that gap by introducing PKI-based digital signatures (AES). Therefore, if you are looking to collect authentic digital signatures verified by unique ID certificates and have offline functionality, you may find Sign365 to be a viable alternative to signNow.
# Document generation and management features
Both Sign365 and signNow enable users to upload documents from various sources, preparing them for signatures using basic editing tools and a range of fillable fields. These platforms allow easy modification of documents by adding elements like text, date, checkmarks, signatures, initials, stamps, and fillable fields. Furthermore, users can convert a fillable form into a reusable template, store it within their account, or export it to the cloud.
However, if advanced document generation and management tools are required, the options differ between Sign365 and signNow. Unlike signNow, Sign365 does not include document generation capabilities in any of its subscription plans. signNow provides these features through a suite of products offering enhanced document management solutions, available at an additional cost.
signNow offers intelligent automation systems specifically designed for agreement generation and management:
✅ signNow CLM: A contract lifecycle management system for generating, negotiating, and automating agreement workflows, along with centralized agreement storage and searches.
✅ signNow Negotiate: A solution automating the generation, negotiation, and approval of agreements within your CRM.
✅ signNow Gen: Automation of agreement generation within your CRM.
✅ signNow Click: Enables embedding consent capture to agreement terms on websites and apps.
✅ Intelligent Insights by Seal Software: AI-driven concept searching, clause identification, and analytics.
✅ Guided Forms by Intelledox: A user-friendly “wizard-style” experience replacing complex forms.
In summary, Sign365 primarily focuses on eSignature capabilities. signNow, however, incorporates intelligent automation systems tailored for agreement generation and management purposes through its suite of products.
# Security and compliance
Is Sign365 as legitimate as signNow? Absolutely. Both Sign365 and signNow provide legally-binding electronic signatures that hold up in courts within the US, Europe, and other regions globally where eSignatures are accepted. Sign365 and signNow adhere to the following standards and regulations:
✅ ESIGN (Electronic Signatures in Global and National Commerce Act)
✅ UETA (Uniform Electronic Transactions Act)
✅ eIDAS (electronic IDentification, Authentication, and trust Services)
✅ GDPR (General Data Protection Regulation)
✅ CCPA (California Consumers Protection Act of 2018)
# Integrations
Integrations are crucial for constructing efficient and seamless eSignature workflows within various software environments, and both Sign365 and signNow recognize this significance.
Throughout its extensive history, signNow has amassed a relatively wider array of pre-built integrations. Nevertheless, Sign365 integrations are well-suited for the most popular CRM systems, productivity applications, and cloud storage services.
In addition to their off-the-shelf integrations, both companies provide robust APIs and connections via Zapier. This implies virtually limitless possibilities for constructing customized eSignature workflows.
# Customer support
Customer support is key for both Sign365 and signNow, with signNow offering various self-service options.
In terms of support options, both signNow and Sign365 offer live chat and ticket-based assistance. Sign365 distinguishes itself by providing phone support and personal integration support specifically catered to customers with its top-tier subscription.
Notably, the key distinction between signNow and Sign365 lies in their customer service approach. Sign365 has all customer service operations located in Australia, emphasizing in-person service and prioritizing the customer experience as a primary focus. This approach aligns with Sign365's belief that placing the customer first is paramount. Conversely, signNow has transformed its customer service into a separate paid product, offering enhanced support plans featuring additional channels and improved response times for an extra fee.
# So which eSignature solution is right for you?
Both Sign365 and signNow serve as excellent tools that streamline daily operations and reduce the time spent on paperwork. signNow caters best to larger companies seeking a more comprehensive suite of features and willing to make substantial investments. Enterprises benefit from signNow's comprehensive suite that includes AI-driven contract management solutions, advanced compliances, and a wide array of pre-built integrations.
While signNow remains at the forefront of the market with its comprehensive offerings, Sign365 focuses primarily on creating a great eSignature experience with a ground-up approach to integrations and emphasizing its offline functionality. Sign365's best competing point is their approach to integrations and their offline functionality, aiming to provide a streamlined and user-friendly experience specifically tailored to different business needs.
The company, Sign365, is steadily broadening its scope within the enterprise segment, continually enhancing its eSignature functionalities, and refining its API for seamless integrations with a broader range of products. It strives to deliver value-added features tailored for organizations of all sizes, aiming to optimize document workflows efficiently.
For those seeking a more cost-effective alternative to signNow's comprehensive suite, Sign365 offers significant value at a reduced cost. With robust eSignature functionality, high standards of security and compliance, and transparent pricing, Sign365 boasts numerous success stories from satisfied customers who appreciate its focused approach to eSignature solutions.
# Ready to switch from signNow to Sign365?
Sign365 ensures a painless transition. You can migrate from signNow to Sign365 hassle-free by contacting our customer support today

View File

@ -1,45 +0,0 @@
---
title: "Top 5 Best Document Automation Software"
subtitle: "Document automation software is revolutionizing the way businesses create, manage, and distribute documents. With the right tool, you can save time, reduce errors, and improve productivity by automating repetitive tasks involved in document preparation. However, with so many options available, choosing the best one for your needs can be a challenge. To help you make an informed decision, we have rounded up the top 5 best document automation software on the market."
date: "2024-01-24"
image: "/images/top-5-best-document-automation-software-0.png"
---
Document automation software is revolutionizing the way businesses create, manage, and distribute documents. With the right tool, you can save time, reduce errors, and improve productivity by automating repetitive tasks involved in document preparation. However, with so many options available, choosing the best one for your needs can be a challenge. To help you make an informed decision, we have rounded up the top 5 best document automation software on the market.
## DocuSign
DocuSign is a leader in the field of electronic signature technology, but it's also a powerful document automation platform. It streamlines the process of collecting signatures and approvals through automated workflow, making it a staple in contract management and other document-heavy processes.
- ✅ DocuSign offers a high level of security and is widely accepted for legal documents, with robust compliance standards.
- ❌ The pricing might be steep for smaller businesses that only require basic document automation features.
## PandaDoc
PandaDoc is not just about getting documents signed; it also offers comprehensive features for creating, tracking, and managing documents across various stages. Designed to accelerate the deal cycle, PandaDoc can produce proposals, quotes, and contracts with ease.
- ✅ It has a user-friendly interface and a plethora of templates that make document creation a breeze for users at any skill level.
- ❌ While the tool is highly versatile, some users may find the template customization options limited compared to other platforms.
## Zoho Writer
Part of the Zoho Office Suite, Zoho Writer is a powerful word processor that brings a strong suite of document automation features. Collaborative editing, real-time tracking, and seamless integration with Zoho CRM make it a solid choice for businesses immersed in the Zoho ecosystem.
- ✅ The affordability and integration with other Zoho apps provide a holistic approach to document automation.
- ❌ Those not using other Zoho products might not get the full benefits from its ecosystem-oriented design.
## Adobe Sign
From the iconic Adobe family, Adobe Sign focuses on streamlining electronic agreements and approvals with trusted digital signatures. Its integration with Adobe's PDF tools provides a seamless document experience for users familiar with Adobe products.
- ✅ Adobe Sign's widespread recognition and trust factor make it a go-to for businesses that prioritize brand reputation and universal c\* ompatibility.
❌ The software might be overwhelming for those who only need basic document automation and do not require the powerful suite of Adobe features.
## Formstack Documents (formerly WebMerge)
Formstack Documents specializes in generating personalized, on-demand documents. It can pull data from numerous sources, including CRM systems, to automate document creation for various purposes such as invoices, reports, and more.
- ✅ The ability to connect with numerous data sources ensures that Formstack Documents can adapt to many business processes and workflows.
- ❌ There can be a learning curve to mastering the full capabilities of the software, and the cost may be a factor for smaller operations.
Choosing the best document automation software requires you to consider your specific needs, budget, and the level of complexity you can handle. Whether you prioritize ease of use, specific features, or integration with your current systems, there's a solution out there that can automate your documents efficiently and effectively. Start with these top contenders, and you'll be on your way to a more streamlined, productive business in no time.

View File

@ -1,26 +0,0 @@
---
title: "Your Forms On Sign365 In 5 Minutes"
subtitle: "In the dynamic landscape of labor hire, efficiency is paramount, and innovation is the key to staying ahead. As forward-thinking pioneers in the industry, your commitment to streamlining processes is crucial. One way to achieve this is by leveraging the power of free templates and creating customized forms that meet the unique needs of your labor hire company. If you are interested in doing this keep reading and we will give you a special template to help you get started in your form filling."
date: "2024-01-22"
image: "/images/your-forms-on-sign365-in-5-minutes-0.png"
---
Are you tired of the tedious task of managing PDFs? At Sign 365, we understand that your time is valuable, which is why we've revolutionized the upload and management process with our seamless offline form software. Our platform is designed to simplify your document workflow, making it more efficient and less time-consuming. Check out the video below
<div align="left">
<a href="https://youtu.be/spkfiKSGqOQ">
<img src="https://img.youtube.com/vi/spkfiKSGqOQ/0.jpg" style="width:75%;margin:0 auto;">
</a>
</div>
Our intuitive S365 Admin Center is the epitome of simplicity and forward-thinking design. When you first join, you'll be greeted with an easy-to-navigate interface that guides you to access your templates with just a few clicks. This streamlined approach ensures that setting up forms is a matter of minutes, not hours.
With a variety of templates already available, you can manage each one with a set of customizable rules. The platform also offers select features such as bulk forwarding, which is a pioneer in offline form automation. This means that every time a form is submitted, it can be automatically forwarded to a designated email address, ensuring you never miss out on important submissions.
Moreover, our offline form software allows you to enable or disable rules with ease, giving you complete control over your document workflow. And if you're in need of a template, we've got you covered with free templates provided for training purposes.
Uploading a new template is as simple as a few clicks, and just like that, you have a fully functional offline form ready to use. This is the power of Sign 365 - we make offline google forms management a breeze.
If you've been struggling with other systems or are looking for a more efficient way to manage your PDFs, Sign 365 is the solution you've been searching for. Our platform is not just about managing forms; it's about simplifying your entire document workflow.
Try it out and experience the difference for yourself. With Sign 365, managing offline forms is no longer a chore; it's a seamless, streamlined process that saves you time and hassle. Say goodbye to the mundane and hello to the future of offline form automation with Sign 365. Cheers to a simpler document management experience!

View File

@ -19,9 +19,9 @@ function BlogCard({
<>
<Link
href={`/blogs/${slug}`}
className="w-52 md:w-64 md:max-w-[300px] h-fit flex flex-col items-center flex-auto bg-white dark:bg-black p-10 rounded-xl"
className="w-52 md:w-64 md:max-w-[300px] h-fit flex flex-col items-center flex-auto bg-base-100 p-10 rounded-xl"
>
<div className="w-full aspect-[4/3] bg-slate-400 rounded-lg overflow-hidden relative">
<div className="w-full aspect-[4/3] rounded-lg overflow-hidden relative">
<Image
src={imageUrl}
alt={title}
@ -30,10 +30,8 @@ function BlogCard({
/>
</div>
<div className="w-full h-2/5 ">
<h1 className="h3 pt-4 pb-2 xl:pt-8 text-black dark:text-white">
{title}
</h1>
<p className="text-black dark:text-white">{subtitle}</p>
<h1 className="pt-4 pb-2 xl:pt-8 text-base-content ">{title}</h1>
<p className="text-base-content ">{subtitle}</p>
</div>
</Link>
</>

View File

@ -9,16 +9,16 @@ export const Button = ({ status, text }: ButtonProps) => {
const className = (() => {
switch (status) {
case ModalStatus.Loading:
return "btn text-primary bg-white hover:bg-white shadow disabled:text-white disabled:shadow-none";
return "btn text-primary-base-content bg-base-100 hover:bg-base-100 shadow disabled:bg-base-content disabled:shadow-none";
case ModalStatus.Success:
return "btn text-primary bg-white hover:bg-white shadow disabled:text-white disabled:shadow-none";
return "btn text-primary-base-content bg-base-100 hover:bg-base-100 shadow disabled:bg-base-content disabled:shadow-none";
case ModalStatus.Default:
return "btn text-primary bg-white hover:bg-white shadow";
return "btn text-primary-base-content bg-base-100 hover:bg-base-100 shadow";
default:
return "btn text-primary bg-white hover:bg-white shadow";
return "btn text-primary-base-content bg-base-100 hover:bg-base-100 shadow";
}
})();
return (
@ -33,7 +33,7 @@ export const Button = ({ status, text }: ButtonProps) => {
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
className="animate-spin -ml-1 mr-3 h-5 w-5 text-white"
className="animate-spin -ml-1 mr-3 h-5 w-5 bg-base-content"
viewBox="0 0 24 24"
>
<circle

View File

@ -10,7 +10,7 @@ const FAQQuestion = ({
}) => {
return (
<div
className="hs-accordion hs-accordion-active:bg-gray-100 rounded-xl p-6 dark:hs-accordion-active:bg-white/[.05] active"
className="hs-accordion hs-accordion-active:bg-gray-100 rounded-xl p-6 dark:hs-accordion-active:bg-base-100/[.05] active"
id="hs-basic-with-title-and-arrow-stretched-heading-one"
>
<button

View File

@ -5,12 +5,12 @@ import Icon from "./icon";
function Footer() {
return (
<footer>
<div className="py-12 md:py-1">
<div className="py-12 mx-auto w-full from-base-100/70 bg-gradient-to-t">
<div className="max-w-6xl mx-auto px-4 sm:px-6" data-aos="fade-up">
{/* Bottom area */}
<div className="flex items-center justify-center">
{/* Social links */}
<ul className="flex md:order-1 md:mb-0 justify-center">
<ul className="flex md:order-1 md:mb-0 justify-center text-base-content fill-base-content">
<li>
<Icon name="LeafThree24Filled" size="xlarge" />
</li>
@ -18,8 +18,8 @@ function Footer() {
</div>
{/* Copyrights note */}
<div className="text-gray-400 text-xs text-center dark:text-white mt-2">
&copy; 2024 Bethel Farms
<div className="text-base-content text-xs text-center mt-2">
&copy; {new Date().getFullYear()} Bethel Farms
</div>
</div>
</div>

View File

@ -29,14 +29,14 @@ export const GetStartedSectionButton = ({
return subscription ? (
<a href={portalWebsite}>
<button className="btn text-base capitalize !rounded-md text-white bg-bg-gray-925 hover:bg-gray-900 w-full sm:w-auto mt-8">
<button className="btn text-base capitalize !rounded-md bg-base-content bg-bg-gray-925 hover:bg-gray-900 w-full sm:w-auto mt-8">
Management Portal
</button>
</a>
) : (
<button
onClick={() => router.push("/pricing")}
className="px-10 py-2 text-base capitalize !rounded-3xl text-white bg-gradient-to-r from-primary to-secondary hover:bg-gray-900 w-full sm:w-auto"
className="px-10 py-2 text-base capitalize !rounded-3xl bg-base-content bg-gradient-to-r from-primary to-secondary hover:bg-gray-900 w-full sm:w-auto"
>
Upgrade
</button>

View File

@ -5,17 +5,18 @@ import Navigation from "./Navigation";
import ModalSignUp from "@/sections/ModalSignUp/ModalSignUp";
import ModalSignIn from "@/sections/ModalSignIn/ModalSignIn";
import { logout } from "@/app/(auth)/actions";
import { useRouter } from "next/navigation";
import { getAuthCookie } from "@/app/(auth)/actions";
import { SourceModal } from "@/types";
import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
import pb from "@/lib/pocketbase";
import { useTheme } from "next-themes";
interface HeaderProps {
isUserLoggedIn: boolean;
}
function Header({ isUserLoggedIn }: HeaderProps) {
const { theme, setTheme } = useTheme();
return (
<header className="absolute w-full z-30">
<div className="max-w-5xl mx-auto px-4 sm:px-6 md:pt-6">
@ -25,7 +26,48 @@ function Header({ isUserLoggedIn }: HeaderProps) {
{/* Desktop navigation */}
<nav className=" md:flex md:grow">
{/* Desktop sign in links */}
<div className="flex flex-row grow items-center pr-2">
<div className="flex flex-row grow items-center pr-2 gap-x-2">
{/* <button
className="btn btn-primary"
onClick={() => setTheme("dark")}
>
dark
</button>
<button
className="btn btn-primary"
onClick={() => setTheme("light")}
>
light
</button> */}
<label className="swap swap-rotate">
{/* this hidden checkbox controls the state */}
<input
type="checkbox"
className="opacity-0"
onClick={() =>
theme === "light" ? setTheme("dark") : setTheme("light")
}
/>
{/* sun icon */}
<svg
className="swap-on fill-base-content w-6 h-6"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path d="M5.64,17l-.71.71a1,1,0,0,0,0,1.41,1,1,0,0,0,1.41,0l.71-.71A1,1,0,0,0,5.64,17ZM5,12a1,1,0,0,0-1-1H3a1,1,0,0,0,0,2H4A1,1,0,0,0,5,12Zm7-7a1,1,0,0,0,1-1V3a1,1,0,0,0-2,0V4A1,1,0,0,0,12,5ZM5.64,7.05a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29,1,1,0,0,0,0-1.41l-.71-.71A1,1,0,0,0,4.93,6.34Zm12,.29a1,1,0,0,0,.7-.29l.71-.71a1,1,0,1,0-1.41-1.41L17,5.64a1,1,0,0,0,0,1.41A1,1,0,0,0,17.66,7.34ZM21,11H20a1,1,0,0,0,0,2h1a1,1,0,0,0,0-2Zm-9,8a1,1,0,0,0-1,1v1a1,1,0,0,0,2,0V20A1,1,0,0,0,12,19ZM18.36,17A1,1,0,0,0,17,18.36l.71.71a1,1,0,0,0,1.41,0,1,1,0,0,0,0-1.41ZM12,6.5A5.5,5.5,0,1,0,17.5,12,5.51,5.51,0,0,0,12,6.5Zm0,9A3.5,3.5,0,1,1,15.5,12,3.5,3.5,0,0,1,12,15.5Z" />
</svg>
{/* moon icon */}
<svg
className="swap-off fill-base-content w-6 h-6"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<path d="M21.64,13a1,1,0,0,0-1.05-.14,8.05,8.05,0,0,1-3.37.73A8.15,8.15,0,0,1,9.08,5.49a8.59,8.59,0,0,1,.25-2A1,1,0,0,0,8,2.36,10.14,10.14,0,1,0,22,14.05,1,1,0,0,0,21.64,13Zm-9.5,6.69A8.14,8.14,0,0,1,7.08,5.22v.27A10.15,10.15,0,0,0,17.22,15.63a9.79,9.79,0,0,0,2.1-.22A8.11,8.11,0,0,1,12.14,19.73Z" />
</svg>
</label>
{!isUserLoggedIn ? (
<>
<button
@ -45,7 +87,7 @@ function Header({ isUserLoggedIn }: HeaderProps) {
}
})()
}
className={`btn-sm cursor-pointer rounded py-5 w-24 text-primary hover:text-primary/70`}
className={`btn btn-sm btn-ghost text-primary mr-1`}
>
Sign In
</button>
@ -59,16 +101,13 @@ function Header({ isUserLoggedIn }: HeaderProps) {
?.removeAttribute("price_id");
document.getElementById("sign-up-modal")?.click();
}}
className={`btn-sm cursor-pointer py-5 w-24 text-primary-content ml-3 bg-primary hover:bg-primary/70`}
className={`btn btn-primary btn-sm text-primary-content`}
>
Sign Up
</button>
</>
) : (
<button
onClick={() => logout()}
className={`btn-sm cursor-pointer py-5 w-24 text-white ml-3 bg-error hover:bg-error/70`}
>
<button onClick={() => logout()} className={`btn btn-error`}>
Logout
</button>
)}

View File

@ -25,13 +25,13 @@ function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) {
<label htmlFor="my-drawer-3">
<Menu
size={36}
className="self-center w-full h-full cursor-pointer fill-black dark:fill-white"
className="self-center w-full h-full cursor-pointer fill-primary"
/>
</label>
</div>
<div className="flex-none hidden lg:block">
<ul className="menu menu-horizontal items-center">
<ul className="menu menu-horizontal items-center text-base-content">
{/* Site branding */}
<div className="shrink-0 mr-4">
{/* Logo */}
@ -70,7 +70,7 @@ function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) {
<div className="drawer-side">
<label htmlFor="my-drawer-3" className="drawer-overlay"></label>
<ul className="menu w-80 h-full bg-white dark:bg-black">
<ul className="menu w-80 h-full bg-base-100 text-base-content">
{/* Sidebar content here */}
<div className="shrink-0 m-3">
{/* Logo */}

View File

@ -1,18 +1,16 @@
"use client";
import colors, { hexToRgb } from "@/utils/colors";
import { useTheme } from "next-themes";
import React, { ReactNode } from "react";
const Background = ({ children }: { children: ReactNode }) => {
const isDarkMode = (() =>
typeof window !== "undefined" &&
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches)();
const { theme } = useTheme();
const backgroundColor = hexToRgb(colors[theme ?? "light"]["base-100"]);
return (
<div
className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed min-h-screen"
className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed min-h-screen flex flex-col"
style={{
backgroundImage: isDarkMode
? "linear-gradient(rgba(0, 0, 0, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)"
: "linear-gradient(rgba(255, 255, 255, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)",
backgroundImage: `linear-gradient(rgba(${backgroundColor?.r}, ${backgroundColor?.g}, ${backgroundColor?.b}, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)`,
}}
>
{children}

View File

@ -17,7 +17,7 @@ export type Props = {
export default function YouTubeFrame({ video, width, height }: Props) {
return (
<MediaPlayer
className="w-full aspect-video bg-slate-900 text-white font-sans overflow-hidden rounded-xl ring-media-focus data-[focus]:ring-4"
className="w-full aspect-video bg-slate-900 bg-base-content font-sans overflow-hidden rounded-xl ring-media-focus data-[focus]:ring-4"
title="Sprite Fight"
src="youtube/KCHnP62DWpg"
controls

View File

@ -1,10 +1,26 @@
export const IconLoading = () => {
return (
<svg xmlns="http://www.w3.org/2000/svg" fill="none" className="animate-spin -ml-1 mr-3 h-5 w-5 text-white" viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" className="opacity-25"></circle>
<path fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" className="opacity-75"></path>
</svg>
)
}
return (
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
className="animate-spin -ml-1 mr-3 h-5 w-5 bg-base-content"
viewBox="0 0 24 24"
>
<circle
cx="12"
cy="12"
r="10"
stroke="currentColor"
strokeWidth="4"
className="opacity-25"
></circle>
<path
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
className="opacity-75"
></path>
</svg>
);
};
export default IconLoading;
export default IconLoading;

View File

@ -24,6 +24,7 @@
"gray-matter": "^4.0.3",
"next": "^14.1.0",
"next-qrcode": "^2.5.1",
"next-themes": "^0.2.1",
"node-fetch-commonjs": "^3.3.2",
"pocketbase": "^0.18.0",
"postcss": "^8.4.33",
@ -37,6 +38,7 @@
"sharp": "^0.32.6",
"styled-icons": "^10.47.0",
"tailwindcss": "3.3.3",
"theme-change": "^2.5.0",
"typescript": "5.1.6",
"yup": "^1.2.0",
"yup-password": "^0.2.2"
@ -174,9 +176,9 @@
}
},
"node_modules/@babel/core": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
"integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
"integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@ -184,11 +186,11 @@
"@babel/generator": "^7.23.6",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3",
"@babel/helpers": "^7.23.7",
"@babel/parser": "^7.23.6",
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6",
"@babel/helpers": "^7.23.9",
"@babel/parser": "^7.23.9",
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -417,14 +419,14 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.23.8",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz",
"integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
"integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
"peer": true,
"dependencies": {
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6"
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9"
},
"engines": {
"node": ">=6.9.0"
@ -516,9 +518,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
"integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
"peer": true,
"bin": {
"parser": "bin/babel-parser.js"
@ -553,23 +555,23 @@
}
},
"node_modules/@babel/template": {
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
"integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
"@babel/code-frame": "^7.23.5",
"@babel/parser": "^7.23.9",
"@babel/types": "^7.23.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
"integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
"integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.23.5",
@ -578,8 +580,8 @@
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/parser": "^7.23.6",
"@babel/types": "^7.23.6",
"@babel/parser": "^7.23.9",
"@babel/types": "^7.23.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@ -597,9 +599,9 @@
}
},
"node_modules/@babel/types": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
"integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
"peer": true,
"dependencies": {
"@babel/helper-string-parser": "^7.23.4",
@ -4497,6 +4499,16 @@
"react": ">=17.0.0"
}
},
"node_modules/next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
"integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==",
"peerDependencies": {
"next": "*",
"react": "*",
"react-dom": "*"
}
},
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@ -5950,6 +5962,11 @@
"version": "0.2.0",
"license": "MIT"
},
"node_modules/theme-change": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/theme-change/-/theme-change-2.5.0.tgz",
"integrity": "sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ=="
},
"node_modules/thenify": {
"version": "3.3.1",
"license": "MIT",
@ -6496,9 +6513,9 @@
"peer": true
},
"@babel/core": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz",
"integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.9.tgz",
"integrity": "sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw==",
"peer": true,
"requires": {
"@ampproject/remapping": "^2.2.0",
@ -6506,11 +6523,11 @@
"@babel/generator": "^7.23.6",
"@babel/helper-compilation-targets": "^7.23.6",
"@babel/helper-module-transforms": "^7.23.3",
"@babel/helpers": "^7.23.7",
"@babel/parser": "^7.23.6",
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6",
"@babel/helpers": "^7.23.9",
"@babel/parser": "^7.23.9",
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -6679,14 +6696,14 @@
"peer": true
},
"@babel/helpers": {
"version": "7.23.8",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz",
"integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.9.tgz",
"integrity": "sha512-87ICKgU5t5SzOT7sBMfCOZQ2rHjRU+Pcb9BoILMYz600W6DkVRLFBPwQ18gwUVvggqXivaUakpnxWQGbpywbBQ==",
"peer": true,
"requires": {
"@babel/template": "^7.22.15",
"@babel/traverse": "^7.23.7",
"@babel/types": "^7.23.6"
"@babel/template": "^7.23.9",
"@babel/traverse": "^7.23.9",
"@babel/types": "^7.23.9"
}
},
"@babel/highlight": {
@ -6759,9 +6776,9 @@
}
},
"@babel/parser": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz",
"integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.9.tgz",
"integrity": "sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA==",
"peer": true
},
"@babel/plugin-syntax-jsx": {
@ -6780,20 +6797,20 @@
}
},
"@babel/template": {
"version": "7.22.15",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
"integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.23.9.tgz",
"integrity": "sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA==",
"peer": true,
"requires": {
"@babel/code-frame": "^7.22.13",
"@babel/parser": "^7.22.15",
"@babel/types": "^7.22.15"
"@babel/code-frame": "^7.23.5",
"@babel/parser": "^7.23.9",
"@babel/types": "^7.23.9"
}
},
"@babel/traverse": {
"version": "7.23.7",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz",
"integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.9.tgz",
"integrity": "sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg==",
"peer": true,
"requires": {
"@babel/code-frame": "^7.23.5",
@ -6802,8 +6819,8 @@
"@babel/helper-function-name": "^7.23.0",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/parser": "^7.23.6",
"@babel/types": "^7.23.6",
"@babel/parser": "^7.23.9",
"@babel/types": "^7.23.9",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@ -6817,9 +6834,9 @@
}
},
"@babel/types": {
"version": "7.23.6",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz",
"integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==",
"version": "7.23.9",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.9.tgz",
"integrity": "sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q==",
"peer": true,
"requires": {
"@babel/helper-string-parser": "^7.23.4",
@ -9044,6 +9061,12 @@
"qrcode": "^1.5.3"
}
},
"next-themes": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/next-themes/-/next-themes-0.2.1.tgz",
"integrity": "sha512-B+AKNfYNIzh0vqQQKqQItTS8evEouKD7H5Hj3kmuPERwddR2TxvDSFZuTj6T7Jfn1oyeUyJMydPl1Bkxkh0W7A==",
"requires": {}
},
"node-abi": {
"version": "3.51.0",
"requires": {
@ -9863,6 +9886,11 @@
"text-table": {
"version": "0.2.0"
},
"theme-change": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/theme-change/-/theme-change-2.5.0.tgz",
"integrity": "sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ=="
},
"thenify": {
"version": "3.3.1",
"requires": {

View File

@ -25,6 +25,7 @@
"gray-matter": "^4.0.3",
"next": "^14.1.0",
"next-qrcode": "^2.5.1",
"next-themes": "^0.2.1",
"node-fetch-commonjs": "^3.3.2",
"pocketbase": "^0.18.0",
"postcss": "^8.4.33",
@ -38,6 +39,7 @@
"sharp": "^0.32.6",
"styled-icons": "^10.47.0",
"tailwindcss": "3.3.3",
"theme-change": "^2.5.0",
"typescript": "5.1.6",
"yup": "^1.2.0",
"yup-password": "^0.2.2"

View File

@ -84,7 +84,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</h3>
<ol className="list-decimal ml-6">
<li>
<p className="text-lg text-white">
<p className="text-lg bg-base-content">
<a
href={downloadApplicationLink}
className="text-secondary"
@ -95,7 +95,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</p>
</li>
<li>
<p className="text-lg text-white">
<p className="text-lg bg-base-content">
<a
href={portalWebsiteTemplatesLink}
className="text-secondary"
@ -106,7 +106,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</p>
</li>
<li>
<p className="text-lg text-white">
<p className="text-lg bg-base-content">
Setup some{" "}
<a
href={portalWebsiteIntegrationsLink}
@ -118,7 +118,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</li>
</ol>
<a href={portalWebsite}>
<button className="btn text-base capitalize !rounded-md text-white bg-bg-gray-925 hover:bg-gray-900 w-full sm:w-auto mt-8">
<button className="btn text-base capitalize !rounded-md bg-base-content bg-bg-gray-925 hover:bg-gray-900 w-full sm:w-auto mt-8">
Management Portal
</button>
</a>
@ -150,10 +150,10 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</h3>
{subscription ? (
<>
<h2 className="h2 text-3xl mb-3 text-black dark:text-white">
<h2 className="text-3xl mb-3 text-black ">
{subscription?.product?.name}
</h2>
<p className="text-lg text-black dark:text-white mb-4">
<p className="text-lg text-black mb-4">
{subscription.product?.description}
</p>
<button
@ -165,12 +165,12 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</>
) : (
<>
<p className="text-lg text-black dark:text-white mb-4">
<p className="text-lg text-black mb-4">
{"You havent upgraded your workflow yet"}
</p>
<button
onClick={() => router.push("/pricing")}
className="px-10 py-2 text-base capitalize !rounded-3xl text-black dark:text-white bg-gradient-to-r from-primary to-secondary hover:bg-gray-900 w-full sm:w-auto"
className="px-10 py-2 text-base capitalize !rounded-3xl text-black bg-gradient-to-r from-primary to-secondary hover:bg-gray-900 w-full sm:w-auto"
>
Upgrade
</button>

View File

@ -3,18 +3,18 @@ import Image from "next/image";
function BlogContent({ post }: { post: any }) {
return (
<>
<h1 className="text-3xl text-black dark:text-slate-200">{post.title}</h1>
<div className="bg-base-200 px-8 py-12 rounded-lg">
<h1 className="text-3xl text-base-content">{post.title}</h1>
<div className="flex items-center gap-2">
{/* Not sure if name is required */}
<p className="text-black dark:text-slate-200">{post.author ?? ""}</p>
<span className="text-black dark:text-slate-200">|</span>
<p className="text-black dark:text-slate-200">
<p className="text-base-content">{post.author ?? ""}</p>
<span className="text-base-content">|</span>
<p className="text-base-content">
{new Date(post.date).toLocaleDateString()}
</p>
</div>
<article className="prose prose-img:rounded-xl max-w-none prose-p:text-black dark:prose-p:text-white prose-a:text-primary prose-h2:text-black dark:prose-h2:text-white prose-li:text-black dark:prose-li:text-white prose-strong:text-black dark:prose-strong:text-white prose-blockquote:pr-2 prose-blockquote:font-normal">
<article className="prose prose-img:rounded-xl max-w-none prose-p:text-base-content prose-a:text-primary prose-h2:text-base-content prose-li:text-base-content prose-strong:text-base-content prose-blockquote:pr-2 prose-blockquote:font-normal">
<div className="h-full w-full">
<Image
priority
@ -33,7 +33,7 @@ function BlogContent({ post }: { post: any }) {
</div>
<div dangerouslySetInnerHTML={{ __html: post.content }}></div>
</article>
</>
</div>
);
}

View File

@ -1,171 +1,164 @@
"use client";
import pb from "@/lib/pocketbase";
import { contactUsValidationSchema } from "@/utils/form";
import { yupResolver } from "@hookform/resolvers/yup";
import React from "react";
import { useForm } from "react-hook-form";
const FormLeftDescriptionRightContactUs = () => {
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(contactUsValidationSchema),
});
const onSubmit = (data: {
firstName: string;
lastName: string;
email: string;
phoneNumber?: string;
note?: string;
}) => {
localStorage.setItem("contactus", JSON.stringify(data));
pb.collection("contact").create(data);
};
return (
<>
{/* Contact Us */}
<div className="max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto">
<div className="max-w-[85rem] px-4 sm:px-6 lg:px-8 mx-auto pb-10">
<div className="max-w-2xl lg:max-w-5xl mx-auto">
<div className="text-center">
<h1 className="text-3xl font-bold text-black sm:text-4xl dark:text-white">
<h1 className="font-bold text-base-content sm:text-4xl ">
Contact us
</h1>
<p className="mt-1 text-black dark:text-white">
<p className="mt-1 text-base-content ">
We&apos;d love to talk about how we can help you.
</p>
</div>
<div className="mt-12 grid items-center lg:grid-cols-2 gap-6 lg:gap-16">
<div className="mt-12 grid items-start lg:grid-cols-2 gap-6 lg:gap-16">
{/* Card */}
<div className="flex flex-col border rounded-xl p-4 sm:p-6 lg:p-8 dark:border-gray-700 ">
<h2 className="mb-8 text-xl font-semibold text-black dark:text-white">
<div className="flex flex-col rounded-xl p-4 sm:p-6 lg:p-8 bg-base-100 min-h-[20rem]">
<h2 className="mb-8 text-xl font-semibold text-base-content ">
Fill in the form
</h2>
<form>
<div className="grid gap-4">
{/* Grid */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
{!localStorage.getItem("contactus") ? (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="grid gap-4 gap-y-0">
{/* Grid */}
<div className="grid grid-cols-1 sm:grid-cols-2 gap-x-4 gap-y-0">
<div>
<label
htmlFor="hs-firstname-contacts-1"
className="sr-only"
>
First Name
</label>
<input
type="text"
id="hs-firstname-contacts-1"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
placeholder="First Name"
{...register("firstName")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.firstName?.message}&nbsp;
</div>
</div>
<div>
<label
htmlFor="hs-lastname-contacts-1"
className="sr-only"
>
Last Name
</label>
<input
type="text"
id="hs-lastname-contacts-1"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
placeholder="Last Name"
{...register("lastName")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.lastName?.message}&nbsp;
</div>
</div>
</div>
{/* End Grid */}
<div>
<label
htmlFor="hs-firstname-contacts-1"
className="sr-only"
>
First Name
<label htmlFor="hs-email-contacts-1" className="sr-only">
Email
</label>
<input
type="text"
name="hs-firstname-contacts-1"
id="hs-firstname-contacts-1"
className="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:ring-gray-600"
placeholder="First Name"
type="email"
id="hs-email-contacts-1"
autoComplete="email"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
placeholder="Email"
{...register("email")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.email?.message}&nbsp;
</div>
</div>
<div>
<label
htmlFor="hs-lastname-contacts-1"
className="sr-only"
>
Last Name
<label htmlFor="hs-phone-number-1" className="sr-only">
Phone Number
</label>
<input
type="text"
name="hs-lastname-contacts-1"
id="hs-lastname-contacts-1"
className="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:ring-gray-600"
placeholder="Last Name"
id="hs-phone-number-1"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
placeholder="Phone Number"
{...register("phoneNumber")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.phoneNumber?.message}&nbsp;
</div>
</div>
<div>
<label htmlFor="hs-about-contacts-1" className="sr-only">
Details
</label>
<textarea
id="hs-about-contacts-1"
rows={4}
className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
placeholder="Details"
defaultValue={""}
{...register("note")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.note?.message}&nbsp;
</div>
</div>
</div>
{/* End Grid */}
<div>
<label htmlFor="hs-email-contacts-1" className="sr-only">
Email
</label>
<input
type="email"
name="hs-email-contacts-1"
id="hs-email-contacts-1"
autoComplete="email"
className="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:ring-gray-600"
placeholder="Email"
/>
<div className="mt-4 grid">
<button type="submit" className="btn btn-primary">
Send inquiry
</button>
</div>
<div>
<label htmlFor="hs-phone-number-1" className="sr-only">
Phone Number
</label>
<input
type="text"
name="hs-phone-number-1"
id="hs-phone-number-1"
className="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:ring-gray-600"
placeholder="Phone Number"
/>
<div className="mt-3 text-center">
<p className="text-sm text-base-content ">
We&apos;ll get back to you in 1-2 business days.
</p>
</div>
<div>
<label htmlFor="hs-about-contacts-1" className="sr-only">
Details
</label>
<textarea
id="hs-about-contacts-1"
name="hs-about-contacts-1"
rows={4}
className="py-3 px-4 block w-full border-gray-200 rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:ring-gray-600"
placeholder="Details"
defaultValue={""}
/>
</div>
</div>
{/* End Grid */}
<div className="mt-4 grid">
<button
type="submit"
className="w-full py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-blue-600 text-white hover:bg-blue-700 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
>
Send inquiry
</button>
</div>
<div className="mt-3 text-center">
<p className="text-sm text-black dark:text-white">
We&apos;ll get back to you in 1-2 business days.
</p>
</div>
</form>
</form>
) : (
<p className="text-sm text-base-content">
We have received your details and will be in touch!
</p>
)}
</div>
{/* End Card */}
<div className="divide-y divide-gray-200 dark:divide-gray-800">
<div className="divide-y divide-white ">
{/* Icon Block */}
<div className="flex gap-x-7 py-6">
<svg
className="flex-shrink-0 size-6 mt-1.5 text-gray-800 dark:text-gray-200"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<circle cx={12} cy={12} r={10} />
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" />
<path d="M12 17h.01" />
</svg>
<div className="grow">
<h3 className="font-semibold text-gray-800 dark:text-gray-200">
Knowledgebase
</h3>
<p className="mt-1 text-sm text-black dark:text-white">
We&apos;re here to help with any questions or code.
</p>
<a
className="mt-2 inline-flex items-center gap-x-2 text-sm font-medium text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
>
Contact support
<svg
className="flex-shrink-0 size-2.5 transition ease-in-out group-hover:translate-x-1"
width={16}
height={16}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M0.975821 6.92249C0.43689 6.92249 -3.50468e-07 7.34222 -3.27835e-07 7.85999C-3.05203e-07 8.37775 0.43689 8.79749 0.975821 8.79749L12.7694 8.79748L7.60447 13.7596C7.22339 14.1257 7.22339 14.7193 7.60447 15.0854C7.98555 15.4515 8.60341 15.4515 8.98449 15.0854L15.6427 8.68862C16.1191 8.23098 16.1191 7.48899 15.6427 7.03134L8.98449 0.634573C8.60341 0.268455 7.98555 0.268456 7.60447 0.634573C7.22339 1.00069 7.22339 1.59428 7.60447 1.9604L12.7694 6.92248L0.975821 6.92249Z"
fill="currentColor"
/>
</svg>
</a>
</div>
</div>
{/* End Icon Block */}
{/* Icon Block */}
<div className="flex gap-x-7 py-6">
<svg
className="flex-shrink-0 size-6 mt-1.5 text-gray-800 dark:text-gray-200"
className="flex-shrink-0 size-6 mt-1.5 text-base-content "
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
@ -180,15 +173,13 @@ const FormLeftDescriptionRightContactUs = () => {
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1" />
</svg>
<div className="grow">
<h3 className="font-semibold text-gray-800 dark:text-gray-200">
FAQ
</h3>
<p className="mt-1 text-sm text-gray-500">
<h3 className="font-semibold text-base-content ">FAQ</h3>
<p className="mt-1 text-sm text-base-content ">
Search our FAQ for answers to anything you might ask.
</p>
<a
className="mt-2 inline-flex items-center gap-x-2 text-sm font-medium text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
className="mt-2 inline-flex items-center gap-x-2 text-sm font-medium text-base-content hover:text-base-content "
href="/"
>
Visit FAQ
<svg
@ -210,59 +201,11 @@ const FormLeftDescriptionRightContactUs = () => {
</div>
</div>
{/* End Icon Block */}
{/* Icon Block */}
<div className=" flex gap-x-7 py-6">
<svg
className="flex-shrink-0 size-6 mt-1.5 text-gray-800 dark:text-gray-200"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="m7 11 2-2-2-2" />
<path d="M11 13h4" />
<rect width={18} height={18} x={3} y={3} rx={2} ry={2} />
</svg>
<div className="grow">
<h3 className="font-semibold text-gray-800 dark:text-gray-200">
Developer APIs
</h3>
<p className="mt-1 text-sm text-gray-500">
Check out our development quickstart guide.
</p>
<a
className="mt-2 inline-flex items-center gap-x-2 text-sm font-medium text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
>
Contact sales
<svg
className="flex-shrink-0 size-2.5 transition ease-in-out group-hover:translate-x-1"
width={16}
height={16}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M0.975821 6.92249C0.43689 6.92249 -3.50468e-07 7.34222 -3.27835e-07 7.85999C-3.05203e-07 8.37775 0.43689 8.79749 0.975821 8.79749L12.7694 8.79748L7.60447 13.7596C7.22339 14.1257 7.22339 14.7193 7.60447 15.0854C7.98555 15.4515 8.60341 15.4515 8.98449 15.0854L15.6427 8.68862C16.1191 8.23098 16.1191 7.48899 15.6427 7.03134L8.98449 0.634573C8.60341 0.268455 7.98555 0.268456 7.60447 0.634573C7.22339 1.00069 7.22339 1.59428 7.60447 1.9604L12.7694 6.92248L0.975821 6.92249Z"
fill="currentColor"
/>
</svg>
</a>
</div>
</div>
{/* End Icon Block */}
{/* Icon Block */}
<div className=" flex gap-x-7 py-6">
<svg
className="flex-shrink-0 size-6 mt-1.5 text-gray-800 dark:text-gray-200"
className="flex-shrink-0 size-6 mt-1.5 text-base-content "
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
@ -277,17 +220,17 @@ const FormLeftDescriptionRightContactUs = () => {
<path d="m22 10-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 10" />
</svg>
<div className="grow">
<h3 className="font-semibold text-gray-800 dark:text-gray-200">
<h3 className="font-semibold text-base-content ">
Contact us by email
</h3>
<p className="mt-1 text-sm text-black dark:text-white">
<p className="mt-1 text-sm text-base-content ">
If you wish to write us an email instead please use
</p>
<a
className="mt-2 inline-flex items-center gap-x-2 text-sm font-medium text-gray-600 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200 dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
className="mt-2 inline-flex items-center gap-x-2 text-sm font-medium text-base-content hover:text-base-content "
href="mailto:developer@biz365.com.au"
>
example@site.com
developer@biz365.com.au
</a>
</div>
</div>

View File

@ -14,7 +14,7 @@ const FeaturesBlocks = () => {
<div className="py-8 md:py-10">
{/* Section header */}
<div className="max-w-3xl mx-auto text-center pb-6 md:pb-8">
<h2 className="h2 mb-4 text-black dark:text-white">
<h2 className="mb-4 text-black dark:text-white">
Say Goodbye To Manual Data Entry With Sign365.
</h2>
</div>
@ -50,7 +50,7 @@ const FeaturesBlocks = () => {
alt="Enter Data Once"
/>
</div>
<h3 className="h3 text-2xl mb-2 text-center text-black dark:text-white">
<h3 className="text-2xl mb-2 text-center text-black dark:text-white">
Enter Data Once
</h3>
<p className="text-lg text-black dark:text-gray-200 text-center">
@ -88,7 +88,7 @@ const FeaturesBlocks = () => {
alt="Connect To Over 1000 Apps"
/>
</div>
<h3 className="h3 text-xl text-black mb-2 text-center dark:text-white">
<h3 className="text-xl text-black mb-2 text-center dark:text-white">
Connect To Over 1000 Apps
</h3>
<p className="text-lg text-black dark:text-gray-200 text-center">
@ -125,7 +125,7 @@ const FeaturesBlocks = () => {
alt="Start Time Saving"
/>
</div>
<h3 className="h3 text-2xl mb-2 text-center text-black dark:text-white">
<h3 className="text-2xl mb-2 text-center text-black dark:text-white">
Start Time Saving
</h3>
<p className="text-lg text-black dark:text-gray-200 text-center">
@ -163,7 +163,7 @@ const FeaturesBlocks = () => {
alt="Start Saving Money"
/>
</div>
<h3 className="h3 text-2xl mb-2 text-center text-black dark:text-white">
<h3 className="text-2xl mb-2 text-center text-black dark:text-white">
Start Saving Money
</h3>
<p className="text-lg text-black dark:text-gray-200 text-center">
@ -200,7 +200,7 @@ const FeaturesBlocks = () => {
alt="Your Forms Your Way"
/>
</div>
<h3 className="h3 text-2xl mb-2 text-center text-black dark:text-white">
<h3 className="text-2xl mb-2 text-center text-black dark:text-white">
Your Forms Your Way
</h3>
<p className="text-lg text-black dark:text-gray-200 text-center">
@ -238,7 +238,7 @@ const FeaturesBlocks = () => {
alt="Collect Customer Info"
/>
</div>
<h3 className="h3 text-2xl mb-2 text-center text-black dark:text-white">
<h3 className="text-2xl mb-2 text-center text-black dark:text-white">
Collect Customer Info
</h3>
<p className="text-lg text-black dark:text-gray-200 text-center">

View File

@ -24,14 +24,14 @@ const FeaturesZigzag = () => {
<div className="max-w-4xl mx-auto text-center pb-12 md:pb-16 group">
<button
onClick={tryItOnClick}
className="inline-flex text-lg font-semibold py-2 px-[7rem] m-2 text-white bg-gradient-to-r from-primary to-secondary rounded-full mb-4 cursor-pointer group-hover:animate-bounce"
className="inline-flex text-lg font-semibold py-2 px-[7rem] m-2 bg-base-content bg-gradient-to-r from-primary to-secondary rounded-full mb-4 cursor-pointer group-hover:animate-bounce"
>
Try it!
</button>
<h1 className="h2 mb-4 text-black dark:text-black dark:text-white">
<h1 className="mb-4 text-black dark:text-black ">
One Form, Zero Data Reentry
</h1>
<p className="text-xl text-black dark:text-black dark:text-white">
<p className="text-xl text-black dark:text-black ">
Enter data once and let our app do the rest. We&apos;ll send the
information to your business systems, so that you don&apos;t need
to do it more than once.
@ -63,15 +63,15 @@ const FeaturesZigzag = () => {
<div className="font-architects-daughter text-xl text-pink-500 mb-2">
Revolutionize Your Workflow
</div>
<h2 className="h2 text-3xl mb-3 text-black dark:text-white">
<h2 className="text-3xl mb-3 text-black
Streamline Your Data Collection Process
</h2>
<p className="text-lg text-black dark:text-white mb-4">
<p className="text-lg text-black mb-4">
Sign365 removes collecting and filling forms from your
workflow through it&apos;s iOS app. You can now fill and
sign your forms without needing to do the work twice.
</p>
<ul className="text-lg text-black dark:text-white ml-4 -mb-2">
<ul className="text-lg text-black
<li className="flex items-center mb-2">
<span>
We give you the app to collect your surveys and forms.
@ -120,10 +120,10 @@ const FeaturesZigzag = () => {
<div className="font-architects-daughter text-xl text-pink-500 mb-2">
More speed. Less spend
</div>
<h2 className="h2 text-3xl mb-3 text-black dark:text-white">
<h2 className="text-3xl mb-3 text-black ">
Save Time and Money
</h2>
<p className="text-lg text-black dark:text-white mb-4">
<p className="text-lg text-black mb-4">
Sign365 reduces your work hours by giving you an assistant
to do all your paperwork. Got forms to store? Let{" "}
<a
@ -136,7 +136,7 @@ const FeaturesZigzag = () => {
</a>{" "}
do it!
</p>
<ul className="text-lg text-black dark:text-white ml-4 -mb-2 ">
<ul className="text-lg text-black ml-4 -mb-2 ">
<li className="flex items-center mb-2">
<span>
Get the app to collect info and free up time to focus on
@ -188,15 +188,15 @@ const FeaturesZigzag = () => {
<div className="font-architects-daughter text-xl text-pink-500 mb-2">
Unlock Seamless Business Operations
</div>
<h2 className="h2 text-3xl mb-3 text-black dark:text-white">
<h2 className="text-3xl mb-3 text-black ">
Connect to Over 1000 Apps
</h2>
<p className="text-lg text-black dark:text-white mb-4">
<p className="text-lg text-black mb-4">
Sign365 can submit information to over 1000 apps. Whether
you use Salesforce, Hubspot, or any other business app,
Sign365 has got you covered.
</p>
<ul className="text-lg text-black dark:text-white ml-4 -mb-2">
<ul className="text-lg text-black ml-4 -mb-2">
<li className="flex items-center mb-2">
<span>
Sign365 lets you choose where to store your forms. You

View File

@ -6,7 +6,7 @@ export const FrequentlyAsked = () => {
return (
<div className="max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 mx-auto">
<div className="max-w-2xl mx-auto text-center mb-10 lg:mb-14">
<h2 className="text-2xl font-bold md:text-4xl md:leading-tight text-black dark:text-white">
<h2 className="text-2xl font-bold md:text-4xl md:leading-tight text-black ">
Your questions, answered
</h2>
<p className="mt-1 text-gray-600 dark:text-gray-200">

View File

@ -9,10 +9,10 @@ const CenterAllignedWithVideoHero = () => {
<div className="relative overflow-hidden my-auto">
<div className="max-w-[85rem] mx-auto px-4 sm:px-6 lg:px-8 py-10">
<div className="max-w-2xl text-center mx-auto">
<h1 className="block text-3xl font-bold text-primary-content sm:text-4xl md:text-5xl">
<h1 className="block text-3xl font-bold bg-base-content sm:text-4xl md:text-5xl">
Fast <span className="text-primary">Pocket</span>
</h1>
<p className="mt-3 text-lg text-primary-content">
<p className="mt-3 text-lg bg-base-content">
Build your startup here. Launch it anywhere.
</p>
</div>

View File

@ -4,7 +4,7 @@ const SimpleHero = () => {
return (
<div className="h-screen flex items-center justify-center">
<div className="text-center py-10 px-4 sm:px-6 lg:px-8">
<h1 className="block text-2xl font-bold text-white sm:text-4xl">
<h1 className="block text-2xl font-bold bg-base-content sm:text-4xl">
Cover Page
</h1>
<p className="mt-3 text-lg text-gray-300">
@ -13,7 +13,7 @@ const SimpleHero = () => {
</p>
<div className="mt-5 flex flex-col justify-center items-center gap-2 sm:flex-row sm:gap-3">
<a
className="w-full sm:w-auto py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-white text-gray-800 hover:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
className="w-full sm:w-auto py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-base-100 text-gray-800 hover:bg-gray-200 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
>
<svg

View File

@ -9,7 +9,7 @@ const SquaredBackgroundHero = () => {
{/* Grid */}
<div className="grid md:grid-cols-2 gap-4 md:gap-8 xl:gap-20 md:items-center">
<div>
<h1 className="block text-3xl font-bold text-primary-content sm:text-4xl lg:text-6xl lg:leading-tight">
<h1 className="block text-3xl font-bold bg-base-content sm:text-4xl lg:text-6xl lg:leading-tight">
Start your journey with{" "}
<span className="text-primary">FastPocket</span>
</h1>
@ -20,7 +20,7 @@ const SquaredBackgroundHero = () => {
{/* Buttons */}
<div className="mt-7 grid gap-3 w-full sm:inline-flex">
<a
className="py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-primary text-primary-content hover:bg-opacity-60 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
className="py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-primary bg-base-content hover:bg-opacity-60 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
>
Get started
@ -40,7 +40,7 @@ const SquaredBackgroundHero = () => {
</svg>
</a>
<a
className="py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-medium rounded-lg border border-base-100 bg-secondary text-primary-content shadow-sm hover:bg-opacity-600 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
className="py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-medium rounded-lg border border-base-100 bg-secondary bg-base-content shadow-sm hover:bg-opacity-600 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
href="#"
>
Contact sales team
@ -53,7 +53,7 @@ const SquaredBackgroundHero = () => {
<div className="py-5">
<div className="flex space-x-1">
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -66,7 +66,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -79,7 +79,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -92,7 +92,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -105,7 +105,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -118,13 +118,13 @@ const SquaredBackgroundHero = () => {
/>
</svg>
</div>
<p className="mt-3 text-sm text-primary-content">
<p className="mt-3 text-sm bg-base-content">
<span className="font-bold">4.6</span> /5 - from 12k reviews
</p>
<div className="mt-5">
{/* Star */}
<svg
className="h-auto w-16 text-primary-content"
className="h-auto w-16 bg-base-content"
width={80}
height={27}
viewBox="0 0 80 27"
@ -164,7 +164,7 @@ const SquaredBackgroundHero = () => {
<div className="py-5">
<div className="flex space-x-1">
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -177,7 +177,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -190,7 +190,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -203,7 +203,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -216,7 +216,7 @@ const SquaredBackgroundHero = () => {
/>
</svg>
<svg
className="size-4 text-primary-content"
className="size-4 bg-base-content"
width={51}
height={51}
viewBox="0 0 51 51"
@ -233,13 +233,13 @@ const SquaredBackgroundHero = () => {
/>
</svg>
</div>
<p className="mt-3 text-sm text-primary-content">
<p className="mt-3 text-sm bg-base-content">
<span className="font-bold">4.8</span> /5 - from 5k reviews
</p>
<div className="mt-5">
{/* Star */}
<svg
className="h-auto w-16 text-primary-content"
className="h-auto w-16 bg-base-content"
width={110}
height={28}
viewBox="0 0 110 28"
@ -273,7 +273,7 @@ const SquaredBackgroundHero = () => {
{/* SVG*/}
<div className="absolute bottom-0 start-0">
<svg
className="w-2/3 ms-auto h-auto text-white dark:text-slate-900"
className="w-2/3 ms-auto h-auto bg-base-content dark:text-slate-900"
width={630}
height={451}
viewBox="0 0 630 451"

View File

@ -1,123 +1,198 @@
import Logo from "@/components/Logo";
import pb from "@/lib/pocketbase";
import { waitinglistValidationSchema } from "@/utils/form";
import { yupResolver } from "@hookform/resolvers/yup";
import React, { useEffect } from "react";
import { useForm } from "react-hook-form";
import Icon from "@/components/icon";
import React from "react";
import colors, { hexToRgb } from "@/utils/colors";
import Footer from "@/components/Footer";
import { useTheme } from "next-themes";
const WaitingListWithImageHero = () => {
const isDarkMode = () =>
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches;
const { theme } = useTheme();
const backgroundColor = hexToRgb(colors[theme ?? "light"]["base-100"]);
const {
register,
handleSubmit,
formState: { errors },
} = useForm({
resolver: yupResolver(waitinglistValidationSchema),
});
const onSubmit = (data: {
firstName: string;
lastName: string;
email: string;
}) => {
localStorage.setItem("contact", JSON.stringify(data));
pb.collection("contact").create(data);
};
return (
<div
className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed"
style={{
backgroundImage: isDarkMode()
? "linear-gradient(rgba(0, 0, 0, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)"
: "linear-gradient(rgba(255, 255, 255, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)",
backgroundImage: `linear-gradient(rgba(${backgroundColor?.r}, ${backgroundColor?.g}, ${backgroundColor?.b}, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)`,
}}
>
<div className="h-screen w-full bg-clip flex items-center justify-center">
<div className="text-center py-8 px-4 sm:px-6 lg:px-8">
<h1 className="text-3xl text-black dark:text-white sm:text-4xl whitespace-nowrap flex flex-row justify-center pb-6 gap-x-3">
<h1 className="text-3xl text-base-content sm:text-4xl whitespace-nowrap flex flex-row justify-center pb-6 gap-x-3">
<Icon name="LeafThree24Filled" size="xlarge" />
Bethel Farms
</h1>
<h2 className="text-2xl text-black dark:text-white sm:text-4xl">
Get notified when we launch
</h2>
<form>
<div className="mt-8 space-y-4">
<div>
<label
htmlFor="hs-cover-with-gradient-form-name-1"
className="sr-only"
>
Full name
</label>
<div className="relative">
<input
type="text"
id="hs-cover-with-gradient-form-name-1"
className=" py-3 ps-11 pe-4 block w-full bg-white/[.03] border-white/20 placeholder:text-black dark:placeholder:text-white placeholder:text-black dark:text-white rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="Full name"
/>
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
<svg
className="flex-shrink-0 size-4 text-black dark:text-white"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
{typeof window !== "undefined" && !localStorage.getItem("contact") ? (
<>
<h2 className="text-2xl text-base-content">
Get notified when we launch
</h2>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="mt-8 space-y-0">
<div>
<label
htmlFor="hs-cover-with-gradient-form-name-1"
className="sr-only"
>
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
<circle cx={12} cy={7} r={4} />
</svg>
First name
</label>
<div className="relative">
<input
{...register("firstName")}
type="text"
id="hs-cover-with-gradient-form-name-1"
className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 placeholder:text-base-content dark:placeholder:bg-base-content placeholder:text-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="First name"
/>
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
<svg
className="flex-shrink-0 size-4 text-base-content "
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
<circle cx={12} cy={7} r={4} />
</svg>
</div>
</div>
<div className="text-start text-sm italic text-error-content">
{errors.firstName?.message}&nbsp;
</div>
</div>
<div>
<label
htmlFor="hs-cover-with-gradient-form-name-1"
className="sr-only"
>
Last name
</label>
<div className="relative">
<input
{...register("lastName")}
type="text"
id="hs-cover-with-gradient-form-name-1"
className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 placeholder:text-base-content dark:placeholder:bg-base-contentntent placeholder:text-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="Last name"
/>
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
<svg
className="flex-shrink-0 size-4 text-base-content"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
<circle cx={12} cy={7} r={4} />
</svg>
</div>
</div>
<div className="text-start text-sm italic text-error-content">
{errors.lastName?.message}&nbsp;
</div>
</div>
<div>
<label
htmlFor="hs-cover-with-gradient-form-email-1"
className="sr-only"
>
Email address
</label>
<div className="relative">
<input
{...register("email")}
type="email"
id="hs-cover-with-gradient-form-email-1"
className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 text-base-content placeholder:text-base-content dark:placeholder:bg-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="Email address"
/>
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
<svg
className="flex-shrink-0 size-4 text-base-content "
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<rect width={20} height={16} x={2} y={4} rx={2} />
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
</svg>
</div>
</div>
<div className="text-start text-sm italic text-error-content">
{errors.email?.message}&nbsp;
</div>
</div>
<div className="grid">
<button
className="btn btn-primary bg-base-content"
type="submit"
>
Join the waitlist
<svg
className="flex-shrink-0 size-4"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="m9 18 6-6-6-6" />
</svg>
</button>
</div>
</div>
</div>
<div>
<label
htmlFor="hs-cover-with-gradient-form-email-1"
className="sr-only"
>
Email address
</label>
<div className="relative">
<input
type="email"
id="hs-cover-with-gradient-form-email-1"
className=" py-3 ps-11 pe-4 block w-full bg-white/[.03] border-white/20 text-black placeholder:text-black dark:placeholder:text-white dark:text-white rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="Email address"
/>
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
<svg
className="flex-shrink-0 size-4 text-black dark:text-white"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<rect width={20} height={16} x={2} y={4} rx={2} />
<path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7" />
</svg>
</div>
</div>
</div>
<div className="grid">
<button
type="submit"
className=" sm:p-4 py-3 px-4 inline-flex justify-center items-center gap-x-2 text-sm font-semibold rounded-lg border border-transparent bg-white/10 text-black dark:text-white hover:bg-white/20 disabled:opacity-50 disabled:pointer-events-none dark:focus:outline-none dark:focus:ring-1 dark:focus:ring-gray-600"
>
Join the waitlist
<svg
className="flex-shrink-0 size-4"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="m9 18 6-6-6-6" />
</svg>
</button>
</div>
</div>
</form>
</form>
</>
) : (
<h2 className="text-2xl text-base-content sm:text-4xl">
You are on our waiting list. We will be in touch!
</h2>
)}
</div>
</div>
<Footer />
</div>
);
};

View File

@ -31,7 +31,7 @@ function HeroHome() {
{/* Section header */}
<div className="max-w-3xl mx-auto text-center pb-12 md:pb-10">
<h1
className={`${raleway.className} text-black dark:text-white font-raleway text-3xl leading-10 lg:py-12 tracking-[-1px] select-none w-[fit-content] md:leading-[6rem] m-auto mb-4 lg:mb-0 md:text-[5.5rem]`}
className={`${raleway.className} text-black font-raleway text-3xl leading-10 lg:py-12 tracking-[-1px] select-none w-[fit-content] md:leading-[6rem] m-auto mb-4 lg:mb-0 md:text-[5.5rem]`}
data-aos="fade-up"
>
Your Offline Digital Forms Simplified.
@ -47,7 +47,7 @@ function HeroHome() {
<div data-aos="fade-up" data-aos-delay="400">
<button
onClick={bookDemoOnClick}
className="btn text-base capitalize rounded text-white bg-secondary hover:bg-pink-700 w-full mb-4 sm:w-auto sm:mb-0"
className="btn text-base capitalize rounded bg-base-content bg-secondary hover:bg-pink-700 w-full mb-4 sm:w-auto sm:mb-0"
>
Book Demo
</button>
@ -55,7 +55,7 @@ function HeroHome() {
<div data-aos="fade-up" data-aos-delay="600">
<button
onClick={learnMoreOnClick}
className="btn text-base capitalize rounded text-white bg-gray-825 hover:bg-gray-650 w-full sm:w-auto sm:ml-4"
className="btn text-base capitalize rounded bg-base-content bg-gray-825 hover:bg-gray-650 w-full sm:w-auto sm:ml-4"
>
Learn more
</button>

View File

@ -41,11 +41,11 @@ function ModalLearnMore() {
className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 pb-6"
data-aos="fade-up"
>
<h3 className="h3 text-white pt-4 pb-2 text-lg md:text-3xl pt-6">
<h3 className="bg-base-content pt-4 pb-2 text-lg md:text-3xl pt-6">
Want to learn more? Get the no-nonsense facts straight from the
source
</h3>
<p className="text-xs text-white md:text-base">
<p className="text-xs bg-base-content md:text-base">
Enter your email and we will email you a copy of our Whitepaper
</p>
</div>

View File

@ -1,93 +1,113 @@
"use client";
import React, { useState } from 'react';
import { useForm } from 'react-hook-form';
import React, { useState } from "react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import { learnMoreValidationSchema } from "@/utils/form";
import { LearnMoreForm, ModalStatus, SourceModal } from '@/types';
import { LearnMoreForm, ModalStatus, SourceModal } from "@/types";
import { mailchimp } from "@/app/(auth)/actions";
import { toast } from 'react-toastify';
import { toast } from "react-toastify";
interface ModalLearnMoreFormProps {
setStatus: React.Dispatch<React.SetStateAction<ModalStatus>>;
setStatus: React.Dispatch<React.SetStateAction<ModalStatus>>;
}
const ModalLearnMoreForm = ({ setStatus }: ModalLearnMoreFormProps) => {
const [email, setEmail] = useState("");
const [email, setEmail] = useState("");
const { register, handleSubmit, reset, formState: {errors} } = useForm({
resolver: yupResolver(learnMoreValidationSchema),
});
const {
register,
handleSubmit,
reset,
formState: { errors },
} = useForm({
resolver: yupResolver(learnMoreValidationSchema),
});
const submitForm = async (data: LearnMoreForm) => {
setEmail(data.email);
if (!data.email) {
return;
}
setStatus(ModalStatus.Loading);
try{
await sendMailchimpRequest(data);
setEmail("");
reset();
// await handleSendgridSubmit(data.email);
setStatus(ModalStatus.Success);
} catch(error) {
if (error instanceof Error){
toast.error(error.message, {
position: "bottom-left",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "colored",
});
}
setStatus(ModalStatus.Default);
}
const submitForm = async (data: LearnMoreForm) => {
setEmail(data.email);
if (!data.email) {
return;
}
setStatus(ModalStatus.Loading);
const sendMailchimpRequest = async (data: LearnMoreForm) => {
console.log("sendMailchimpRequest call initiated");
await mailchimp({
email: data.email,
first_name: '',
last_name: '',
phone_number: '',
company_size: '',
source: SourceModal.LearnMore,
try {
await sendMailchimpRequest(data);
setEmail("");
reset();
// await handleSendgridSubmit(data.email);
setStatus(ModalStatus.Success);
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
position: "bottom-left",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "colored",
});
console.log("sendMailchimpRequest call success");
}
setStatus(ModalStatus.Default);
}
};
const sendMailchimpRequest = async (data: LearnMoreForm) => {
console.log("sendMailchimpRequest call initiated");
await mailchimp({
email: data.email,
first_name: "",
last_name: "",
phone_number: "",
company_size: "",
source: SourceModal.LearnMore,
});
console.log("sendMailchimpRequest call success");
};
const handleSendgridSubmit = async (email: string) => {
const data = {
subscriberEmail: email,
};
//call to the Netlify Function you created
return fetch("./.netlify/functions/triggerLearnMoreEmail", {
method: "POST",
body: JSON.stringify({
subscriberEmail: data.subscriberEmail,
}),
});
};
const handleSendgridSubmit = async (email: string) => {
const data = {
subscriberEmail: email,
};
//call to the Netlify Function you created
return fetch("./.netlify/functions/triggerLearnMoreEmail", {
method: "POST",
body: JSON.stringify({
subscriberEmail: data.subscriberEmail,
}),
});
};
return (
<form onSubmit={handleSubmit(submitForm)} className="w-full md:w-1/2">
<div className="relative mt-3 mb-2">
<input
{...register("email")}
id="learnMoreEmail"
type="text"
className="w-full appearance-none bg-transparent border border-white focus:border-white rounded-sm px-4 mr-2 bg-base-content placeholder-white"
placeholder="Your best email…"
aria-label="Your best email…"
autoComplete="on"
/>
<label
className="md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400"
htmlFor="learnMoreEmail"
>
{errors.email ? "*" + errors.email.message : ""}
</label>
</div>
return (
<form onSubmit={handleSubmit(submitForm)} className="w-full md:w-1/2">
<div className='relative mt-3 mb-2'>
<input {...register("email")} id="learnMoreEmail" type='text' className="w-full appearance-none bg-transparent border border-white focus:border-white rounded-sm px-4 mr-2 text-white placeholder-white" placeholder="Your best email…" aria-label="Your best email…" autoComplete="on" />
<label className='md:absolute top-[50%] translate-y-[-50%] left-[105%] w-[220px] text-red-400' htmlFor='learnMoreEmail'>{errors.email ? "*" + errors.email.message : ""}</label>
</div>
<button type="submit" className="btn capitalize font-bold text-black bg-white hover:bg-white shadow">Submit</button>
</form>
);
<button
type="submit"
className="btn capitalize font-bold text-black bg-base-100 hover:bg-white shadow"
>
Submit
</button>
</form>
);
};
export default ModalLearnMoreForm;
export default ModalLearnMoreForm;

View File

@ -1,20 +1,16 @@
"use client";
import React, { useRef, useState } from "react";
import xButton from "@/images/icon-x.svg";
import useTextsBasedOnActivityState from "@/sections/ModalSignIn/useTextsBasedOnActivityState";
import ModalSignInForm, {
FormRefMethods,
} from "@/sections/ModalSignIn/ModalSignInForm";
import SuccessModal from "@/sections/SuccessModal";
import LoadingModal from "@/sections/LoadingModal";
import Image from "next/image";
import { ModalStatus } from "@/types";
import Icon from "@/components/icon";
function ModalSignIn() {
const [status, setStatus] = useState<ModalStatus>(ModalStatus.Default);
const { textOnUse, whenModalOpens } = useTextsBasedOnActivityState(setStatus);
const formRef = useRef<FormRefMethods>(null);
const handleCloseModal = () => {
if (formRef.current) {
@ -29,10 +25,9 @@ function ModalSignIn() {
id="sign-in-modal"
className="modal-toggle"
name=""
onChange={whenModalOpens}
/>
<label htmlFor="sign-in-modal" className="modal cursor-pointer">
<label className="modal-box relative bg-gray-100 dark:bg-gray-850 max-w-full md:max-w-[550px] py-4 px-3 md:p-6">
<label className="modal-box relative bg-gray-100 max-w-full md:max-w-[550px] py-4 px-3 md:p-6">
<div className="flex justify-end pb-2 select-none">
<label
onClick={handleCloseModal}
@ -47,18 +42,18 @@ function ModalSignIn() {
className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 pb-6"
data-aos="fade-up"
>
<h3 className="h3 text-white pt-4 pb-2 text-lg md:text-3xl pt-6">
{textOnUse.title}
<h3 className="pt-4 pb-2 text-lg md:text-3xl pt-6">
{/* {textOnUse.title} */}
</h3>
<p className="text-xs text-white md:text-base">
{textOnUse.subTitle}
<p className="text-xs md:text-base">
{/* {textOnUse.subTitle} */}
</p>
</div>
<ModalSignInForm
textOnUse={textOnUse}
{/* <ModalSignInForm
textOnUse={"textOnUse"}
setStatus={setStatus}
ref={formRef}
/>
/> */}
</div>
{status === ModalStatus.Success && <SuccessModal />}
{status === ModalStatus.Loading && <LoadingModal />}

View File

@ -73,7 +73,7 @@ const ModalSignInForm = forwardRef<FormRefMethods, ModalSignInFormProps>(
{...register("email")}
id="SignInEmail"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Your email…"
aria-label="Your email…"
autoComplete="on"
@ -90,7 +90,7 @@ const ModalSignInForm = forwardRef<FormRefMethods, ModalSignInFormProps>(
{...register("password")}
id="SignInPwd"
type="password"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Your password..."
aria-label="Your password..."
/>
@ -104,7 +104,7 @@ const ModalSignInForm = forwardRef<FormRefMethods, ModalSignInFormProps>(
<button
type="submit"
className="btn capitalize font-bold text-black bg-white hover:bg-white shadow"
className="btn capitalize font-bold text-black bg-base-100 hover:bg-base-100 shadow"
>
{textOnUse.buttonText}
</button>

View File

@ -1,32 +0,0 @@
import { ModalStatus } from '@/types';
import { useState } from 'react';
function useTextsBasedOnActivityState(setStatus: React.Dispatch<React.SetStateAction<ModalStatus>>){
const signInTexts = {
title: "Welcome Back!",
subTitle: "We missed you! Please sign in.",
buttonText: "Sign In",
netlifyFunction: "triggerSignInEmail"
}
const [textOnUse, setTextOnUse] = useState(signInTexts)
const whenModalOpens = () => {
const signInModal = document.getElementById("sign-in-modal");
if (!signInModal) return;
const nameAttribute = signInModal.getAttribute("name");
switch(nameAttribute){
case "signIn":
setTextOnUse(signInTexts);
break;
default:
setTextOnUse(signInTexts);
break;
}
setTimeout(() => setStatus(ModalStatus.Default), 500);
}
return {textOnUse, whenModalOpens}
}
export default useTextsBasedOnActivityState;

View File

@ -2,26 +2,16 @@
// TODO: Needs a complete rework to use the DaisyUI component
import React, { useRef, useState } from "react";
import xButton from "@/images/icon-x.svg";
import useTextsBasedOnActivityState from "./useTextsBasedOnActivityState";
import ModalSignUpForm from "./ModalSignUpForm";
import SuccessModal from "@/sections/SuccessModal";
import LoadingModal from "@/sections/LoadingModal";
import Image from "next/image";
import { ModalStatus } from "@/types";
import { FormRefMethods } from "../ModalSignIn/ModalSignInForm";
import Icon from "@/components/icon";
function ModalSignUp() {
const [status, setStatus] = useState<ModalStatus>(ModalStatus.Default);
const { textOnUse, companySizeList, whenModalOpens, getPriceId } =
useTextsBasedOnActivityState(setStatus);
const formRef = useRef<FormRefMethods>(null);
const handleCloseModal = () => {
if (formRef.current) {
formRef.current.resetForm();
}
setStatus(ModalStatus.Default);
};
return (
@ -31,10 +21,10 @@ function ModalSignUp() {
id="sign-up-modal"
className="modal-toggle"
name=""
onChange={whenModalOpens}
// onChange={whenModalOpens}
/>
<label htmlFor="sign-up-modal" className="modal cursor-pointer">
<label className="modal-box relative bg-gray-100 dark:bg-gray-850 max-w-full md:max-w-[550px] py-4 px-3 md:p-6">
<label className="modal-box relative max-w-full md:max-w-[550px] py-4 px-3 md:p-6">
<div className="flex justify-end pb-2 select-none">
<label
onClick={handleCloseModal}
@ -44,30 +34,24 @@ function ModalSignUp() {
<Icon name="Dismiss20Filled" size="medium" />
</label>
</div>
<div className={status === ModalStatus.Default ? "block" : "hidden"}>
<div
className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 pb-6"
data-aos="fade-up"
>
<h3 className="h3 text-white pt-4 pb-2 text-lg md:text-3xl pt-6">
{textOnUse.title}
</h3>
<p className="text-xs text-white md:text-base">
{textOnUse.subTitle}
</p>
</div>
<div
className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 pb-6"
data-aos="fade-up"
>
<h3 className="pb-2 text-lg md:text-3xl pt-6">
{/* {textOnUse.title} */}
</h3>
<p className="text-xs md:text-base">{/* {textOnUse.subTitle} */}</p>
</div>
<ModalSignUpForm
{/* <ModalSignUpForm
generateCheckoutSession={false}
companySizeList={companySizeList}
textOnUse={textOnUse}
setStatus={setStatus}
getPriceId={getPriceId}
ref={formRef}
/>
</div>
{status === ModalStatus.Success && <SuccessModal />}
{status === ModalStatus.Loading && <LoadingModal />}
/> */}
</label>
</label>
</>

View File

@ -160,7 +160,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("email")}
type="text"
id="SignUpEmail"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Email…"
aria-label="Email…"
autoComplete="on"
@ -177,7 +177,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("first_name")}
id="SignUpFirstName"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black"
placeholder="First Name…"
aria-label="First Name…"
autoComplete="on"
@ -194,7 +194,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("last_name")}
id="SignUpLastName"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Last Name…"
aria-label="Last Name…"
/>
@ -211,7 +211,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("phone_number")}
id="SignUpPhoneNumber"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Phone Number…"
aria-label="Phone Number…"
/>
@ -227,7 +227,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("organisation")}
id="SignUpOrganisation"
type="text"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Organisation…"
aria-label="Organisation…"
/>
@ -243,7 +243,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("company_size")}
id="SignUpCompanySize"
defaultValue={""}
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
>
<option className="bg-gray-850" value={""} disabled>
Company Size
@ -272,7 +272,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("password")}
id="SignUpPwd"
type="password"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Password..."
aria-label="Password"
/>
@ -288,7 +288,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
{...register("passwordConfirmation")}
id="SignUpPwdConfirm"
type="password"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:text-white dark:placeholder-white dark:border-white"
className="w-full appearance-none bg-transparent border rounded-sm px-4 mr-2 text-black placeholder-black border-black dark:placeholder-white dark:border-white"
placeholder="Confirmed Password..."
aria-label="Confirmed Password"
/>
@ -304,7 +304,7 @@ const ModalSignUpForm = forwardRef<FormRefMethods, ModalSignUpFormProps>(
<button
type="submit"
className="btn capitalize font-bold text-black bg-white hover:bg-white shadow"
className="btn capitalize font-bold text-black bg-base-100 hover:bg-base-100 shadow"
>
{textOnUse.buttonText}
</button>

View File

@ -1,122 +1,131 @@
"use client";
import React, { useState } from 'react';
import { NewsLetterForm, SourceModal } from '@/types';
import React, { useState } from "react";
import { NewsLetterForm, SourceModal } from "@/types";
import { mailchimp } from "@/app/(auth)/actions";
import { toast } from 'react-toastify';
import { ModalStatus } from '@/types';
import IconLoading from '@/images/IconLoading';
import Button from '@/components/Button';
import { toast } from "react-toastify";
import { ModalStatus } from "@/types";
import Button from "@/components/Button";
const NewsletterForm = () => {
const [status, setStatus] = useState<ModalStatus>(ModalStatus.Default);
const [email, setEmail] = useState("");
const [status, setStatus] = useState<ModalStatus>(ModalStatus.Default);
const [email, setEmail] = useState('');
const submitForm = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
try{
if (!email) {
throw Error("Email is Empty");
}
if (email.indexOf("@") === -1) {
throw Error("Email is invalid");
}
setStatus(ModalStatus.Loading);
const formData = {
email: email,
first_name: '',
last_name: '',
phone_number: '',
company_size: '',
source: SourceModal.Newsletter,
}
await sendMailchimpRequest(formData);
// await handleSendgridSubmit(formData.email);
setStatus(ModalStatus.Success);
} catch(error) {
if (error instanceof Error){
toast.error(error.message, {
position: "bottom-left",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "colored",
});
}
setStatus(ModalStatus.Default);
}
const submitForm = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
try {
if (!email) {
throw Error("Email is Empty");
}
if (email.indexOf("@") === -1) {
throw Error("Email is invalid");
}
setStatus(ModalStatus.Loading);
const formData = {
email: email,
first_name: "",
last_name: "",
phone_number: "",
company_size: "",
source: SourceModal.Newsletter,
};
await sendMailchimpRequest(formData);
// await handleSendgridSubmit(formData.email);
setStatus(ModalStatus.Success);
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
position: "bottom-left",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "colored",
});
}
setStatus(ModalStatus.Default);
}
const sendMailchimpRequest = async (data: NewsLetterForm) => {
console.log("sendMailchimpRequest call initiated");
await mailchimp({
email: data.email,
first_name: '',
last_name: '',
phone_number: '',
company_size: '',
source: data.source,
});
console.log("sendMailchimpRequest call success");
};
const handleSendgridSubmit = async (email: string) => {
const data = {
subscriberEmail: email,
};
//call to the Netlify Function you created
return fetch("./.netlify/functions/triggerLearnMoreEmail", {
method: "POST",
body: JSON.stringify({
subscriberEmail: data.subscriberEmail,
}),
});
};
const sendMailchimpRequest = async (data: NewsLetterForm) => {
console.log("sendMailchimpRequest call initiated");
await mailchimp({
email: data.email,
first_name: "",
last_name: "",
phone_number: "",
company_size: "",
source: data.source,
});
console.log("sendMailchimpRequest call success");
};
const handleSendgridSubmit = async (email: string) => {
const data = {
subscriberEmail: email,
};
//call to the Netlify Function you created
return fetch("./.netlify/functions/triggerLearnMoreEmail", {
method: "POST",
body: JSON.stringify({
subscriberEmail: data.subscriberEmail,
}),
});
};
return (
return (
<>
<div className="mb-6 lg:mr-16 lg:mb-0 text-center lg:text-left lg:w-1/2">
<h3 className=" mb-2 text-3xl font-black">
{status !== ModalStatus.Success
? "Stay Ahead of the Curve"
: "Thanks for subscribing"}
</h3>
<p className=" text-lg">
{status !== ModalStatus.Success
? "Join our newsletter to get top news before anyone else."
: "You are going to love what we have to show you"}
</p>
</div>
<>
<div className="mb-6 lg:mr-16 lg:mb-0 text-center lg:text-left lg:w-1/2">
<h3 className="h3 text-white mb-2">{status !== ModalStatus.Success ? "Stay Ahead of the Curve" : "Thanks for subscribing"}</h3>
<p className="text-white text-lg">{status !== ModalStatus.Success ? "Join our newsletter to get top news before anyone else." : "You are going to love what we have to show you"}</p>
</div>
<div className="w-full lg:w-1/2">
<form onSubmit={(e) => submitForm(e)} className="flex flex-col sm:flex-row justify-center max-w-xs mx-auto sm:max-w-md lg:max-w-none">
<input
required
name="email"
type="email"
onChange={event => setEmail(event.target.value)}
value={email}
className="w-full appearance-none bg-transparent border border-white focus:border-white rounded-sm px-4 py-3 mb-2 sm:mb-0 sm:mr-2 text-white placeholder-white disabled:bg-transparent"
placeholder="Your best email…"
aria-label="Your best email…"
disabled={status === ModalStatus.Success}
autoComplete="on"
/>
<Button status={status} text={(() => {
switch (status) {
case ModalStatus.Loading:
return "Sending...";
case ModalStatus.Success:
return "Success";
case ModalStatus.Default:
return "Subscribe";
default:
return "default-class";
}
})()}/>
</form>
</div>
</>
);
<div className="w-full lg:w-1/2">
<form
onSubmit={(e) => submitForm(e)}
className="flex flex-col sm:flex-row justify-center max-w-xs mx-auto sm:max-w-md lg:max-w-none"
>
<input
required
name="email"
type="email"
onChange={(event) => setEmail(event.target.value)}
value={email}
className="w-full appearance-none bg-transparent border border-white focus:border-white rounded-sm px-4 py-3 mb-2 sm:mb-0 sm:mr-2 placeholder-white disabled:bg-transparent"
placeholder="Your best email…"
aria-label="Your best email…"
disabled={status === ModalStatus.Success}
autoComplete="on"
/>
<Button
status={status}
text={(() => {
switch (status) {
case ModalStatus.Loading:
return "Sending...";
case ModalStatus.Success:
return "Success";
case ModalStatus.Default:
return "Subscribe";
default:
return "default-class";
}
})()}
/>
</form>
</div>
</>
);
};
export default NewsletterForm;
export default NewsletterForm;

View File

@ -7,7 +7,9 @@ interface PageHeaderProps {
function PageHeader({ title, subtitle }: PageHeaderProps) {
return (
<div className="pt-28 max-w-screen flex flex-col">
<h1 className="h1 text-black dark:text-white mb-12 mx-auto">{title}</h1>
<h1 className="text-5xl font-black text-base-content mb-12 mx-auto">
{title}
</h1>
{subtitle}
</div>
);

View File

@ -1,57 +0,0 @@
/* Range slider */
:root {
--range-thumb-size: 36px;
}
input[type=range] {
appearance: none;
background: #ccc;
border-radius: 3px;
height: 6px;
margin-top: (--range-thumb-size - 6px) * 0.5;
margin-bottom: (--range-thumb-size - 6px) * 0.5;
--thumb-size: #{--range-thumb-size};
}
input[type=range]::-webkit-slider-thumb {
appearance: none;
-webkit-appearance: none;
background-color: #000;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 .5v7L12 4zM0 4l4 3.5v-7z' fill='%23FFF' fill-rule='nonzero'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
border: 0;
border-radius: 50%;
cursor: pointer;
height: --range-thumb-size;
width: --range-thumb-size;
}
input[type=range]::-moz-range-thumb {
background-color: #000;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 .5v7L12 4zM0 4l4 3.5v-7z' fill='%23FFF' fill-rule='nonzero'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
border: 0;
border: none;
border-radius: 50%;
cursor: pointer;
height: --range-thumb-size;
width: --range-thumb-size;
}
input[type=range]::-ms-thumb {
background-color: #000;
background-image: url("data:image/svg+xml,%3Csvg width='12' height='8' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 .5v7L12 4zM0 4l4 3.5v-7z' fill='%23FFF' fill-rule='nonzero'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
border: 0;
border-radius: 50%;
cursor: pointer;
height: --range-thumb-size;
width: --range-thumb-size;
}
input[type=range]::-moz-focus-outer {
border: 0;
}

View File

@ -1,152 +0,0 @@
.form-input:focus,
.form-textarea:focus,
.form-multiselect:focus,
.form-select:focus,
.form-checkbox:focus,
.form-radio:focus {
@apply ring-0;
}
/* Hamburger button */
.hamburger svg > *:nth-child(1),
.hamburger svg > *:nth-child(2),
.hamburger svg > *:nth-child(3) {
transform-origin: center;
transform: rotate(0deg);
}
.hamburger svg > *:nth-child(1) {
transition: y 0.1s 0.25s ease-in, transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), opacity 0.1s ease-in;
}
.hamburger svg > *:nth-child(2) {
transition: transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19);
}
.hamburger svg > *:nth-child(3) {
transition: y 0.1s 0.25s ease-in, transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19), width 0.1s 0.25s ease-in;
}
.hamburger.active svg > *:nth-child(1) {
opacity: 0;
y: 11;
transform: rotate(225deg);
transition: y 0.1s ease-out, transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), opacity 0.1s 0.12s ease-out;
}
.hamburger.active svg > *:nth-child(2) {
transform: rotate(225deg);
transition: transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.hamburger.active svg > *:nth-child(3) {
y: 11;
transform: rotate(135deg);
transition: y 0.1s ease-out, transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1), width 0.1s ease-out;
}
/* Pulsing animation */
@keyframes pulseLoop {
0% { opacity: 0; transform: scale(0.1) translateZ(0); }
40% { opacity: 1; }
60% { opacity: 1; }
100% { opacity: 0; transform: scale(2) translateZ(0); }
}
.pulse {
transform: scale(0.1);
opacity: 0;
transform-origin: center;
animation: pulseLoop 8000ms linear infinite;
}
.pulse-1 {
animation-delay: -2000ms;
}
.pulse-2 {
animation-delay: -4000ms;
}
.pulse-3 {
animation-delay: -6000ms;
}
/* Custom AOS distance */
@media screen {
html:not(.no-js) [data-aos=fade-up] {
-webkit-transform: translate3d(0, 10px, 0);
transform: translate3d(0, 10px, 0);
}
html:not(.no-js) [data-aos=fade-down] {
-webkit-transform: translate3d(0, -10px, 0);
transform: translate3d(0, -10px, 0);
}
html:not(.no-js) [data-aos=fade-right] {
-webkit-transform: translate3d(-10px, 0, 0);
transform: translate3d(-10px, 0, 0);
}
html:not(.no-js) [data-aos=fade-left] {
-webkit-transform: translate3d(10px, 0, 0);
transform: translate3d(10px, 0, 0);
}
html:not(.no-js) [data-aos=fade-up-right] {
-webkit-transform: translate3d(-10px, 10px, 0);
transform: translate3d(-10px, 10px, 0);
}
html:not(.no-js) [data-aos=fade-up-left] {
-webkit-transform: translate3d(10px, 10px, 0);
transform: translate3d(10px, 10px, 0);
}
html:not(.no-js) [data-aos=fade-down-right] {
-webkit-transform: translate3d(-10px, -10px, 0);
transform: translate3d(-10px, -10px, 0);
}
html:not(.no-js) [data-aos=fade-down-left] {
-webkit-transform: translate3d(10px, -10px, 0);
transform: translate3d(10px, -10px, 0);
}
html:not(.no-js) [data-aos=zoom-in-up] {
-webkit-transform: translate3d(0, 10px, 0) scale(.6);
transform: translate3d(0, 10px, 0) scale(.6);
}
html:not(.no-js) [data-aos=zoom-in-down] {
-webkit-transform: translate3d(0, -10px, 0) scale(.6);
transform: translate3d(0, -10px, 0) scale(.6);
}
html:not(.no-js) [data-aos=zoom-in-right] {
-webkit-transform: translate3d(-10px, 0, 0) scale(.6);
transform: translate3d(-10px, 0, 0) scale(.6);
}
html:not(.no-js) [data-aos=zoom-in-left] {
-webkit-transform: translate3d(10px, 0, 0) scale(.6);
transform: translate3d(10px, 0, 0) scale(.6);
}
html:not(.no-js) [data-aos=zoom-out-up] {
-webkit-transform: translate3d(0, 10px, 0) scale(1.2);
transform: translate3d(0, 10px, 0) scale(1.2);
}
html:not(.no-js) [data-aos=zoom-out-down] {
-webkit-transform: translate3d(0, -10px, 0) scale(1.2);
transform: translate3d(0, -10px, 0) scale(1.2);
}
html:not(.no-js) [data-aos=zoom-out-right] {
-webkit-transform: translate3d(-10px, 0, 0) scale(1.2);
transform: translate3d(-10px, 0, 0) scale(1.2);
}
html:not(.no-js) [data-aos=zoom-out-left] {
-webkit-transform: translate3d(10px, 0, 0) scale(1.2);
transform: translate3d(10px, 0, 0) scale(1.2);
}
}

View File

@ -1,27 +0,0 @@
/* Switch element */
.form-switch {
@apply relative select-none;
width: 60px;
}
.form-switch label {
@apply block overflow-hidden cursor-pointer h-8 rounded-full;
}
.form-switch label>span:first-child {
@apply absolute block rounded-full;
width: 28px;
height: 28px;
top: 2px;
left: 2px;
right: 50%;
transition: all .15s ease-out;
}
.form-switch input[type="checkbox"]:checked+label {
@apply bg-purple-600;
}
.form-switch input[type="checkbox"]:checked+label>span:first-child {
left: 30px;
}

View File

@ -1,79 +0,0 @@
/* Typography */
.h1 {
@apply text-4xl font-extrabold leading-tight tracking-tighter;
}
.h2 {
@apply text-3xl font-extrabold leading-tight tracking-tighter;
}
.h3 {
@apply text-3xl font-bold leading-tight;
}
.h4 {
@apply text-2xl font-bold leading-snug tracking-tight;
}
@screen md {
.h1 {
@apply text-5xl;
}
.h2 {
@apply text-4xl;
}
}
/* Buttons */
.btn,
.btn-sm {
@apply font-medium inline-flex items-center justify-center border border-transparent rounded-sm leading-snug transition duration-150 ease-in-out;
}
.btn {
@apply px-8 py-3;
}
.btn-sm {
@apply px-4 py-2;
}
/* Forms */
.form-input,
.form-textarea,
.form-multiselect,
.form-select,
.form-checkbox,
.form-radio {
@apply bg-transparent border border-gray-700 focus:border-gray-500;
}
.form-input,
.form-textarea,
.form-multiselect,
.form-select,
.form-checkbox {
@apply rounded-sm;
}
.form-input,
.form-textarea,
.form-multiselect,
.form-select {
@apply py-3 px-4;
}
.form-input,
.form-textarea {
@apply placeholder-gray-500;
}
.form-select {
@apply pr-10;
}
.form-checkbox,
.form-radio {
@apply text-purple-600;
}

View File

@ -4,12 +4,6 @@
@import 'tailwindcss/base';
@import 'tailwindcss/components';
/* Additional styles */
@import 'additional-styles/utility-patterns.css';
@import 'additional-styles/range-slider.css';
@import 'additional-styles/toggle-switch.css';
@import 'additional-styles/theme.css';
@import 'tailwindcss/utilities';
/* Additional Tailwind directives: https://tailwindcss.com/docs/functions-and-directives/#responsive */
@ -22,28 +16,4 @@
/* See Alpine.js: https://github.com/alpinejs/alpine#x-cloak */
[x-cloak=""] {
display: none;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
textarea:-webkit-autofill,
textarea:-webkit-autofill:hover,
textarea:-webkit-autofill:focus,
select:-webkit-autofill,
select:-webkit-autofill:hover,
select:-webkit-autofill:focus {
-webkit-text-fill-color: #fff;
/* -webkit-box-shadow: 0 0 0px 1000px #1b1b6c inset; */
background-color: transparent!important;
background: transparent!important;
transition: background-color 5000s ease-in-out 0s;
}
body, .font-inter{
font-family: Arimo;
}
h1, h2, h3, p {
color: white;
}

View File

@ -1,5 +1,5 @@
import type { Config } from "tailwindcss";
const defaultTheme = require('tailwindcss/defaultTheme')
const defaultTheme = require("tailwindcss/defaultTheme");
const config: Config = {
content: [
@ -7,7 +7,7 @@ const config: Config = {
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./sections/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
'./node_modules/preline/preline.js',
"./node_modules/preline/preline.js",
],
theme: {
extend: {
@ -27,7 +27,7 @@ const config: Config = {
850: "#383040",
900: "#151719",
925: "#191D24",
950: "#000000"
950: "#000000",
},
purple: {
default: "#8000FF",
@ -51,8 +51,8 @@ const config: Config = {
},
red: {
300: "#C84C4C",
600: "#8b2e2e"
}
600: "#8b2e2e",
},
},
spacing: {
"9/16": "56.25%",
@ -60,8 +60,8 @@ const config: Config = {
"1/1": "100%",
},
fontFamily: {
'primary': ['Raleway Variable', ...defaultTheme.fontFamily.sans],
'secondary': ['Arimo Variable', ...defaultTheme.fontFamily.sans],
primary: ["Raleway Variable", ...defaultTheme.fontFamily.sans],
secondary: ["Arimo Variable", ...defaultTheme.fontFamily.sans],
},
fontSize: {
xs: "0.75rem",
@ -98,13 +98,45 @@ const config: Config = {
themes: [
{
light: {
...require("daisyui/src/theming/themes")["light"],
"primary": '#c0df68',
"secondary": '#73d776'
primary: "#5700ff",
"primary-content": "#fff",
secondary: "#ff7400",
"secondary-content": "#000",
accent: "#fd0000",
neutral: "#28282e",
"base-100": "#fefaff",
"base-200": "#e1e2e9",
"base-300": "#c5cad3",
"base-content": "#000",
info: "#00f5ff",
success: "#00ff8b",
warning: "#ff5100",
error: "#ff0051",
},
dark: {
primary: "#5900ff",
"primary-content": "#fff",
secondary: "#002eff",
"secondary-content": "#fff",
accent: "#006cff",
neutral: "#060206",
"base-100": "#292924",
"base-200": "#2a2d2a",
"base-300": "#2b3130",
"base-content": "#fff",
info: "#009ae0",
success: "#76e200",
warning: "#eb9400",
error: "#be2133",
}
},
],
},
plugins: [require("@tailwindcss/forms"), require("@tailwindcss/typography"), require("daisyui"), require('preline/plugin')],
plugins: [
require("@tailwindcss/forms"),
require("@tailwindcss/typography"),
require("daisyui"),
require("preline/plugin"),
],
};
export default config;

View File

@ -0,0 +1,12 @@
import tw from '../tailwind.config'
export default tw.daisyui.themes[0];
export function hexToRgb(hex: string) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}

View File

@ -55,6 +55,20 @@ const signUpValidationSchema = Yup.object().shape({
.required("Please retype your password.")
.oneOf([Yup.ref("password")], "Your passwords do not match."),
});
const waitinglistValidationSchema = Yup.object().shape({
firstName: Yup.string().required("First Name is required"),
lastName: Yup.string().required("Last Name is required"),
email: Yup.string().email().required("E-mail is required"),
});
const contactUsValidationSchema = Yup.object().shape({
firstName: Yup.string().required("First Name is required"),
lastName: Yup.string().required("Last Name is required"),
note: Yup.string(),
phoneNumber: Yup.string()
.required("Phone Number is required")
.mobileNumberValidation("Phone Number is not valid"),
email: Yup.string().email().required("E-mail is required"),
});
const learnMoreValidationSchema = Yup.object().shape({
email: Yup.string().email().required("E-mail is required"),
@ -73,4 +87,6 @@ export {
learnMoreValidationSchema,
signUpValidationSchema,
signInValidationSchema,
waitinglistValidationSchema,
contactUsValidationSchema
};