diff --git a/Frontend/app/(authenticated)/account/page.jsx b/Frontend/app/(authenticated)/account/page.jsx
new file mode 100644
index 0000000..2fab39f
--- /dev/null
+++ b/Frontend/app/(authenticated)/account/page.jsx
@@ -0,0 +1,36 @@
+import React from "react"
+import PageHeader from "@/sections/PageHeader"
+import { cookies } from "next/headers"
+import { getUserFromCookie } from "@/lib/auth"
+import AccountContent from "@/sections/AccountContent"
+import { redirect } from "next/navigation"
+import pb from "@/lib/pocketbase"
+import Background from "@/components/Utilities/Background"
+import Footer from "@/components/Footer"
+import Spacer from "@/components/Utilities/Spacer"
+
+export default async function AccountPage() {
+ const user = await getUserFromCookie(cookies())
+ const cookie = cookies().get("pb_auth")
+ //server side
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ !pb.authStore.isValid && redirect("/")
+ return (
+ user && (
+
+
+
+
+
+ )
+ )
+}
diff --git a/Frontend/app/(authenticated)/account/page.tsx b/Frontend/app/(authenticated)/account/page.tsx
deleted file mode 100644
index 7f572f1..0000000
--- a/Frontend/app/(authenticated)/account/page.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import React from "react";
-import PageHeader from "@/sections/PageHeader";
-import { cookies } from "next/headers";
-import { getUserFromCookie } from "@/lib/auth";
-import { User } from "@/types";
-import AccountContent from "@/sections/AccountContent";
-import { redirect } from "next/navigation";
-import pb from "@/lib/pocketbase";
-import Background from "@/components/Utilities/Background";
-import Footer from "@/components/Footer";
-import Spacer from "@/components/Utilities/Spacer";
-
-export default async function AccountPage() {
- const user = (await getUserFromCookie(cookies())) as User;
- const cookie = cookies().get("pb_auth");
- //server side
- pb.authStore.loadFromCookie(cookie?.value || "");
- !pb.authStore.isValid && redirect("/");
- return (
- user && (
-
-
-
-
-
- )
- );
-}
diff --git a/Frontend/app/(public)/[ignore]/auth/confirm-email-change/[token]/page.jsx b/Frontend/app/(public)/[ignore]/auth/confirm-email-change/[token]/page.jsx
new file mode 100644
index 0000000..4c58fd6
--- /dev/null
+++ b/Frontend/app/(public)/[ignore]/auth/confirm-email-change/[token]/page.jsx
@@ -0,0 +1,89 @@
+"use client"
+
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { changeEmailValidationSchema } from "@/utils/form"
+import { toast } from "react-toastify"
+import PocketBase from "pocketbase"
+import PageWrapper from "@/components/Utilities/PageWrapper"
+import { usePathname } from "next/navigation"
+import Background from "@/components/Utilities/Background"
+import PageHeader from "@/sections/PageHeader"
+
+const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL)
+
+export default function ConfirmEmailChangePage() {
+ const pathName = usePathname()
+ const token = pathName.split("/").at(-1)
+ const {
+ register,
+ handleSubmit,
+ formState: { errors, isSubmitting },
+ reset
+ } = useForm({
+ resolver: yupResolver(changeEmailValidationSchema)
+ })
+
+ const onSubmit = async data => {
+ try {
+ await pb.collection("user").confirmEmailChange(token ?? "", data.password)
+ reset()
+ document.getElementById("sign-in-modal")?.click()
+ } catch (error) {
+ if (error instanceof Error) {
+ toast.error("There was a problem. Please try change your email again", {
+ position: "bottom-left",
+ autoClose: 5000,
+ hideProgressBar: false,
+ closeOnClick: true,
+ pauseOnHover: true,
+ draggable: true,
+ progress: undefined,
+ theme: "colored"
+ })
+ }
+ }
+ }
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/Frontend/app/(public)/[ignore]/auth/confirm-email-change/[token]/page.tsx b/Frontend/app/(public)/[ignore]/auth/confirm-email-change/[token]/page.tsx
deleted file mode 100644
index 9270ca9..0000000
--- a/Frontend/app/(public)/[ignore]/auth/confirm-email-change/[token]/page.tsx
+++ /dev/null
@@ -1,89 +0,0 @@
-"use client"
-
-import React from "react";
-import { useForm } from "react-hook-form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { changeEmailValidationSchema } from "@/utils/form";
-import { toast } from "react-toastify";
-import PocketBase from 'pocketbase';
-import PageWrapper from "@/components/Utilities/PageWrapper";
-import { usePathname, useRouter } from 'next/navigation';
-import Background from "@/components/Utilities/Background";
-import PageHeader from "@/sections/PageHeader";
-
-const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL as string);
-
-export default function ConfirmEmailChangePage() {
- const pathName = usePathname();
- const token = pathName.split('/').at(-1);
- const {
- register,
- handleSubmit,
- formState: { errors, isSubmitting },
- reset
- } = useForm({
- resolver: yupResolver(changeEmailValidationSchema),
- });
-
- const onSubmit = async (data: any) => {
- try {
- await pb.collection('user').confirmEmailChange(
- token ?? "",
- data.password,
- );
- reset();
- document.getElementById("sign-in-modal")?.click();
- } catch (error) {
- if (error instanceof Error) {
- toast.error("There was a problem. Please try change your email again", {
- position: "bottom-left",
- autoClose: 5000,
- hideProgressBar: false,
- closeOnClick: true,
- pauseOnHover: true,
- draggable: true,
- progress: undefined,
- theme: "colored",
- });
- }
- }
- };
-
- return (
-
-
-
-
-
- );
-}
diff --git a/Frontend/app/(public)/[ignore]/auth/confirm-password-reset/[token]/page.jsx b/Frontend/app/(public)/[ignore]/auth/confirm-password-reset/[token]/page.jsx
new file mode 100644
index 0000000..7399fb4
--- /dev/null
+++ b/Frontend/app/(public)/[ignore]/auth/confirm-password-reset/[token]/page.jsx
@@ -0,0 +1,108 @@
+"use client"
+
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { passwordValidationSchema } from "@/utils/form"
+import { toast } from "react-toastify"
+import PocketBase from "pocketbase"
+import PageWrapper from "@/components/Utilities/PageWrapper"
+import { usePathname } from "next/navigation"
+import Background from "@/components/Utilities/Background"
+import PageHeader from "@/sections/PageHeader"
+
+const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL)
+
+export default function ConfirmPasswordResetPage() {
+ const pathName = usePathname()
+ const token = pathName.split("/").at(-1)
+ const {
+ register,
+ handleSubmit,
+ formState: { errors, isSubmitting },
+ reset
+ } = useForm({
+ resolver: yupResolver(passwordValidationSchema)
+ })
+
+ const onSubmit = async data => {
+ try {
+ await pb
+ .collection("user")
+ .confirmPasswordReset(
+ token ?? "",
+ data.newPassword,
+ data.newPasswordConfirm
+ )
+ reset()
+ document.getElementById("sign-in-modal")?.click()
+ } catch (error) {
+ if (error instanceof Error) {
+ toast.error(
+ "There was a problem. Please try reset your password again",
+ {
+ position: "bottom-left",
+ autoClose: 5000,
+ hideProgressBar: false,
+ closeOnClick: true,
+ pauseOnHover: true,
+ draggable: true,
+ progress: undefined,
+ theme: "colored"
+ }
+ )
+ }
+ }
+ }
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/Frontend/app/(public)/[ignore]/auth/confirm-password-reset/[token]/page.tsx b/Frontend/app/(public)/[ignore]/auth/confirm-password-reset/[token]/page.tsx
deleted file mode 100644
index ef3f365..0000000
--- a/Frontend/app/(public)/[ignore]/auth/confirm-password-reset/[token]/page.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-"use client"
-
-import React from "react";
-import { useForm } from "react-hook-form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { passwordValidationSchema } from "@/utils/form";
-import { toast } from "react-toastify";
-import PocketBase from 'pocketbase';
-import PageWrapper from "@/components/Utilities/PageWrapper";
-import { usePathname, useRouter } from 'next/navigation';
-import Background from "@/components/Utilities/Background";
-import PageHeader from "@/sections/PageHeader";
-
-const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL as string);
-
-export default function ConfirmPasswordResetPage() {
- const pathName = usePathname();
- const token = pathName.split('/').at(-1);
- const {
- register,
- handleSubmit,
- formState: { errors, isSubmitting },
- reset
- } = useForm({
- resolver: yupResolver(passwordValidationSchema),
- });
-
- const onSubmit = async (data: any) => {
- try {
- await pb.collection('user').confirmPasswordReset(
- token ?? "",
- data.newPassword,
- data.newPasswordConfirm,
- );
- reset()
- document.getElementById("sign-in-modal")?.click();
- } catch (error) {
- if (error instanceof Error) {
- toast.error("There was a problem. Please try reset your password again", {
- position: "bottom-left",
- autoClose: 5000,
- hideProgressBar: false,
- closeOnClick: true,
- pauseOnHover: true,
- draggable: true,
- progress: undefined,
- theme: "colored",
- });
- }
- }
- };
-
- return (
-
-
-
-
-
- );
-}
diff --git a/Frontend/app/(public)/[ignore]/auth/confirm-verification/[token]/page.jsx b/Frontend/app/(public)/[ignore]/auth/confirm-verification/[token]/page.jsx
new file mode 100644
index 0000000..7399fb4
--- /dev/null
+++ b/Frontend/app/(public)/[ignore]/auth/confirm-verification/[token]/page.jsx
@@ -0,0 +1,108 @@
+"use client"
+
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { passwordValidationSchema } from "@/utils/form"
+import { toast } from "react-toastify"
+import PocketBase from "pocketbase"
+import PageWrapper from "@/components/Utilities/PageWrapper"
+import { usePathname } from "next/navigation"
+import Background from "@/components/Utilities/Background"
+import PageHeader from "@/sections/PageHeader"
+
+const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL)
+
+export default function ConfirmPasswordResetPage() {
+ const pathName = usePathname()
+ const token = pathName.split("/").at(-1)
+ const {
+ register,
+ handleSubmit,
+ formState: { errors, isSubmitting },
+ reset
+ } = useForm({
+ resolver: yupResolver(passwordValidationSchema)
+ })
+
+ const onSubmit = async data => {
+ try {
+ await pb
+ .collection("user")
+ .confirmPasswordReset(
+ token ?? "",
+ data.newPassword,
+ data.newPasswordConfirm
+ )
+ reset()
+ document.getElementById("sign-in-modal")?.click()
+ } catch (error) {
+ if (error instanceof Error) {
+ toast.error(
+ "There was a problem. Please try reset your password again",
+ {
+ position: "bottom-left",
+ autoClose: 5000,
+ hideProgressBar: false,
+ closeOnClick: true,
+ pauseOnHover: true,
+ draggable: true,
+ progress: undefined,
+ theme: "colored"
+ }
+ )
+ }
+ }
+ }
+
+ return (
+
+
+
+
+
+ )
+}
diff --git a/Frontend/app/(public)/[ignore]/auth/confirm-verification/[token]/page.tsx b/Frontend/app/(public)/[ignore]/auth/confirm-verification/[token]/page.tsx
deleted file mode 100644
index 15382d1..0000000
--- a/Frontend/app/(public)/[ignore]/auth/confirm-verification/[token]/page.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-"use client"
-
-import React, { useEffect } from "react";
-import { toast } from "react-toastify";
-import PocketBase from 'pocketbase';
-import PageWrapper from "@/components/Utilities/PageWrapper";
-import { usePathname, useRouter } from 'next/navigation';
-import Background from "@/components/Utilities/Background";
-import PageHeader from "@/sections/PageHeader";
-
-const pb = new PocketBase(process.env.NEXT_PUBLIC_POCKETBASE_URL as string);
-
-export default function ConfirmVerification() {
- const pathName = usePathname();
- const router = useRouter();
- const token = pathName.split('/').at(-1);
-
- useEffect(() => {
- (async () => {
- try {
- await pb.collection('user').confirmVerification(
- token ?? ""
- );
- } catch (error) {
- if (error instanceof Error) {
- toast.error("There was a problem. Please try confirm your email again", {
- position: "bottom-left",
- autoClose: 5000,
- hideProgressBar: false,
- closeOnClick: true,
- pauseOnHover: true,
- draggable: true,
- progress: undefined,
- theme: "colored",
- });
- }
- }
- })()
- }, [])
-
- const handleSignInRedirect = () => {
- document.getElementById("sign-in-modal")?.click();
- };
-
- return (
-
-
-
-
>}
- />
-
- Go to Sign In
-
-
-
-
- );
-}
diff --git a/Frontend/app/(public)/about/page.tsx b/Frontend/app/(public)/about/page.jsx
similarity index 53%
rename from Frontend/app/(public)/about/page.tsx
rename to Frontend/app/(public)/about/page.jsx
index aeae38f..268d73c 100644
--- a/Frontend/app/(public)/about/page.tsx
+++ b/Frontend/app/(public)/about/page.jsx
@@ -1,8 +1,8 @@
-import PageHeader from "@/sections/PageHeader";
-import React from "react";
-import Footer from "@/components/Footer";
-import Image from "next/image";
-import Link from "next/link";
+import PageHeader from "@/sections/PageHeader"
+import React from "react"
+import Footer from "@/components/Footer"
+import Image from "next/image"
+import Link from "next/link"
export default async function About() {
return (
@@ -15,20 +15,45 @@ export default async function About() {
- In 2023 I built Sign365 using pocketbase
- and setup an open source library to help people get setup with Stripe
- + Pocketbase. As 2024 has come around I have had more and more
- requests for applications and features on the existing code. I built a
- codebase that would save me 20 hours + in the bootstrapping time to
- get my applications ready. That is why I had to build FastPocket an
- easy solution to give everyone a head start.
+ In 2023 I built{" "}
+
+ Sign365
+ {" "}
+ using pocketbase and setup an open source library to help people get
+ setup with{" "}
+
+ Stripe + Pocketbase
+
+ . As 2024 has come around I have had more and more requests for
+ applications and features on the existing code. I built a codebase
+ that would save me 20 hours + in the bootstrapping time to get my
+ applications ready. That is why I had to build{" "}
+
+ FastPocket
+ {" "}
+ an easy solution to give everyone a head start.
After reflecting on the challenges that developers face building their
applications, I've seen that there will never be one codebase
that suits all developers. But I am sure for those who are
opensourcing, self-hosting and want to spin up an application quickly
- they will be able to do it using FastPocket
+ they will be able to do it using{" "}
+
+ FastPocket
+
I am taking all of the knowledge that I have gained across 20+
@@ -38,11 +63,23 @@ export default async function About() {
that have been battle tested in enterprise code
- So I've committed to building FastPocket to help you build your
- projects faster to get paid.
+ So I've committed to building{" "}
+
+ FastPocket
+ {" "}
+ to help you build your projects faster to get paid.
- FastPocket will get you producing more with less development.
+
+ FastPocket
+ {" "}
+ will get you producing more with less development.
I know that your next project will grow exponentially because of the
@@ -69,5 +106,5 @@ export default async function About() {
- );
+ )
}
diff --git a/Frontend/app/(public)/blogs/[slug]/page.tsx b/Frontend/app/(public)/blogs/[slug]/page.jsx
similarity index 56%
rename from Frontend/app/(public)/blogs/[slug]/page.tsx
rename to Frontend/app/(public)/blogs/[slug]/page.jsx
index 41ffa96..7159902 100644
--- a/Frontend/app/(public)/blogs/[slug]/page.tsx
+++ b/Frontend/app/(public)/blogs/[slug]/page.jsx
@@ -1,32 +1,28 @@
-import BlogContent from "@/sections/BlogContent";
-import getPostMetadata from "@/utils/getPostMetaData";
-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";
+import BlogContent from "@/sections/BlogContent"
+import getPostMetadata from "@/utils/getPostMetaData"
+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,
-}: {
- params: { slug: string };
-}) {
- const { slug } = params;
- const headersList = headers();
- const siteURL = headersList.get("host");
- pb.autoCancellation(false);
+export async function generateMetadata({ params }) {
+ const { slug } = params
+ const headersList = headers()
+ const siteURL = headersList.get("host")
+ pb.autoCancellation(false)
const post = await pb.collection("blog").getFirstListItem(`slug="${slug}"`, {
- requestKey: "metaData",
- });
- pb.autoCancellation(true);
+ requestKey: "metaData"
+ })
+ pb.autoCancellation(true)
return {
title: `${post.title} | FastPocket`,
authors: [
{
- name: post.author || "Samuel Wyndham",
- },
+ name: post.author || "Samuel Wyndham"
+ }
],
description: post.description,
keywords: post.keywords,
@@ -44,9 +40,9 @@ export async function generateMetadata({
width: 1024,
height: 576,
alt: post.title,
- type: "image/png",
- },
- ],
+ type: "image/png"
+ }
+ ]
},
twitter: {
card: "summary_large_image",
@@ -59,32 +55,32 @@ export async function generateMetadata({
url: `${post.imageUrl}`,
width: 1024,
height: 576,
- alt: post.title,
- },
- ],
+ alt: post.title
+ }
+ ]
},
alternates: {
- canonical: `https://${siteURL}/blogs/${post.slug}`,
- },
- };
+ canonical: `https://${siteURL}/blogs/${post.slug}`
+ }
+ }
}
export const generateStaticParams = async () => {
- const posts = await getPostMetadata();
- console.log("static posts", posts.length);
- const mappedPosts = posts.map((post) => ({
- slug: post.slug,
- }));
- return mappedPosts;
-};
+ const posts = await getPostMetadata()
+ console.log("static posts", posts.length)
+ const mappedPosts = posts.map(post => ({
+ slug: post.slug
+ }))
+ return mappedPosts
+}
-const PostPage = async (props: any) => {
- console.log("params", props.params);
+const PostPage = async props => {
+ console.log("params", props.params)
const post = await pb
.collection("blog")
.getFirstListItem(`slug="` + props.params.slug + `"`, {
- requestKey: "post",
- });
+ requestKey: "post"
+ })
return (
{
- );
-};
+ )
+}
-export default PostPage;
+export default PostPage
diff --git a/Frontend/app/(public)/blogs/page.tsx b/Frontend/app/(public)/blogs/page.jsx
similarity index 69%
rename from Frontend/app/(public)/blogs/page.tsx
rename to Frontend/app/(public)/blogs/page.jsx
index b4ef42f..20845c9 100644
--- a/Frontend/app/(public)/blogs/page.tsx
+++ b/Frontend/app/(public)/blogs/page.jsx
@@ -1,17 +1,17 @@
-import PageHeader from "@/sections/PageHeader";
-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";
+import PageHeader from "@/sections/PageHeader"
+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();
+ const postMetadata = await getPostMetadata()
- console.log("blogs", postMetadata.length);
+ console.log("blogs", postMetadata.length)
const postPreviews = postMetadata
.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
- .map((post) => );
+ .map(post => )
return (
- );
+ )
}
diff --git a/Frontend/app/(public)/contact/page.tsx b/Frontend/app/(public)/contact/page.jsx
similarity index 68%
rename from Frontend/app/(public)/contact/page.tsx
rename to Frontend/app/(public)/contact/page.jsx
index ba8e525..a57ddda 100644
--- a/Frontend/app/(public)/contact/page.tsx
+++ b/Frontend/app/(public)/contact/page.jsx
@@ -1,9 +1,9 @@
-import Footer from "@/components/Footer";
-import Background from "@/components/Utilities/Background";
-import Spacer from "@/components/Utilities/Spacer";
-import FormLeftDescriptionRightContactUs from "@/sections/ContactUs/FormLeftDescriptionRightContactUs";
-import PageHeader from "@/sections/PageHeader";
-import React from "react";
+import Footer from "@/components/Footer"
+import Background from "@/components/Utilities/Background"
+import Spacer from "@/components/Utilities/Spacer"
+import FormLeftDescriptionRightContactUs from "@/sections/ContactUs/FormLeftDescriptionRightContactUs"
+import PageHeader from "@/sections/PageHeader"
+import React from "react"
const page = () => {
return (
@@ -25,7 +25,7 @@ const page = () => {
- );
-};
+ )
+}
-export default page;
+export default page
diff --git a/Frontend/app/(public)/pricing/action.js b/Frontend/app/(public)/pricing/action.js
new file mode 100644
index 0000000..e7bdc7d
--- /dev/null
+++ b/Frontend/app/(public)/pricing/action.js
@@ -0,0 +1,51 @@
+"use server"
+import pb from "@/lib/pocketbase"
+
+export async function apiPrices() {
+ try {
+ const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL
+ if (!pocketbaseUrl) {
+ throw Error("Connection Timeout")
+ }
+ const productRequest = await fetch(
+ `${pocketbaseUrl}/api/collections/product/records?filter=(active=true)`,
+ {
+ cache: "no-cache",
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json"
+ }
+ }
+ )
+ const productResponse = await productRequest.json()
+ console.log("app/pricing/action", "productResponse", productResponse)
+ const unsortedProducts = productResponse.items
+ console.log("app/pricing/action", "unsortedProducts", unsortedProducts)
+ const prices = await pb.collection("price").getFullList()
+ console.log("app/pricing/action", "prices", prices)
+ for (const product of unsortedProducts) {
+ product.metadata.benefits = product?.metadata?.benefits
+ ? JSON.parse(product.metadata.benefits)
+ : []
+ const pricesOfProduct = prices.filter(
+ price => price.product_id === product.product_id
+ )
+ for (const priceOfProduct of pricesOfProduct) {
+ product.type = priceOfProduct.type
+ if (priceOfProduct.interval === "year") {
+ product.yearlyPrice = priceOfProduct
+ } else {
+ product.monthlyPrice = priceOfProduct
+ }
+ }
+ }
+
+ const sortedProducts = unsortedProducts.sort(
+ (a, b) => a.product_order - b.product_order
+ )
+ return sortedProducts
+ } catch (error) {
+ console.log(error)
+ return []
+ }
+}
diff --git a/Frontend/app/(public)/pricing/actions.ts b/Frontend/app/(public)/pricing/actions.ts
deleted file mode 100644
index 1baea0b..0000000
--- a/Frontend/app/(public)/pricing/actions.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-"use server";
-
-import { Product, Price } from "@/types";
-import pb from "@/lib/pocketbase";
-
-export async function apiPrices() {
- try {
- const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL;
- if (!pocketbaseUrl) {
- throw Error('Connection Timeout');
- }
- const productRequest = await fetch(
- `${pocketbaseUrl}/api/collections/product/records?filter=(active=true)`,
- {
- cache: 'no-cache',
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- },
- }
- );
- const productResponse = await productRequest.json();
- console.log("app/pricing/actions","productResponse",productResponse)
- const unsortedProducts: Product[] = productResponse.items;
- console.log("app/pricing/actions","unsortedProducts",unsortedProducts)
- const prices = await pb.collection("price").getFullList();
- console.log("app/pricing/actions","prices",prices)
- for (const product of unsortedProducts) {
- product.metadata.benefits = product?.metadata?.benefits ? JSON.parse(product.metadata.benefits as any) : [];
- const pricesOfProduct = prices.filter(price => price.product_id === product.product_id);
- for (const priceOfProduct of pricesOfProduct){
- product.type = priceOfProduct.type;
- if (priceOfProduct.interval === "year"){
- product.yearlyPrice = priceOfProduct;
- } else {
- product.monthlyPrice = priceOfProduct;
- }
- }
- }
-
- const sortedProducts = unsortedProducts.sort((a: Product, b: Product) => a.product_order - b.product_order)
- return sortedProducts;
- } catch (error) {
- console.log(error);
- return [];
- }
-}
\ No newline at end of file
diff --git a/Frontend/app/(public)/pricing/page.tsx b/Frontend/app/(public)/pricing/page.jsx
similarity index 76%
rename from Frontend/app/(public)/pricing/page.tsx
rename to Frontend/app/(public)/pricing/page.jsx
index 8ad1c66..263c6f6 100644
--- a/Frontend/app/(public)/pricing/page.tsx
+++ b/Frontend/app/(public)/pricing/page.jsx
@@ -1,13 +1,13 @@
"use client"
-import React from "react";
-import PageHeader from "@/sections/PageHeader";
-import Newsletter from "@/sections/Newsletter/Newsletter";
-import Background from "@/components/Utilities/Background";
-import Footer from "@/components/Footer";
-import Payment from "@/sections/Payment";
-import Spacer from "@/components/Utilities/Spacer";
-import SolidBackgrondIconFeature from "@/sections/Features/SolidBackgrondIconFeature";
+import React from "react"
+import PageHeader from "@/sections/PageHeader"
+import Newsletter from "@/sections/Newsletter/Newsletter"
+import Background from "@/components/Utilities/Background"
+import Footer from "@/components/Footer"
+import Payment from "@/sections/Payment"
+import Spacer from "@/components/Utilities/Spacer"
+import SolidBackgrondIconFeature from "@/sections/Features/SolidBackgrondIconFeature"
export default function PricingPage() {
return (
@@ -44,5 +44,5 @@ export default function PricingPage() {
- );
+ )
}
diff --git a/Frontend/app/(public)/whatsnew/page.tsx b/Frontend/app/(public)/whatsnew/page.jsx
similarity index 70%
rename from Frontend/app/(public)/whatsnew/page.tsx
rename to Frontend/app/(public)/whatsnew/page.jsx
index 865bcba..09c3914 100644
--- a/Frontend/app/(public)/whatsnew/page.tsx
+++ b/Frontend/app/(public)/whatsnew/page.jsx
@@ -1,11 +1,11 @@
"use client"
-import Footer from "@/components/Footer";
-import Background from "@/components/Utilities/Background";
-import Spacer from "@/components/Utilities/Spacer";
-import SolidBackgrondIconFeature from "@/sections/Features/SolidBackgrondIconFeature";
-import PageHeader from "@/sections/PageHeader";
-import React from "react";
+import Footer from "@/components/Footer"
+import Background from "@/components/Utilities/Background"
+import Spacer from "@/components/Utilities/Spacer"
+import SolidBackgrondIconFeature from "@/sections/Features/SolidBackgrondIconFeature"
+import PageHeader from "@/sections/PageHeader"
+import React from "react"
const page = () => {
return (
@@ -28,7 +28,7 @@ const page = () => {
- );
-};
+ )
+}
-export default page;
+export default page
diff --git a/Frontend/app/actions.js b/Frontend/app/actions.js
new file mode 100644
index 0000000..8de57c1
--- /dev/null
+++ b/Frontend/app/actions.js
@@ -0,0 +1,287 @@
+"use server"
+import { redirect } from "next/navigation"
+import pb from "@/lib/pocketbase"
+import { cookies } from "next/headers"
+import CryptoJS from "crypto-js"
+
+import { apiPrices } from "./(public)/pricing/action"
+
+export async function mailchimp(formData) {
+ const email = formData.email
+ const mailchimpBaseUrl = process.env.NEXT_PUBLIC_MAILCHIMP_BASE_URL
+ const mailchimpApiKey = process.env.NEXT_PUBLIC_MAILCHIMP_BASE64_API_KEY
+ const mailchimpList = process.env.NEXT_PUBLIC_MAILCHIMP_LIST_ID
+ if (!mailchimpApiKey) return
+ try {
+ const subscriberHash = CryptoJS.MD5(email.toLocaleLowerCase())
+ const mailchimpResponse = await fetch(
+ `${mailchimpBaseUrl}/3.0/lists/${mailchimpList}/members/${subscriberHash}`,
+ {
+ method: "PUT",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: mailchimpApiKey
+ },
+ body: JSON.stringify({
+ email_address: email,
+ status: "subscribed",
+ merge_fields: {
+ EMAIL: formData.email,
+ FNAME: formData.first_name,
+ LNAME: formData.last_name,
+ PHONE: !formData.phone_number ? "" : formData.phone_number,
+ CSIZE: formData.company_size,
+ SOURCE: formData.source
+ }
+ })
+ }
+ )
+ if (mailchimpResponse.status !== 200) {
+ throw new Error("couldn't complete the request")
+ }
+ return mailchimpResponse.json()
+ } catch (err) {
+ throw new Error("couldn't complete the request")
+ }
+}
+
+export async function signup(formData) {
+ const email = formData.email
+ const password = formData.password
+ const organisation = formData.organisation
+ console.log("app/(authenticated)/actions", "organisation", organisation)
+ const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL
+ const adminToken = process.env.NEXT_PUBLIC_POCKETBASE_ADMIN_TOKEN
+ try {
+ const orgRes = await fetch(
+ `${pocketbaseUrl}/api/collections/organisation/records`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: adminToken
+ },
+ body: JSON.stringify({
+ name: organisation
+ })
+ }
+ )
+ console.log("orgRes.status: ", orgRes.status)
+ if (orgRes.status !== 200) {
+ throw new Error("Failed to create organisation")
+ }
+ const orgData = await orgRes.json()
+ console.log(orgData)
+ const userRes = await fetch(
+ `${pocketbaseUrl}/api/collections/user/records`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: adminToken
+ },
+ body: JSON.stringify({
+ firstName: formData.first_name,
+ lastName: formData.last_name,
+ displayName: formData.first_name + " " + formData.last_name,
+ email: email,
+ password: password,
+ passwordConfirm: password,
+ organisation: orgData?.id,
+ role: "Admin",
+ lastSeen: new Date()
+ })
+ }
+ )
+ console.log("userRes.status: ", userRes.status)
+ if (userRes.status !== 200) {
+ console.log(userRes)
+ throw new Error("Failed to create user")
+ }
+ } catch (err) {
+ if (err instanceof Error) {
+ throw new Error(err.message)
+ }
+ }
+}
+
+export async function login(formData) {
+ console.log("login")
+ const email = formData.email
+ const password = formData.password
+ try {
+ const { token, record: data } = await pb
+ .collection("user")
+ .authWithPassword(email, password)
+ if (pb.authStore.isValid) {
+ const cookie = pb.authStore.exportToCookie()
+
+ cookies().set("pb_auth", cookie, {
+ secure: true,
+ path: "/",
+ sameSite: "strict",
+ httpOnly: true
+ })
+ }
+ return {
+ success: true,
+ error: "Failed to log in",
+ token: token,
+ data: data
+ }
+ } catch (error) {
+ console.log(error)
+ if (error.status == 403) {
+ await pb.collection("user").requestVerification(email)
+ }
+ return JSON.parse(JSON.stringify(error))
+ }
+}
+
+export async function getAuthCookie() {
+ try {
+ const cookie = cookies().get("pb_auth")
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ return pb.authStore.token
+ } catch (error) {
+ return undefined
+ }
+}
+
+export async function isAuthenticated() {
+ try {
+ const cookie = cookies().get("pb_auth")
+ if (!cookie) return false
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ return pb.authStore.isValid || false
+ } catch (error) {
+ return undefined
+ }
+}
+export async function getUser() {
+ try {
+ const cookie = cookies().get("pb_auth")
+ if (!cookie) return false
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ return pb.authStore.model
+ } catch (error) {
+ return undefined
+ }
+}
+
+export async function logout() {
+ cookies().delete("pb_auth")
+ redirect("/")
+}
+
+export async function createCheckoutSession(price_id, type) {
+ const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL
+ if (!pocketbaseUrl) {
+ throw Error("Connection Timeout")
+ }
+ if (!price_id) {
+ throw Error("There was an error during the payment processing")
+ }
+ const token = await getAuthCookie()
+ if (!token) {
+ throw Error("Could not authenticate")
+ }
+ console.log("token", token)
+ console.log("url ", `${pocketbaseUrl}/create-checkout-session`)
+
+ const body = JSON.stringify({
+ price: {
+ id: price_id,
+ type: type
+ },
+ quantity: 1
+ })
+ console.log("body", body)
+
+ try {
+ const createCheckoutSessionResponse = await fetch(
+ `${pocketbaseUrl}/create-checkout-session`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: token
+ },
+ body: body
+ }
+ )
+ if (createCheckoutSessionResponse.status !== 200) {
+ throw new Error("Failed to process Request")
+ }
+
+ const createCheckoutSessionData = await createCheckoutSessionResponse.json()
+
+ if (createCheckoutSessionData.url === "") {
+ throw new Error("Failed to process request an invalid URL was served")
+ }
+ return createCheckoutSessionData
+ } catch (error) {
+ throw error
+ }
+}
+
+export async function getSubscriptions() {
+ const cookie = cookies().get("pb_auth")
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ const userId = pb.authStore.model.id
+ const subscriptions = await pb
+ .collection("subscription")
+ .getFullList({ filter: `user_id="${userId}" && status="active"` })
+ console.log("app/(authenticated)/actions", "subscriptions", subscriptions)
+ if (subscriptions.length === 0) {
+ return []
+ }
+ const products = await apiPrices()
+ const subscriptionWithProducts = subscriptions.map(subscription => {
+ return {
+ ...subscription,
+ product: products.find(
+ product =>
+ product?.yearlyPrice?.price_id === subscription.price_id ||
+ product?.monthlyPrice?.price_id === subscription.price_id
+ )
+ }
+ })
+ return subscriptionWithProducts
+}
+
+export async function createManagementSubscriptionSession() {
+ const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL
+ if (!pocketbaseUrl) {
+ throw Error("Connection Timeout")
+ }
+ const token = await getAuthCookie()
+ if (!token) {
+ throw Error("Could not authenticate")
+ }
+ console.log("token", token)
+ console.log("url ", `${pocketbaseUrl}/create-checkout-session`)
+ try {
+ const createManagementSessionResponse = await fetch(
+ `${pocketbaseUrl}/create-portal-link`,
+ {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ Authorization: token
+ },
+ body: JSON.stringify({})
+ }
+ )
+ if (createManagementSessionResponse.status !== 200) {
+ console.log(createManagementSessionResponse.status)
+ throw new Error(
+ JSON.stringify(await createManagementSessionResponse.json())
+ )
+ }
+ const createManagementSessionData = await createManagementSessionResponse.json()
+ return createManagementSessionData
+ } catch (error) {
+ throw error
+ }
+}
diff --git a/Frontend/app/actions.ts b/Frontend/app/actions.ts
deleted file mode 100644
index 790a65a..0000000
--- a/Frontend/app/actions.ts
+++ /dev/null
@@ -1,278 +0,0 @@
-"use server";
-
-import { redirect } from "next/navigation";
-import pb from "@/lib/pocketbase";
-import { cookies } from "next/headers";
-import CryptoJS from 'crypto-js';
-
-import { CheckoutSession, SignUpForm, SourceModal, Subscription, SubscriptionSession, User } from "@/types";
-import { apiPrices } from "./(public)/pricing/actions";
-
-export async function mailchimp(formData: {
- email: string;
- first_name: string;
- last_name: string;
- phone_number?: string;
- company_size: string;
- source?: SourceModal;
-}) {
- const email = formData.email;
- const mailchimpBaseUrl = process.env.NEXT_PUBLIC_MAILCHIMP_BASE_URL;
- const mailchimpApiKey = process.env.NEXT_PUBLIC_MAILCHIMP_BASE64_API_KEY;
- const mailchimpList = process.env.NEXT_PUBLIC_MAILCHIMP_LIST_ID;
- if (!mailchimpApiKey) return;
- try {
- const subscriberHash = CryptoJS.MD5(email.toLocaleLowerCase());
- const mailchimpResponse = await fetch(`${mailchimpBaseUrl}/3.0/lists/${mailchimpList}/members/${subscriberHash}`,
- {
- method: 'PUT',
- headers: {
- "Content-Type": "application/json",
- Authorization: mailchimpApiKey,
- },
- body: JSON.stringify(
- {
- "email_address": email,
- status: "subscribed",
- merge_fields: {
- EMAIL: formData.email,
- FNAME: formData.first_name,
- LNAME: formData.last_name,
- PHONE: !formData.phone_number ? '' : formData.phone_number,
- CSIZE: formData.company_size,
- SOURCE: formData.source
- }
- }
- )
- })
- if (mailchimpResponse.status !== 200) {
- throw new Error("couldn't complete the request");
- }
- return mailchimpResponse.json();
- } catch (err) {
- throw new Error("couldn't complete the request");
- }
-}
-
-export async function signup(formData: SignUpForm) {
- const email = formData.email;
- const password = formData.password;
- const organisation = formData.organisation;
- console.log('app/(authenticated)/actions', 'organisation', organisation)
- const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL as string;
- const adminToken = process.env.NEXT_PUBLIC_POCKETBASE_ADMIN_TOKEN as string;
- try {
- const orgRes = await fetch(
- `${pocketbaseUrl}/api/collections/organisation/records`,
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: adminToken,
- },
- body: JSON.stringify({
- name: organisation,
- }),
- }
- );
- console.log("orgRes.status: ", orgRes.status);
- if (orgRes.status !== 200) {
- throw new Error("Failed to create organisation");
- }
- const orgData = await orgRes.json();
- console.log(orgData);
- const userRes = await fetch(
- `${pocketbaseUrl}/api/collections/user/records`,
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: adminToken,
- },
- body: JSON.stringify({
- firstName: formData.first_name,
- lastName: formData.last_name,
- displayName: formData.first_name + ' ' + formData.last_name,
- email: email,
- password: password,
- passwordConfirm: password,
- organisation: orgData?.id,
- role: "Admin",
- lastSeen: new Date(),
- }),
- }
- );
- console.log("userRes.status: ", userRes.status);
- if (userRes.status !== 200) {
- console.log(userRes);
- throw new Error("Failed to create user");
- }
- } catch (err) {
- if (err instanceof Error) {
- throw new Error(err.message);
- }
- }
-}
-
-export async function login(formData: { email: string; password: string }) {
- console.log('login')
- const email = formData.email as string;
- const password = formData.password as string;
- try {
- const { token, record: data } = await pb
- .collection("user")
- .authWithPassword(email, password);
- if (pb.authStore.isValid) {
- const cookie = pb.authStore.exportToCookie();
-
- cookies().set("pb_auth", cookie, {
- secure: true,
- path: "/",
- sameSite: "strict",
- httpOnly: true,
- });
- }
- return { success: true, error: "Failed to log in", token: token, data: data };
- } catch (error) {
- console.log(error)
- if ((error as any).status == 403) {
- await pb.collection('user').requestVerification(email);
- }
- return JSON.parse(JSON.stringify(error))
- }
-}
-
-export async function getAuthCookie() {
- try {
- const cookie = cookies().get('pb_auth');
- pb.authStore.loadFromCookie(cookie?.value || '');
- return pb.authStore.token;
- } catch (error) {
- return undefined;
- }
-}
-
-export async function isAuthenticated() {
- try {
- const cookie = cookies().get('pb_auth');
- if(!cookie) return false;
- pb.authStore.loadFromCookie(cookie?.value || '');
- return pb.authStore.isValid || false;
- } catch (error) {
- return undefined;
- }
-}
-export async function getUser() {
- try {
- const cookie = cookies().get('pb_auth');
- if(!cookie) return false;
- pb.authStore.loadFromCookie(cookie?.value || '');
- return pb.authStore.model;
- } catch (error) {
- return undefined;
- }
-}
-
-export async function logout() {
- cookies().delete("pb_auth");
- redirect('/');
-}
-
-export async function createCheckoutSession(price_id: string, type: string) {
- const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL;
- if (!pocketbaseUrl) {
- throw Error('Connection Timeout');
- }
- if (!price_id) {
- throw Error('There was an error during the payment processing');
- }
- const token = await getAuthCookie();
- if (!token) {
- throw Error('Could not authenticate');
- }
- console.log('token', token);
- console.log('url ', `${pocketbaseUrl}/create-checkout-session`);
-
- const body = JSON.stringify({
- price: {
- id: price_id,
- type: type
- },
- quantity: 1
- });
- console.log('body',body);
-
- try{
- const createCheckoutSessionResponse = await fetch(
- `${pocketbaseUrl}/create-checkout-session`,
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: token,
- },
- body: body,
- }
- );
- if (createCheckoutSessionResponse.status !== 200) {
- throw new Error("Failed to process Request");
- }
-
- const createCheckoutSessionData: CheckoutSession = await createCheckoutSessionResponse.json();
-
- if (createCheckoutSessionData.url === "") {
- throw new Error("Failed to process request an invalid URL was served");
- }
- return createCheckoutSessionData;
- } catch (error) {
- throw error;
- }
-}
-
-export async function getSubscriptions() {
- const cookie = cookies().get('pb_auth');
- pb.authStore.loadFromCookie(cookie?.value || '');
- const userId = (pb.authStore.model as User).id
- const subscriptions = await pb.collection("subscription").getFullList({filter: `user_id="${userId}" && status="active"`});
- console.log('app/(authenticated)/actions', 'subscriptions', subscriptions)
- if (subscriptions.length === 0){
- return [];
- }
- const products = await apiPrices();
- const subscriptionWithProducts = subscriptions.map(subscription => {return {...subscription, product: products.find(product => product?.yearlyPrice?.price_id === subscription.price_id || product?.monthlyPrice?.price_id === subscription.price_id)}}) as Subscription[]
- return subscriptionWithProducts;
-}
-
-export async function createManagementSubscriptionSession() {
- const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL;
- if (!pocketbaseUrl) {
- throw Error('Connection Timeout');
- }
- const token = await getAuthCookie();
- if (!token) {
- throw Error('Could not authenticate');
- }
- console.log('token', token);
- console.log('url ', `${pocketbaseUrl}/create-checkout-session`);
- try{
- const createManagementSessionResponse = await fetch(
- `${pocketbaseUrl}/create-portal-link`,
- {
- method: "POST",
- headers: {
- "Content-Type": "application/json",
- Authorization: token,
- },
- body: JSON.stringify({}),
- }
- );
- if (createManagementSessionResponse.status !== 200) {
- console.log(createManagementSessionResponse.status)
- throw new Error(JSON.stringify( await createManagementSessionResponse.json()));
- }
- const createManagementSessionData: SubscriptionSession = await createManagementSessionResponse.json();
- return createManagementSessionData;
- } catch (error) {
- throw error;
- }
-}
\ No newline at end of file
diff --git a/Frontend/app/layout.tsx b/Frontend/app/layout.jsx
similarity index 77%
rename from Frontend/app/layout.tsx
rename to Frontend/app/layout.jsx
index de5e2b4..7f68825 100644
--- a/Frontend/app/layout.tsx
+++ b/Frontend/app/layout.jsx
@@ -1,40 +1,36 @@
/* eslint-disable @next/next/no-before-interactive-script-outside-document */
-import "./globals.css";
-import "../app/globals.css";
-import { Arimo, Indie_Flower } from "next/font/google";
-import { ToastContainer } from "react-toastify";
-import "react-toastify/dist/ReactToastify.css";
-import Header from "@/components/Header";
-import { cookies } from "next/headers";
-import { isAuthenticated } from "@/lib/auth";
-import { GTagProvider, PHProvider, ThemeProvider } from "./providers";
-import Script from "next/script";
+import "./globals.css"
+import "../app/globals.css"
+import { Arimo, Indie_Flower } from "next/font/google"
+import { ToastContainer } from "react-toastify"
+import "react-toastify/dist/ReactToastify.css"
+import Header from "@/components/Header"
+import { cookies } from "next/headers"
+import { isAuthenticated } from "@/lib/auth"
+import { GTagProvider, PHProvider, ThemeProvider } from "./providers"
+import Script from "next/script"
const raleway = Arimo({
variable: "--body-font",
subsets: ["latin"],
- display: "swap",
-});
+ display: "swap"
+})
const arimo = Arimo({
variable: "--body-font",
subsets: ["latin"],
- display: "swap",
-});
+ display: "swap"
+})
const indieFlower = Indie_Flower({
variable: "--accent-font",
weight: "400",
subsets: ["latin"],
- display: "swap",
-});
+ display: "swap"
+})
-export default async function RootLayout({
- children,
-}: {
- children: React.ReactNode;
-}) {
- const isUserLoggedIn = await isAuthenticated(cookies());
+export default async function RootLayout({ children }) {
+ const isUserLoggedIn = await isAuthenticated(cookies())
return (
-
+
{children}
@@ -84,7 +83,7 @@ export default async function RootLayout({
id="promotekit"
async
defer
- strategy="afterInteractive"
+ strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `
$(document).ready(function(){
@@ -103,11 +102,11 @@ export default async function RootLayout({
}, 2000);
});
- `,
+ `
}}
>
- );
+ )
}
diff --git a/Frontend/app/not-found.tsx b/Frontend/app/not-found.jsx
similarity index 94%
rename from Frontend/app/not-found.tsx
rename to Frontend/app/not-found.jsx
index 1801ac3..e5f7f28 100644
--- a/Frontend/app/not-found.tsx
+++ b/Frontend/app/not-found.jsx
@@ -1,7 +1,5 @@
-import Footer from "@/components/Footer";
-import Background from "@/components/Utilities/Background";
-import PageWrapper from "@/components/Utilities/PageWrapper";
-import Link from "next/link";
+import Background from "@/components/Utilities/Background"
+import Link from "next/link"
export default function NotFound() {
return (
@@ -70,5 +68,5 @@ export default function NotFound() {
>
- );
+ )
}
diff --git a/Frontend/app/page.tsx b/Frontend/app/page.jsx
similarity index 73%
rename from Frontend/app/page.tsx
rename to Frontend/app/page.jsx
index 04b3ea2..757dbf3 100644
--- a/Frontend/app/page.tsx
+++ b/Frontend/app/page.jsx
@@ -1,22 +1,20 @@
-import "aos/dist/aos.css";
-import React from "react";
-import { SquaredBackgroundHero } from "@/sections/Hero";
-import PageWrapper from "@/components/Utilities/PageWrapper";
-import Footer from "@/components/Footer";
-import PageHeader from "@/sections/PageHeader";
-import ContainerImageIconBlocksFeature from "@/sections/Features/ContainerImageIconBlocksFeature";
-import Background from "@/components/Utilities/Background";
-import CardTestemonial from "@/sections/Testemonial/CardTestemonial";
-import Payment from "@/sections/Payment";
-import CardsFeature from "@/sections/Features/CardsFeature";
-import FAQ from "@/sections/FAQ/RightAlignedBorderBottomFAQ";
-import VerticalTabsFeature from "@/sections/Features/VerticalTabsFeature";
+import "aos/dist/aos.css"
+import React from "react"
+import { SquaredBackgroundHero } from "@/sections/Hero"
+import PageWrapper from "@/components/Utilities/PageWrapper"
+import Footer from "@/components/Footer"
+import PageHeader from "@/sections/PageHeader"
+import ContainerImageIconBlocksFeature from "@/sections/Features/ContainerImageIconBlocksFeature"
+import Background from "@/components/Utilities/Background"
+import CardTestemonial from "@/sections/Testemonial/CardTestemonial"
+import Payment from "@/sections/Payment"
+import CardsFeature from "@/sections/Features/CardsFeature"
+import FAQ from "@/sections/FAQ/RightAlignedBorderBottomFAQ"
+import VerticalTabsFeature from "@/sections/Features/VerticalTabsFeature"
-import { Metadata } from "next";
-import Head from "next/head";
-import Teste from "@/sections/Testing/Teste";
+import Teste from "@/sections/Testing/Teste"
-export const metadata: Metadata = {
+export const metadata = {
title: "Pocketbase, Stripe, Next.js, Boilerplate | FastPocket",
description:
"FastPocket - Is a boilerplate codebase for everyone to build a product quickly.",
@@ -26,7 +24,7 @@ export const metadata: Metadata = {
"next.js",
"boilerplate",
"template",
- "codebase",
+ "codebase"
],
openGraph: {
url: "https://fastpocket.dev",
@@ -39,9 +37,9 @@ export const metadata: Metadata = {
url: "https://fastpocket.dev/images/home/thumbnail.png",
width: 1200,
height: 630,
- alt: "fastpocket.degv",
- },
- ],
+ alt: "fastpocket.degv"
+ }
+ ]
},
twitter: {
card: "summary_large_image",
@@ -55,14 +53,14 @@ export const metadata: Metadata = {
url: "https://fastpocket.dev/images/home/thumbnail.png",
width: 1200,
height: 630,
- alt: "fastpocket.degv",
- },
- ],
+ alt: "fastpocket.degv"
+ }
+ ]
},
alternates: {
- canonical: "https://fastpocket.dev",
- },
-};
+ canonical: "https://fastpocket.dev"
+ }
+}
export default function Home() {
return (
@@ -70,8 +68,7 @@ export default function Home() {
-
-
+
@@ -105,5 +102,5 @@ export default function Home() {
>
- );
+ )
}
diff --git a/Frontend/app/sitemap.js b/Frontend/app/sitemap.js
new file mode 100644
index 0000000..bbc815d
--- /dev/null
+++ b/Frontend/app/sitemap.js
@@ -0,0 +1,51 @@
+import getPostMetadata from "@/utils/getPostMetaData"
+
+export default async function sitemap() {
+ const defaultPages = [
+ {
+ url: "https://fastpocket.dev",
+ lastModified: new Date(),
+ changeFrequency: "daily",
+ priority: 1
+ },
+ {
+ url: "https://fastpocket.dev/about",
+ lastModified: new Date(),
+ changeFrequency: "monthly",
+ priority: 0.9
+ },
+ {
+ url: "https://fastpocket.dev/pricing",
+ lastModified: new Date(),
+ changeFrequency: "monthly",
+ priority: 0.9
+ },
+ {
+ url: "https://fastpocket.dev/blogs",
+ lastModified: new Date(),
+ changeFrequency: "monthly",
+ priority: 0.9
+ },
+ {
+ url: "https://fastpocket.dev/whatsnew",
+ lastModified: new Date(),
+ changeFrequency: "monthly",
+ priority: 0.9
+ }
+ // other pages
+ ]
+
+ const postSlugs = await getPostMetadata()
+
+ const sitemap = [
+ ...defaultPages,
+ ...postSlugs.map(e => ({
+ url: `https://fastpocket.dev/blogs/${e.slug}`,
+ lastModified: e.modified,
+ changeFrequency: "daily",
+ priority: 0.8
+ }))
+ ]
+
+ return sitemap
+}
diff --git a/Frontend/app/sitemap.ts b/Frontend/app/sitemap.ts
deleted file mode 100644
index dcdd1b7..0000000
--- a/Frontend/app/sitemap.ts
+++ /dev/null
@@ -1,52 +0,0 @@
- import getPostMetadata from "@/utils/getPostMetaData";
-import { MetadataRoute } from "next";
-
- export default async function sitemap(): Promise {
- const defaultPages = [
- {
- url: "https://fastpocket.dev",
- lastModified: new Date(),
- changeFrequency: "daily",
- priority: 1
- },
- {
- url: "https://fastpocket.dev/about",
- lastModified: new Date(),
- changeFrequency: "monthly",
- priority: 0.9
- },
- {
- url: "https://fastpocket.dev/pricing",
- lastModified: new Date(),
- changeFrequency: "monthly",
- priority: 0.9
- },
- {
- url: "https://fastpocket.dev/blogs",
- lastModified: new Date(),
- changeFrequency: "monthly",
- priority: 0.9
- },
- {
- url: "https://fastpocket.dev/whatsnew",
- lastModified: new Date(),
- changeFrequency: "monthly",
- priority: 0.9
- }
- // other pages
- ];
-
- const postSlugs = await getPostMetadata();
-
- const sitemap = [
- ...defaultPages,
- ...postSlugs.map((e: any) => ({
- url: `https://fastpocket.dev/blogs/${e.slug}`,
- lastModified: e.modified,
- changeFrequency: "daily",
- priority: 0.8
- } as any))
- ];
-
- return sitemap;
- }
\ No newline at end of file
diff --git a/Frontend/components/BlogCard.tsx b/Frontend/components/BlogCard.jsx
similarity index 70%
rename from Frontend/components/BlogCard.tsx
rename to Frontend/components/BlogCard.jsx
index 877e0c0..99400a4 100644
--- a/Frontend/components/BlogCard.tsx
+++ b/Frontend/components/BlogCard.jsx
@@ -1,20 +1,9 @@
-import React from "react";
+import React from "react"
-import { PostMetadata } from "@/types";
-import Image from "next/image";
-import Link from "next/link";
+import Image from "next/image"
+import Link from "next/link"
-function BlogCard({
- title,
- slug,
- subtitle,
- imageUrl,
-}: {
- title: string;
- slug: string;
- subtitle: string;
- imageUrl: string;
-}) {
+function BlogCard({ title, slug, subtitle, imageUrl }) {
return (
<>
>
- );
+ )
}
-export default BlogCard;
+export default BlogCard
diff --git a/Frontend/components/FastPocketBadge.tsx b/Frontend/components/FastPocketBadge.jsx
similarity index 99%
rename from Frontend/components/FastPocketBadge.tsx
rename to Frontend/components/FastPocketBadge.jsx
index ee462e0..3583a5f 100644
--- a/Frontend/components/FastPocketBadge.tsx
+++ b/Frontend/components/FastPocketBadge.jsx
@@ -1,5 +1,5 @@
-import * as React from "react";
-const SvgComponent = (props: any) => (
+import * as React from "react"
+const SvgComponent = props => (
(
/>
-);
-export default SvgComponent;
+)
+export default SvgComponent
diff --git a/Frontend/components/Footer.tsx b/Frontend/components/Footer.jsx
similarity index 98%
rename from Frontend/components/Footer.tsx
rename to Frontend/components/Footer.jsx
index 182f52e..e048c01 100644
--- a/Frontend/components/Footer.tsx
+++ b/Frontend/components/Footer.jsx
@@ -1,7 +1,7 @@
-import React from "react";
-import { title } from "@/constants";
-import Logo from "@/components/Logo";
-import Link from "next/link";
+import React from "react"
+import { title } from "@/constants"
+import Logo from "@/components/Logo"
+import Link from "next/link"
import FastPocketBadge from "@/components/FastPocketBadge"
function Footer() {
@@ -253,7 +253,7 @@ function Footer() {
- );
+ )
}
-export default Footer;
+export default Footer
diff --git a/Frontend/components/GetStartedSectionButton.tsx b/Frontend/components/GetStartedSectionButton.jsx
similarity index 71%
rename from Frontend/components/GetStartedSectionButton.tsx
rename to Frontend/components/GetStartedSectionButton.jsx
index f4424fc..ce74e2d 100644
--- a/Frontend/components/GetStartedSectionButton.tsx
+++ b/Frontend/components/GetStartedSectionButton.jsx
@@ -1,18 +1,13 @@
"use client";
import React, { useEffect, useState } from "react";
-import { Subscription, User } from "@/types";
import { getSubscriptions } from "@/app/actions";
import { useRouter } from "next/navigation";
-interface GetStartedSectionButtonProps {
- user: User;
-}
-export const GetStartedSectionButton = ({
- user,
-}: GetStartedSectionButtonProps) => {
+export const GetStartedSectionButton = ({ user }) => {
const router = useRouter();
- const [subscription, setSubscription] = useState();
+ const [subscription, setSubscription] = useState();
+
useEffect(() => {
(async () => {
if (!user) {
@@ -37,4 +32,4 @@ export const GetStartedSectionButton = ({
);
};
-export default GetStartedSectionButton;
+export default GetStartedSectionButton;
\ No newline at end of file
diff --git a/Frontend/components/GoogleAnalytics.tsx b/Frontend/components/GoogleAnalytics.jsx
similarity index 78%
rename from Frontend/components/GoogleAnalytics.tsx
rename to Frontend/components/GoogleAnalytics.jsx
index 774308f..d3e79d0 100644
--- a/Frontend/components/GoogleAnalytics.tsx
+++ b/Frontend/components/GoogleAnalytics.jsx
@@ -1,6 +1,6 @@
-import Script from "next/script";
+import Script from "next/script"
-const GoogleAnalytics = ({ ga_id }: { ga_id: string }) => (
+const GoogleAnalytics = ({ ga_id }) => (
<>
>
-);
-export default GoogleAnalytics;
+)
+export default GoogleAnalytics
diff --git a/Frontend/components/Header.jsx b/Frontend/components/Header.jsx
new file mode 100644
index 0000000..d3e79d0
--- /dev/null
+++ b/Frontend/components/Header.jsx
@@ -0,0 +1,28 @@
+import Script from "next/script"
+
+const GoogleAnalytics = ({ ga_id }) => (
+ <>
+
+
+ >
+)
+export default GoogleAnalytics
diff --git a/Frontend/components/Header.tsx b/Frontend/components/Header.tsx
deleted file mode 100644
index 9bfa374..0000000
--- a/Frontend/components/Header.tsx
+++ /dev/null
@@ -1,162 +0,0 @@
-"use client";
-
-import React, { useEffect, useState, useRef } from "react";
-import Navigation from "@/components/Navigation";
-import ModalSignUp from "@/components/Modals/ModalSignUp";
-import ModalSignIn from "@/components/Modals/ModalSignIn";
-import { getAuthCookie, getUser, logout } from "@/app/actions";
-import { User } from "@/types";
-import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
-import pb from "@/lib/pocketbase";
-import { useTheme } from "next-themes";
-import Link from "next/link";
-import ModalPasswordReset from "./Modals/ModalPasswordReset";
-import {Person24Filled, SignOut24Filled} from '@fluentui/react-icons'
-import ModalEmailChange from "./Modals/ModalEmailChange";
-import { usePathname } from "next/navigation";
-
-interface HeaderProps {
- isUserLoggedIn: boolean;
- authString: string;
-}
-
-export default function Header({ isUserLoggedIn, authString }: HeaderProps) {
- //Advice: Remove this and replace it with proper state management like Redux, Recoil or Zustand
- const [user, setUser] = useState();
- const [statefulUser, setStatefulUser] = useState();
- const pathName = usePathname();
- useEffect(() => {
- (async () => {
- const user = await getUser();
- setUser(user as User);
- })();
- }, [statefulUser]);
-
-
- const { theme, setTheme } = useTheme();
- return (
-
-
-
-
-
- {/* Desktop navigation */}
-
- {/* Desktop sign in links */}
-
- {/*
setTheme("dark")}
- >
- dark
-
-
setTheme("light")}
- >
- light
- */}
-
- {/* this hidden checkbox controls the state */}
-
- theme === "light" ? setTheme("dark") : setTheme("light")
- }
- />
-
- {/* sun icon */}
-
-
-
-
- {/* moon icon */}
-
-
-
-
-
- {!isUserLoggedIn ? (
- <>
-
- (async (router?: AppRouterInstance) => {
- console.log("firing");
- const authCookie = await getAuthCookie();
- pb.authStore.loadFromCookie(authCookie || "");
- if (!authCookie || !pb.authStore.isValid) {
- document.getElementById("sign-in-modal")?.click();
- } else {
- router?.push("/account");
- }
- })()
- }
- className={`btn btn-sm btn-ghost text-primary mr-1`}
- >
- Sign In
-
-
{
- localStorage.getItem("price") &&
- localStorage.removeItem("price");
- document.getElementById("sign-up-modal")?.click();
- }}
- className={`btn btn-primary btn-sm text-primary-content `}
- id="sign-up-modal-button"
- >
- Get First Access
-
- >
- ) : (
-
-
-
-
-
-
-
- {user?.displayName}
-
-
-
- logout()}>
-
-
- Logout
-
-
-
-
- )}
-
-
-
-
-
-
-
-
-
- );
-}
diff --git a/Frontend/components/Logo.tsx b/Frontend/components/Logo.jsx
similarity index 64%
rename from Frontend/components/Logo.tsx
rename to Frontend/components/Logo.jsx
index 07277f5..ba5f3bf 100644
--- a/Frontend/components/Logo.tsx
+++ b/Frontend/components/Logo.jsx
@@ -1,14 +1,8 @@
-import React from "react";
+import React from "react"
-import Image, { ImageProps } from "next/image";
+import Image from "next/image"
-interface LogoProps {
- label?: string;
- className?: string;
- imageProps?: ImageProps;
-}
-
-function Logo({ imageProps, ...props }: LogoProps) {
+function Logo({ imageProps, ...props }) {
return (
- );
+ )
}
-export default Logo;
+export default Logo
diff --git a/Frontend/components/Modals/ModalEmailChange.tsx b/Frontend/components/Modals/ModalEmailChange.jsx
similarity index 72%
rename from Frontend/components/Modals/ModalEmailChange.tsx
rename to Frontend/components/Modals/ModalEmailChange.jsx
index 81c10d9..3335056 100644
--- a/Frontend/components/Modals/ModalEmailChange.tsx
+++ b/Frontend/components/Modals/ModalEmailChange.jsx
@@ -1,31 +1,31 @@
-import React, { useRef } from "react";
-import { useForm } from "react-hook-form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { emailValidationSchema } from "@/utils/form";
-import { toast } from "react-toastify";
-import pb from "@/lib/pocketbase";
-import {Dismiss20Filled} from "@fluentui/react-icons"
-import { redirect } from "next/navigation";
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { emailValidationSchema } from "@/utils/form"
+import { toast } from "react-toastify"
+import pb from "@/lib/pocketbase"
+import { Dismiss20Filled } from "@fluentui/react-icons"
+import { redirect } from "next/navigation"
-function ModalEmailChange({authString}:{authString:string}) {
+function ModalEmailChange({ authString }) {
const {
register,
handleSubmit,
reset,
- formState: { errors, isSubmitting },
+ formState: { errors, isSubmitting }
} = useForm({
- resolver: yupResolver(emailValidationSchema),
- });
+ resolver: yupResolver(emailValidationSchema)
+ })
- const onSubmit = async (data: any) => {
- console.log(data);
- pb.authStore.loadFromCookie(authString);
- !pb.authStore.isValid && redirect("/");
+ const onSubmit = async data => {
+ console.log(data)
+ pb.authStore.loadFromCookie(authString)
+ !pb.authStore.isValid && redirect("/")
try {
if (await pb.collection("user").requestEmailChange(data.email)) {
- reset();
- document.getElementById("email-change-modal")?.click();
- document.getElementById("sign-in-modal")?.click();
+ reset()
+ document.getElementById("email-change-modal")?.click()
+ document.getElementById("sign-in-modal")?.click()
}
} catch (error) {
if (error instanceof Error) {
@@ -37,11 +37,11 @@ function ModalEmailChange({authString}:{authString:string}) {
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
+ }
return (
<>
{
- reset();
+ reset()
}}
/>
@@ -88,7 +88,7 @@ function ModalEmailChange({authString}:{authString:string}) {
Change Email
{isSubmitting &&
}
@@ -99,7 +99,7 @@ function ModalEmailChange({authString}:{authString:string}) {
>
- );
+ )
}
-export default ModalEmailChange;
+export default ModalEmailChange
diff --git a/Frontend/components/Modals/ModalPasswordReset.tsx b/Frontend/components/Modals/ModalPasswordReset.jsx
similarity index 79%
rename from Frontend/components/Modals/ModalPasswordReset.tsx
rename to Frontend/components/Modals/ModalPasswordReset.jsx
index ef7921d..ffc1bd9 100644
--- a/Frontend/components/Modals/ModalPasswordReset.tsx
+++ b/Frontend/components/Modals/ModalPasswordReset.jsx
@@ -1,30 +1,29 @@
-import React, { useRef } from "react";
-import { useForm } from "react-hook-form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { emailValidationSchema } from "@/utils/form";
-import { toast } from "react-toastify";
-import pb from "@/lib/pocketbase";
-import {Dismiss20Filled} from '@fluentui/react-icons'
-import { redirect } from "next/navigation";
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { emailValidationSchema } from "@/utils/form"
+import { toast } from "react-toastify"
+import pb from "@/lib/pocketbase"
+import { Dismiss20Filled } from "@fluentui/react-icons"
function ModalPasswordReset() {
const {
register,
handleSubmit,
reset,
- formState: { errors, isSubmitting },
+ formState: { errors, isSubmitting }
} = useForm({
- resolver: yupResolver(emailValidationSchema),
- });
+ resolver: yupResolver(emailValidationSchema)
+ })
- const onSubmit = async (data: any) => {
- console.log(data);
+ const onSubmit = async data => {
+ console.log(data)
try {
//login user
if (await pb.collection("user").requestPasswordReset(data.email)) {
- reset();
- document.getElementById("password-reset-modal")?.click();
- document.getElementById("sign-in-modal")?.click();
+ reset()
+ document.getElementById("password-reset-modal")?.click()
+ document.getElementById("sign-in-modal")?.click()
}
} catch (error) {
if (error instanceof Error) {
@@ -36,11 +35,11 @@ function ModalPasswordReset() {
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
+ }
return (
<>
{
- reset();
+ reset()
}}
/>
@@ -98,7 +97,7 @@ function ModalPasswordReset() {
>
- );
+ )
}
-export default ModalPasswordReset;
+export default ModalPasswordReset
diff --git a/Frontend/components/Modals/ModalSignIn.tsx b/Frontend/components/Modals/ModalSign.jsx
similarity index 82%
rename from Frontend/components/Modals/ModalSignIn.tsx
rename to Frontend/components/Modals/ModalSign.jsx
index 2b4a112..f2c808c 100644
--- a/Frontend/components/Modals/ModalSignIn.tsx
+++ b/Frontend/components/Modals/ModalSign.jsx
@@ -1,36 +1,34 @@
-"use client";
+"use client"
-import React from "react";
-import { useForm } from "react-hook-form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { signInValidationSchema } from "@/utils/form";
-import { login } from "@/app/actions";
-import { toast } from "react-toastify";
-import { useRouter } from "next/navigation";
-import {Dismiss20Filled} from '@fluentui/react-icons'
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { signInValidationSchema } from "@/utils/form"
+import { login } from "@/app/actions"
+import { toast } from "react-toastify"
+import { useRouter } from "next/navigation"
+import { Dismiss20Filled } from "@fluentui/react-icons"
function ModalSignIn() {
- const router = useRouter();
+ const router = useRouter()
const {
register,
handleSubmit,
reset,
- formState: { errors, isSubmitting },
+ formState: { errors, isSubmitting }
} = useForm({
- resolver: yupResolver(signInValidationSchema),
- });
+ resolver: yupResolver(signInValidationSchema)
+ })
- const onSubmit = async (data: any) => {
+ const onSubmit = async data => {
try {
//login user
- const auth = (await login({ email: data.email, password: data.password }))
- if (
- auth.success
- ) {
- reset();
- document.getElementById("sign-in-modal")?.click();
- router.push("/account");
+ const auth = await login({ email: data.email, password: data.password })
+ if (auth.success) {
+ reset()
+ document.getElementById("sign-in-modal")?.click()
+ router.push("/account")
} else {
throw new Error(auth.response.message)
}
@@ -44,11 +42,11 @@ function ModalSignIn() {
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
+ }
return (
<>
{
- reset();
+ reset()
}}
/>
@@ -120,8 +118,8 @@ function ModalSignIn() {
{
- document.getElementById("sign-in-modal")?.click();
- document.getElementById("sign-up-modal")?.click();
+ document.getElementById("sign-in-modal")?.click()
+ document.getElementById("sign-up-modal")?.click()
}}
className="text-primary hover:text-primary/60 cursor-pointer "
>
@@ -143,7 +141,7 @@ function ModalSignIn() {
>
- );
+ )
}
-export default ModalSignIn;
+export default ModalSignIn
diff --git a/Frontend/components/Modals/ModalSignUp.tsx b/Frontend/components/Modals/ModalSignUp.jsx
similarity index 83%
rename from Frontend/components/Modals/ModalSignUp.tsx
rename to Frontend/components/Modals/ModalSignUp.jsx
index 39c960e..c0b83fa 100644
--- a/Frontend/components/Modals/ModalSignUp.tsx
+++ b/Frontend/components/Modals/ModalSignUp.jsx
@@ -1,39 +1,33 @@
-"use client";
+"use client"
+import React from "react"
+import { useForm } from "react-hook-form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import { signUpValidationSchema } from "@/utils/form"
+import { companySizeList } from "@/constants"
+import pb from "@/lib/pocketbase"
+import { createCheckoutSession, login } from "@/app/actions"
+import { toast } from "react-toastify"
+import { useRouter } from "next/navigation"
+import { Dismiss20Filled } from "@fluentui/react-icons"
-import React, { Dispatch, SetStateAction } from "react";
-import { useForm } from "react-hook-form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import { signUpValidationSchema } from "@/utils/form";
-import { companySizeList } from "@/constants";
-import pb from "@/lib/pocketbase";
-import { createCheckoutSession, login } from "@/app/actions";
-import { toast } from "react-toastify";
-import { Price, User } from "@/types";
-import { useRouter } from "next/navigation";
-import {Dismiss20Filled} from '@fluentui/react-icons'
-
-function ModalSignUp({
- setUser,
-}: {
- setUser: Dispatch>;
-}) {
+function ModalSignUp({ setUser }) {
const {
register,
handleSubmit,
reset,
- formState: { errors, isSubmitting },
+ formState: { errors, isSubmitting }
} = useForm({
- resolver: yupResolver(signUpValidationSchema),
- });
- const router = useRouter();
- const generateCheckoutPage = async (price: Price, type: string) => {
+ resolver: yupResolver(signUpValidationSchema)
+ })
+ const router = useRouter()
+ const generateCheckoutPage = async (price, type) => {
try {
const checkoutSessionResponse = await createCheckoutSession(
price.price_id,
type
- );
- console.log(checkoutSessionResponse);
- router.push(checkoutSessionResponse.url);
+ )
+ console.log(checkoutSessionResponse)
+ router.push(checkoutSessionResponse.url)
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
@@ -44,53 +38,51 @@ function ModalSignUp({
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
- const onSubmit = async (data: any) => {
+ }
+ const onSubmit = async data => {
data = {
emailVisibility: false,
lastSeen: new Date(),
role: "Admin",
displayName: `${data.firstName} ${data.lastName}`,
passwordConfirm: data.password,
- ...data,
- };
+ ...data
+ }
try {
//create organisation
const organisation = await pb.collection("organisation").create({
name: data.organisation,
- organisationSize: data.organisationSize,
- });
+ organisationSize: data.organisationSize
+ })
//create user
const user = await pb
.collection("user")
- .create({ ...data, organisation: organisation.id });
+ .create({ ...data, organisation: organisation.id })
//login user
- const auth = (await login({ email: data.email, password: data.password }))
- if (
- auth.success
- ) {
- reset();
- document.getElementById("sign-up-modal")?.click();
- const price = localStorage.getItem("price");
- const type = localStorage.getItem("type");
- setUser(user as User);
- console.log("price", price);
- console.log("type", type);
+ const auth = await login({ email: data.email, password: data.password })
+ if (auth.success) {
+ reset()
+ document.getElementById("sign-up-modal")?.click()
+ const price = localStorage.getItem("price")
+ const type = localStorage.getItem("type")
+ setUser(user)
+ console.log("price", price)
+ console.log("type", type)
price
? generateCheckoutPage(JSON.parse(price), type ?? "")
- : router.push("/account");
+ : router.push("/account")
} else {
throw new Error(auth.response.message)
}
} catch (error) {
if (error instanceof Error) {
toast.error(
- Object.values((error as any).data.data)
- .map((x: any) => x.message)
+ Object.values(error.data.data)
+ .map(x => x.message)
.join(),
{
position: "bottom-left",
@@ -100,12 +92,12 @@ function ModalSignUp({
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
+ theme: "colored"
}
- );
+ )
}
}
- };
+ }
return (
<>
{
- reset();
+ reset()
}}
/>
@@ -124,7 +116,7 @@ function ModalSignUp({
htmlFor="sign-up-modal"
className="cursor-pointer text-base-content"
onClick={() => {
- reset();
+ reset()
}}
>
@@ -225,7 +217,7 @@ function ModalSignUp({
>
{companySizeOption}
- );
+ )
})}
@@ -265,8 +257,8 @@ function ModalSignUp({
{
- document.getElementById("sign-up-modal")?.click();
- document.getElementById("sign-in-modal")?.click();
+ document.getElementById("sign-up-modal")?.click()
+ document.getElementById("sign-in-modal")?.click()
}}
className="text-primary hover:text-primary/60 cursor-pointer "
>
@@ -279,7 +271,7 @@ function ModalSignUp({
>
- );
+ )
}
-export default ModalSignUp;
+export default ModalSignUp
diff --git a/Frontend/components/Navigation.tsx b/Frontend/components/Navigation.jsx
similarity index 84%
rename from Frontend/components/Navigation.tsx
rename to Frontend/components/Navigation.jsx
index 13cca7d..fa6cd44 100644
--- a/Frontend/components/Navigation.tsx
+++ b/Frontend/components/Navigation.jsx
@@ -1,15 +1,15 @@
-"use client";
+"use client"
-import Logo from "@/components/Logo";
-import React, { useState } from "react";
-import Link from "next/link";
-import {Navigation24Filled} from "@fluentui/react-icons"
+import Logo from "@/components/Logo"
+import React, { useState } from "react"
+import Link from "next/link"
+import { Navigation24Filled } from "@fluentui/react-icons"
-function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) {
- const [checked, setChecked] = useState();
+function Navigation({ isUserLoggedIn }) {
+ const [checked, setChecked] = useState()
const handleClick = () => {
- checked ? setChecked(!checked) : setChecked(checked);
- };
+ checked ? setChecked(!checked) : setChecked(checked)
+ }
return (
- );
+ )
}
-export default Navigation;
+export default Navigation
diff --git a/Frontend/components/PriceCard.tsx b/Frontend/components/PriceCard.jsx
similarity index 72%
rename from Frontend/components/PriceCard.tsx
rename to Frontend/components/PriceCard.jsx
index 592a4c3..9d10c41 100644
--- a/Frontend/components/PriceCard.tsx
+++ b/Frontend/components/PriceCard.jsx
@@ -1,34 +1,24 @@
-"use client";
+"use client"
+import { createCheckoutSession, isAuthenticated } from "@/app/actions"
+import { toast } from "react-toastify"
+import { useRouter } from "next/navigation"
+import { CheckmarkCircle24Filled } from "@fluentui/react-icons"
-import { Price, Product, SourceModal } from "@/types";
-import { createCheckoutSession, isAuthenticated } from "@/app/actions";
-import { toast } from "react-toastify";
-import { useRouter } from "next/navigation";
-import {CheckmarkCircle24Filled } from "@fluentui/react-icons"
-
-export default function PriceCard({
- product,
- isAnnual,
- loading,
-}: {
- product?: Product;
- isAnnual?: boolean;
- loading?: boolean;
-}) {
- const router = useRouter();
- const openSignUpModalOnPriceClick = (price: Price, type: string) => {
- const signUpModal = document.getElementById("sign-up-modal");
- if (!signUpModal) return;
- signUpModal.click();
- };
- const generateCheckoutPage = async (price: Price, type: string) => {
+export default function PriceCard({ product, isAnnual, loading }) {
+ const router = useRouter()
+ const openSignUpModalOnPriceClick = (price, type) => {
+ const signUpModal = document.getElementById("sign-up-modal")
+ if (!signUpModal) return
+ signUpModal.click()
+ }
+ const generateCheckoutPage = async (price, type) => {
try {
const checkoutSessionResponse = await createCheckoutSession(
price.price_id,
type
- );
- console.log(checkoutSessionResponse);
- router.push(checkoutSessionResponse.url);
+ )
+ console.log(checkoutSessionResponse)
+ router.push(checkoutSessionResponse.url)
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
@@ -39,25 +29,25 @@ export default function PriceCard({
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
- const submitForm = async (product: Product) => {
- const userIsAuthenticated = await isAuthenticated();
- console.log("userIsAuthenticated", userIsAuthenticated);
- const price = isAnnual ? product.yearlyPrice : product.monthlyPrice;
- console.log("price", price);
- console.log("product.type", product.type);
- localStorage.setItem("price", JSON.stringify(price));
- localStorage.setItem("type", product.type);
+ }
+ const submitForm = async product => {
+ const userIsAuthenticated = await isAuthenticated()
+ console.log("userIsAuthenticated", userIsAuthenticated)
+ const price = isAnnual ? product.yearlyPrice : product.monthlyPrice
+ console.log("price", price)
+ console.log("product.type", product.type)
+ localStorage.setItem("price", JSON.stringify(price))
+ localStorage.setItem("type", product.type)
if (userIsAuthenticated) {
- await generateCheckoutPage(price, product.type);
+ await generateCheckoutPage(price, product.type)
} else {
- openSignUpModalOnPriceClick(price, product.type);
+ openSignUpModalOnPriceClick(price, product.type)
}
- };
+ }
return (
- );
+ )
}
diff --git a/Frontend/components/PriceToggle.jsx b/Frontend/components/PriceToggle.jsx
new file mode 100644
index 0000000..71c2c8d
--- /dev/null
+++ b/Frontend/components/PriceToggle.jsx
@@ -0,0 +1,29 @@
+export default function PriceToggle({ isAnnual, onChange }) {
+ return (
+ <>
+
+
+
+ Monthly Billing
+
+
+ Yearly Billing
+
+
+ >
+ )
+ }
+
\ No newline at end of file
diff --git a/Frontend/components/PriceToggle.tsx b/Frontend/components/PriceToggle.tsx
deleted file mode 100644
index 10ec11d..0000000
--- a/Frontend/components/PriceToggle.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import { ChangeEventHandler } from "react";
-
-export default function PriceToggle({
- isAnnual,
- onChange,
-}: {
- isAnnual: boolean;
- onChange?: ChangeEventHandler;
-}) {
- return (
- <>
-
-
-
- Monthly Billing
-
-
- Yearly Billing
-
-
- >
- );
-}
diff --git a/Frontend/components/Utilities/Background.jsx b/Frontend/components/Utilities/Background.jsx
new file mode 100644
index 0000000..dbc4ec8
--- /dev/null
+++ b/Frontend/components/Utilities/Background.jsx
@@ -0,0 +1,34 @@
+"use client"
+
+import { useTheme } from "next-themes"
+import React from "react"
+import Image from "next/image"
+
+const Background = ({ children, className }) => {
+ const { theme } = useTheme()
+
+ return (
+
+ )
+}
+
+export default Background
diff --git a/Frontend/components/Utilities/Background.tsx b/Frontend/components/Utilities/Background.tsx
deleted file mode 100644
index 0dbafee..0000000
--- a/Frontend/components/Utilities/Background.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-"use client";
-
-import { useTheme } from "next-themes";
-import React, { ReactNode } from "react";
-import Image from "next/image";
-
-const Background = ({
- children,
- className,
-}: {
- children: ReactNode;
- className?: string;
-}) => {
- const { theme } = useTheme();
-
- return (
-
- );
-};
-
-export default Background;
\ No newline at end of file
diff --git a/Frontend/components/Utilities/PageWrapper.jsx b/Frontend/components/Utilities/PageWrapper.jsx
new file mode 100644
index 0000000..f865408
--- /dev/null
+++ b/Frontend/components/Utilities/PageWrapper.jsx
@@ -0,0 +1,11 @@
+import React from "react"
+
+function PageWrapper({ children }) {
+ return (
+
+ {children}
+
+ )
+}
+
+export default PageWrapper
diff --git a/Frontend/components/Utilities/PageWrapper.tsx b/Frontend/components/Utilities/PageWrapper.tsx
deleted file mode 100644
index 168216b..0000000
--- a/Frontend/components/Utilities/PageWrapper.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import { WaitingListWithImageHero } from "@/sections/Hero";
-import React from "react";
-
-function PageWrapper({ children }: { children: React.ReactNode }) {
- return (
-
- {children}
-
- );
-}
-
-export default PageWrapper;
diff --git a/Frontend/components/Utilities/Spacer.jsx b/Frontend/components/Utilities/Spacer.jsx
new file mode 100644
index 0000000..e37acbb
--- /dev/null
+++ b/Frontend/components/Utilities/Spacer.jsx
@@ -0,0 +1,7 @@
+import React from "react"
+
+const Spacer = props => {
+ return
+}
+
+export default Spacer
diff --git a/Frontend/components/Utilities/Spacer.tsx b/Frontend/components/Utilities/Spacer.tsx
deleted file mode 100644
index 36fbb16..0000000
--- a/Frontend/components/Utilities/Spacer.tsx
+++ /dev/null
@@ -1,12 +0,0 @@
-import React, { ReactHTMLElement } from "react";
-
-const Spacer = (
- props: React.DetailedHTMLProps<
- React.HTMLAttributes,
- HTMLDivElement
- >
-) => {
- return
;
-};
-
-export default Spacer;
diff --git a/Frontend/components/Utilities/YoutubeEmbed.tsx b/Frontend/components/Utilities/YoutubeEmbed.jsx
similarity index 57%
rename from Frontend/components/Utilities/YoutubeEmbed.tsx
rename to Frontend/components/Utilities/YoutubeEmbed.jsx
index 35f61f1..0defd64 100644
--- a/Frontend/components/Utilities/YoutubeEmbed.tsx
+++ b/Frontend/components/Utilities/YoutubeEmbed.jsx
@@ -1,20 +1,14 @@
-import React, { useState } from "react";
+import React from "react"
-import { MediaPlayer, MediaProvider } from "@vidstack/react";
+import { MediaPlayer, MediaProvider } from "@vidstack/react"
import {
DefaultAudioLayout,
defaultLayoutIcons,
- DefaultVideoLayout,
-} from "@vidstack/react/player/layouts/default";
-import "@vidstack/react/player/styles/base.css";
-export type Props = {
- videotitle: string;
- video: string;
- width: number;
- height: number;
-};
+ DefaultVideoLayout
+} from "@vidstack/react/player/layouts/default"
+import "@vidstack/react/player/styles/base.css"
-export default function YouTubeFrame({ video, width, height }: Props) {
+export default function YouTubeFrame({ video, width, height }) {
return (
- );
+ )
}
diff --git a/Frontend/constants/index.ts b/Frontend/constants/index.js
similarity index 76%
rename from Frontend/constants/index.ts
rename to Frontend/constants/index.js
index 54fc3b1..7c16243 100644
--- a/Frontend/constants/index.ts
+++ b/Frontend/constants/index.js
@@ -4,6 +4,7 @@ export const companySizeList = [
"30-70 employees",
"70-100 employees",
"100+ employees"
-]
-
-export const title = "FastPocket"
\ No newline at end of file
+ ]
+
+ export const title = "FastPocket"
+
\ No newline at end of file
diff --git a/Frontend/lib/auth.js b/Frontend/lib/auth.js
new file mode 100644
index 0000000..02b809a
--- /dev/null
+++ b/Frontend/lib/auth.js
@@ -0,0 +1,20 @@
+import pb from "@/lib/pocketbase"
+import { redirect } from "next/navigation"
+
+export const getUserFromCookie = async cookies => {
+ const cookie = cookies.get("pb_auth")
+ if (!cookie) {
+ redirect("/")
+ //throw new Error("No authenticated user");
+ } else {
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ return pb.authStore.model
+ }
+}
+
+export const isAuthenticated = async cookieStore => {
+ const cookie = cookieStore.get("pb_auth")
+ if (!cookie) return false
+ pb.authStore.loadFromCookie(cookie?.value || "")
+ return pb.authStore.isValid || false
+}
diff --git a/Frontend/lib/auth.ts b/Frontend/lib/auth.ts
deleted file mode 100644
index 1b409be..0000000
--- a/Frontend/lib/auth.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-import { ReadonlyRequestCookies } from "next/dist/server/web/spec-extension/adapters/request-cookies";
-import pb from "@/lib/pocketbase";
-import { redirect } from "next/navigation";
-
-export const getUserFromCookie = async (cookies: ReadonlyRequestCookies) => {
- const cookie = cookies.get('pb_auth');
- if (!cookie) {
- redirect('/');
- //throw new Error("No authenticated user");
- } else {
- pb.authStore.loadFromCookie(cookie?.value || '');
- return pb.authStore.model;
- }
-}
-
-export const isAuthenticated = async (cookieStore: ReadonlyRequestCookies) => {
- const cookie = cookieStore.get('pb_auth');
- if(!cookie) return false;
- pb.authStore.loadFromCookie(cookie?.value || '');
- return pb.authStore.isValid || false;
-}
\ No newline at end of file
diff --git a/Frontend/lib/pocketbase.ts b/Frontend/lib/pocketbase.js
similarity index 100%
rename from Frontend/lib/pocketbase.ts
rename to Frontend/lib/pocketbase.js
diff --git a/Frontend/middleware.js b/Frontend/middleware.js
new file mode 100644
index 0000000..925112c
--- /dev/null
+++ b/Frontend/middleware.js
@@ -0,0 +1,23 @@
+import { NextResponse } from "next/server"
+import { isAuthenticated } from "./lib/auth"
+
+export async function middleware(request) {
+ const { pathname } = request.nextUrl
+ if (
+ pathname.startsWith("/_next") ||
+ pathname.startsWith("/api") ||
+ pathname.startsWith("/static")
+ ) {
+ return NextResponse.next()
+ }
+ const isLoggedIn = await isAuthenticated(request.cookies)
+ if (pathname.startsWith("/account")) {
+ if (isLoggedIn) {
+ return NextResponse.next()
+ } else {
+ request.nextUrl.pathname = "/"
+ }
+ return NextResponse.redirect(request.nextUrl)
+ }
+ return NextResponse.next()
+}
diff --git a/Frontend/middleware.ts b/Frontend/middleware.ts
deleted file mode 100644
index 6b2593e..0000000
--- a/Frontend/middleware.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-import { NextRequest, NextResponse } from "next/server";
-import { isAuthenticated } from "./lib/auth";
-
-export async function middleware(request: NextRequest) {
- const { pathname } = request.nextUrl;
- if (
- pathname.startsWith("/_next") ||
- pathname.startsWith("/api") ||
- pathname.startsWith("/static")
- ) {
- return NextResponse.next();
- }
- const isLoggedIn = await isAuthenticated(request.cookies as any);
- if (pathname.startsWith("/account")) {
- if (isLoggedIn) {
- return NextResponse.next();
- } else {
- request.nextUrl.pathname = "/"
- }
- return NextResponse.redirect(request.nextUrl);
- }
- return NextResponse.next();
-}
diff --git a/Frontend/sections/AccountContent.jsx b/Frontend/sections/AccountContent.jsx
new file mode 100644
index 0000000..006d069
--- /dev/null
+++ b/Frontend/sections/AccountContent.jsx
@@ -0,0 +1,124 @@
+"use client";
+
+import React, { useState, useEffect } from "react";
+import { toast } from "react-toastify";
+import { useRouter } from "next/navigation";
+import { useQRCode } from "next-qrcode";
+import { createManagementSubscriptionSession, getSubscriptions } from "@/app/actions";
+import pb from "@/lib/pocketbase";
+import { Subscription, User } from "@/types";
+
+function AccountContent({ user }) {
+ const router = useRouter();
+ const { Canvas } = useQRCode();
+
+ const [subscription, setSubscription] = useState();
+ const [loading, setLoading] = useState(true);
+
+ useEffect(() => {
+ (async () => {
+ if (!user) {
+ setLoading(false);
+ return;
+ }
+ try {
+ setLoading(true);
+ const subscriptions = await getSubscriptions();
+ if (subscriptions.length > 0) {
+ setSubscription(subscriptions[0]);
+ }
+ setLoading(false);
+ } catch (err) {
+ setLoading(false);
+ }
+ })();
+ }, [user]);
+
+ const manageSubscription = async () => {
+ try {
+ const managementSession = await createManagementSubscriptionSession();
+ router.push(managementSession.url);
+ } 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",
+ });
+ }
+ }
+ };
+
+ return loading ? (
+
+ ) : (
+
+
+
+
+ Your Subscription
+
+ {subscription && subscription.status !== "canceled" ? (
+ <>
+
+ {subscription?.product?.name}
+
+
+ {subscription.product?.description}
+
+
+ Manage Subscription
+
+ >
+ ) : (
+ <>
+
+ {"You haven’t upgraded your workflow yet"}
+
+
+ router.push("/pricing")}
+ className="btn btn-sm btn-neutral text-primary-content capitalize bg-gradient-to-r from-primary to-secondary border-none"
+ >
+ Upgrade
+
+
+ Manage Purchases
+
+
+ document.getElementById("password-reset-modal")?.click()
+ }
+ className="btn btn-sm btn-secondary md:ml-auto text-primary-content capitalize border-none"
+ >
+ Reset Password
+
+
+ document.getElementById("email-change-modal")?.click()
+ }
+ className="btn btn-sm btn-secondary text-primary-content capitalize border-none"
+ >
+ Change Email
+
+
+ >
+ )}
+
+
+
+ );
+}
+
+export default AccountContent;
diff --git a/Frontend/sections/AccountContent.tsx b/Frontend/sections/AccountContent.tsx
deleted file mode 100644
index 2bed9f1..0000000
--- a/Frontend/sections/AccountContent.tsx
+++ /dev/null
@@ -1,199 +0,0 @@
-"use client";
-
-import {
- createManagementSubscriptionSession,
- getSubscriptions,
-} from "@/app/actions";
-import { Subscription, User } from "@/types";
-import React from "react";
-import { useState, useEffect } from "react";
-import { toast } from "react-toastify";
-import { useRouter } from "next/navigation";
-import { useQRCode } from "next-qrcode";
-import pb from "@/lib/pocketbase";
-
-interface ManageSubscriptionProps {
- user: User;
-}
-
-function AccountContent({ user }: ManageSubscriptionProps) {
- const router = useRouter();
- const { Canvas } = useQRCode();
-
- const [subscription, setSubscription] = useState();
- const [loading, setLoading] = useState(true);
- useEffect(() => {
- (async () => {
- if (!user) {
- setLoading(false);
- return;
- }
- try {
- setLoading(true);
- const subscriptions = await getSubscriptions();
- if (subscriptions.length > 0) {
- setSubscription(subscriptions[0]);
- }
- setLoading(false);
- } catch (err) {
- setLoading(false);
- }
- })();
- }, [user]);
- const manageSubscription = async () => {
- try {
- const managementSession = await createManagementSubscriptionSession();
- router.push(managementSession.url);
- } 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",
- });
- }
- }
- };
-
- return loading ? (
-
- ) : (
-
- {/* //TODO: Create Application Component */}
- {/* {subscription ? (
-
- ) : (
- <>>
- )} */}
-
-
-
- Your Subscription
-
- {subscription && subscription.status != "canceled" ? (
- <>
-
- {subscription?.product?.name}
-
-
- {subscription.product?.description}
-
-
- Manage Subscription
-
- >
- ) : (
- <>
-
- {"You haven’t upgraded your workflow yet"}
-
-
- router.push("/pricing")}
- className="btn btn-sm btn-neutral text-primary-content capitalize bg-gradient-to-r from-primary to-secondary border-none"
- >
- Upgrade
-
-
- Manage Purchases
-
-
- document.getElementById("password-reset-modal")?.click()
- }
- className="btn btn-sm btn-secondary md:ml-auto text-primary-content capitalize border-none"
- >
- Reset Password
-
-
- document.getElementById("email-change-modal")?.click()
- }
- className="btn btn-sm btn-secondary text-primary-content capitalize border-none"
- >
- Change Email
-
-
- >
- )}
-
-
-
- );
-}
-
-export default AccountContent;
diff --git a/Frontend/sections/BlogContent.tsx b/Frontend/sections/BlogContent.jsx
similarity index 88%
rename from Frontend/sections/BlogContent.tsx
rename to Frontend/sections/BlogContent.jsx
index 550c5fd..be88bf1 100644
--- a/Frontend/sections/BlogContent.tsx
+++ b/Frontend/sections/BlogContent.jsx
@@ -1,7 +1,7 @@
-import React from "react";
-import Image from "next/image";
+import React from "react"
+import Image from "next/image"
-function BlogContent({ post }: { post: any }) {
+function BlogContent({ post }) {
return (
@@ -30,7 +30,7 @@ function BlogContent({ post }: { post: any }) {
display: "block",
width: "100%",
height: "100%",
- objectFit: "cover",
+ objectFit: "cover"
}}
/>
@@ -40,7 +40,7 @@ function BlogContent({ post }: { post: any }) {
>
- );
+ )
}
-export default BlogContent;
+export default BlogContent
diff --git a/Frontend/sections/ContactUs/FormLeftDescriptionRightContactUs.tsx b/Frontend/sections/ContactUs/FormLeftDescriptionRightContactUs.jsx
similarity index 93%
rename from Frontend/sections/ContactUs/FormLeftDescriptionRightContactUs.tsx
rename to Frontend/sections/ContactUs/FormLeftDescriptionRightContactUs.jsx
index d2abc87..78010c6 100644
--- a/Frontend/sections/ContactUs/FormLeftDescriptionRightContactUs.tsx
+++ b/Frontend/sections/ContactUs/FormLeftDescriptionRightContactUs.jsx
@@ -1,31 +1,25 @@
-"use client";
+"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";
-import { toast } from "react-toastify";
+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"
+import { toast } from "react-toastify"
const FormLeftDescriptionRightContactUs = () => {
const {
register,
handleSubmit,
- formState: { errors },
+ formState: { errors }
} = useForm({
- resolver: yupResolver(contactUsValidationSchema),
- });
+ resolver: yupResolver(contactUsValidationSchema)
+ })
- const onSubmit = async (data: {
- firstName: string;
- lastName: string;
- email: string;
- phoneNumber?: string;
- note?: string;
- }) => {
+ const onSubmit = async data => {
try {
- await pb.collection("contact").create({ source: "contactus", ...data });
- localStorage.setItem("contactus", JSON.stringify(data));
+ await pb.collection("contact").create({ source: "contactus", ...data })
+ localStorage.setItem("contactus", JSON.stringify(data))
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
@@ -36,11 +30,11 @@ const FormLeftDescriptionRightContactUs = () => {
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
+ }
return (
<>
{/* Contact Us */}
@@ -250,7 +244,7 @@ const FormLeftDescriptionRightContactUs = () => {
{/* End Contact Us */}
>
- );
-};
+ )
+}
-export default FormLeftDescriptionRightContactUs;
+export default FormLeftDescriptionRightContactUs
diff --git a/Frontend/sections/FAQ/RightAlignedBorderBottomFAQ.tsx b/Frontend/sections/FAQ/RightAlignedBorderBottomFAQ.jsx
similarity index 87%
rename from Frontend/sections/FAQ/RightAlignedBorderBottomFAQ.tsx
rename to Frontend/sections/FAQ/RightAlignedBorderBottomFAQ.jsx
index 01d242d..14cda4d 100644
--- a/Frontend/sections/FAQ/RightAlignedBorderBottomFAQ.tsx
+++ b/Frontend/sections/FAQ/RightAlignedBorderBottomFAQ.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React from "react"
function RightAlignedBorderBottomFAQ() {
return (
@@ -31,7 +31,10 @@ function RightAlignedBorderBottomFAQ() {
className="w-auto h-auto"
defaultChecked
/>
-
+
My tech stack is different can I still use it?
@@ -51,7 +54,10 @@ function RightAlignedBorderBottomFAQ() {
name="my-accordion-3"
className="w-auto h-auto"
/>
-
+
What do I get exactly?
@@ -77,7 +83,10 @@ function RightAlignedBorderBottomFAQ() {
name="my-accordion-3"
className="w-auto h-auto"
/>
-
+
Is it a website template?
@@ -99,7 +108,10 @@ function RightAlignedBorderBottomFAQ() {
name="my-accordion-3"
className="w-auto h-auto"
/>
-
+
Are there any other costs associated
@@ -119,7 +131,10 @@ function RightAlignedBorderBottomFAQ() {
name="my-accordion-3"
className="w-auto h-auto"
/>
-
+
How is FastPocket different from other boilerplates
@@ -140,7 +155,7 @@ function RightAlignedBorderBottomFAQ() {
\{/* End FAQ */}
>
- );
+ )
}
-export default RightAlignedBorderBottomFAQ;
+export default RightAlignedBorderBottomFAQ
diff --git a/Frontend/sections/Features/CardsFeature.tsx b/Frontend/sections/Features/CardsFeature.jsx
similarity index 99%
rename from Frontend/sections/Features/CardsFeature.tsx
rename to Frontend/sections/Features/CardsFeature.jsx
index eb57ddc..b906a94 100644
--- a/Frontend/sections/Features/CardsFeature.tsx
+++ b/Frontend/sections/Features/CardsFeature.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React from "react"
function CardsFeature() {
return (
@@ -212,7 +212,7 @@ function CardsFeature() {
{/* End Icon Blocks */}
>
- );
+ )
}
-export default CardsFeature;
+export default CardsFeature
diff --git a/Frontend/sections/Features/ContainerImageIconBlocksFeature.tsx b/Frontend/sections/Features/ContainerImageIconBlocksFeature.jsx
similarity index 98%
rename from Frontend/sections/Features/ContainerImageIconBlocksFeature.tsx
rename to Frontend/sections/Features/ContainerImageIconBlocksFeature.jsx
index 8053ade..a988cd1 100644
--- a/Frontend/sections/Features/ContainerImageIconBlocksFeature.tsx
+++ b/Frontend/sections/Features/ContainerImageIconBlocksFeature.jsx
@@ -1,5 +1,5 @@
-import React from "react";
-import Image from "next/image";
+import React from "react"
+import Image from "next/image"
function ContainerImageIconBlocksFeature() {
return (
@@ -164,7 +164,7 @@ function ContainerImageIconBlocksFeature() {
{/* End Features */}
>
- );
+ )
}
-export default ContainerImageIconBlocksFeature;
+export default ContainerImageIconBlocksFeature
diff --git a/Frontend/sections/Features/SolidBackgrondIconFeature.tsx b/Frontend/sections/Features/SolidBackgrondIconFeature.jsx
similarity index 97%
rename from Frontend/sections/Features/SolidBackgrondIconFeature.tsx
rename to Frontend/sections/Features/SolidBackgrondIconFeature.jsx
index 9aa9558..8f3f27a 100644
--- a/Frontend/sections/Features/SolidBackgrondIconFeature.tsx
+++ b/Frontend/sections/Features/SolidBackgrondIconFeature.jsx
@@ -1,6 +1,6 @@
-import React from "react";
-import Image from "next/image";
-import { Library32Filled } from "@fluentui/react-icons";
+import React from "react"
+import Image from "next/image"
+import { Library32Filled } from "@fluentui/react-icons"
function SolidBackgrondIconFeature() {
return (
@@ -149,7 +149,7 @@ function SolidBackgrondIconFeature() {
{/* End Icon Blocks */}
>
- );
+ )
}
-export default SolidBackgrondIconFeature;
+export default SolidBackgrondIconFeature
diff --git a/Frontend/sections/Features/VerticalTabsFeature.tsx b/Frontend/sections/Features/VerticalTabsFeature.jsx
similarity index 93%
rename from Frontend/sections/Features/VerticalTabsFeature.tsx
rename to Frontend/sections/Features/VerticalTabsFeature.jsx
index eba9f3d..df57b0b 100644
--- a/Frontend/sections/Features/VerticalTabsFeature.tsx
+++ b/Frontend/sections/Features/VerticalTabsFeature.jsx
@@ -1,9 +1,9 @@
-"use client";
-import Image from "next/image";
-import React, { useState } from "react";
+"use client"
+import Image from "next/image"
+import React, { useState } from "react"
function VerticalTabsFeature() {
- const [tab, setTab] = useState("1");
+ const [tab, setTab] = useState("1")
return (
<>
{/* Features */}
@@ -23,9 +23,8 @@ function VerticalTabsFeature() {
>
{/* End Features */}
>
- );
+ )
}
-export default VerticalTabsFeature;
+export default VerticalTabsFeature
diff --git a/Frontend/sections/Hero/CenterAllignedWithVideoHero.tsx b/Frontend/sections/Hero/CenterAllignedWithVideoHero.jsx
similarity index 92%
rename from Frontend/sections/Hero/CenterAllignedWithVideoHero.tsx
rename to Frontend/sections/Hero/CenterAllignedWithVideoHero.jsx
index d24a87d..cf1391c 100644
--- a/Frontend/sections/Hero/CenterAllignedWithVideoHero.tsx
+++ b/Frontend/sections/Hero/CenterAllignedWithVideoHero.jsx
@@ -1,5 +1,5 @@
-import React from "react";
-import Video from "../Video";
+import React from "react"
+import Video from "../Video"
const CenterAllignedWithVideoHero = () => {
return (
@@ -30,7 +30,7 @@ const CenterAllignedWithVideoHero = () => {
{/* End Hero */}
>
- );
-};
+ )
+}
-export default CenterAllignedWithVideoHero;
+export default CenterAllignedWithVideoHero
diff --git a/Frontend/sections/Hero/SimpleHero.tsx b/Frontend/sections/Hero/SimpleHero.jsx
similarity index 95%
rename from Frontend/sections/Hero/SimpleHero.tsx
rename to Frontend/sections/Hero/SimpleHero.jsx
index 32effc6..a4e11b2 100644
--- a/Frontend/sections/Hero/SimpleHero.tsx
+++ b/Frontend/sections/Hero/SimpleHero.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React from "react"
const SimpleHero = () => {
return (
@@ -35,7 +35,7 @@ const SimpleHero = () => {
- );
-};
+ )
+}
-export default SimpleHero;
+export default SimpleHero
diff --git a/Frontend/sections/Hero/SquaredBackgroundHero.tsx b/Frontend/sections/Hero/SquaredBackgroundHero.jsx
similarity index 93%
rename from Frontend/sections/Hero/SquaredBackgroundHero.tsx
rename to Frontend/sections/Hero/SquaredBackgroundHero.jsx
index 03736ec..5c718de 100644
--- a/Frontend/sections/Hero/SquaredBackgroundHero.tsx
+++ b/Frontend/sections/Hero/SquaredBackgroundHero.jsx
@@ -1,7 +1,7 @@
-import Background from "@/components/Utilities/Background";
-import { title } from "@/constants";
-import Image from "next/image";
-import React from "react";
+import Background from "@/components/Utilities/Background"
+import { title } from "@/constants"
+import Image from "next/image"
+import React from "react"
const SquaredBackgroundHero = () => {
return (
@@ -72,7 +72,7 @@ const SquaredBackgroundHero = () => {
{/* End Hero */}
>
- );
-};
+ )
+}
-export default SquaredBackgroundHero;
+export default SquaredBackgroundHero
diff --git a/Frontend/sections/Hero/WaitingListWithImageHero.tsx b/Frontend/sections/Hero/WaitingListWithImageHero.jsx
similarity index 90%
rename from Frontend/sections/Hero/WaitingListWithImageHero.tsx
rename to Frontend/sections/Hero/WaitingListWithImageHero.jsx
index aa2d852..b2511e7 100644
--- a/Frontend/sections/Hero/WaitingListWithImageHero.tsx
+++ b/Frontend/sections/Hero/WaitingListWithImageHero.jsx
@@ -1,34 +1,26 @@
-"use client";
+"use client"
+import pb from "@/lib/pocketbase"
+import { waitinglistValidationSchema } from "@/utils/form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import React from "react"
+import { useForm } from "react-hook-form"
-import pb from "@/lib/pocketbase";
-import { waitinglistValidationSchema } from "@/utils/form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import React from "react";
-import { useForm } from "react-hook-form";
-
-import Footer from "@/components/Footer";
-import Background from "@/components/Utilities/Background";
-import { toast } from "react-toastify";
-import { title } from "@/constants";
-import Logo from "@/components/Logo";
+import Background from "@/components/Utilities/Background"
+import { toast } from "react-toastify"
const WaitingListWithImageHero = () => {
const {
register,
handleSubmit,
- formState: { errors, isSubmitting },
+ formState: { errors, isSubmitting }
} = useForm({
- resolver: yupResolver(waitinglistValidationSchema),
- });
+ resolver: yupResolver(waitinglistValidationSchema)
+ })
- const onSubmit = async (data: {
- firstName: string;
- lastName: string;
- email: string;
- }) => {
+ const onSubmit = async data => {
try {
- await pb.collection("contact").create({ source: "waitinglist", ...data });
- localStorage.setItem("waitinglist", JSON.stringify(data));
+ await pb.collection("contact").create({ source: "waitinglist", ...data })
+ localStorage.setItem("waitinglist", JSON.stringify(data))
} catch (error) {
if (error instanceof Error) {
toast.error(error.message, {
@@ -39,11 +31,11 @@ const WaitingListWithImageHero = () => {
pauseOnHover: true,
draggable: true,
progress: undefined,
- theme: "colored",
- });
+ theme: "colored"
+ })
}
}
- };
+ }
return (
@@ -211,7 +203,7 @@ const WaitingListWithImageHero = () => {
- );
-};
+ )
+}
-export default WaitingListWithImageHero;
+export default WaitingListWithImageHero
diff --git a/Frontend/sections/Hero/index.js b/Frontend/sections/Hero/index.js
new file mode 100644
index 0000000..8de674c
--- /dev/null
+++ b/Frontend/sections/Hero/index.js
@@ -0,0 +1,8 @@
+import SquaredBackgroundHero from "./SquaredBackgroundHero"
+import CenterAllignedWithVideoHero from "./CenterAllignedWithVideoHero"
+import WaitingListWithImageHero from "./WaitingListWithImageHero"
+export {
+ SquaredBackgroundHero,
+ CenterAllignedWithVideoHero,
+ WaitingListWithImageHero
+}
diff --git a/Frontend/sections/Hero/index.ts b/Frontend/sections/Hero/index.ts
deleted file mode 100644
index 1683333..0000000
--- a/Frontend/sections/Hero/index.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-import SquaredBackgroundHero from "./SquaredBackgroundHero";
-import CenterAllignedWithVideoHero from "./CenterAllignedWithVideoHero";
-import WaitingListWithImageHero from "./WaitingListWithImageHero";
-export {
- SquaredBackgroundHero,
- CenterAllignedWithVideoHero,
- WaitingListWithImageHero
-};
\ No newline at end of file
diff --git a/Frontend/sections/Newsletter/Newsletter.tsx b/Frontend/sections/Newsletter/Newsletter.jsx
similarity index 81%
rename from Frontend/sections/Newsletter/Newsletter.tsx
rename to Frontend/sections/Newsletter/Newsletter.jsx
index 5c91ef8..5c47e03 100644
--- a/Frontend/sections/Newsletter/Newsletter.tsx
+++ b/Frontend/sections/Newsletter/Newsletter.jsx
@@ -1,96 +1,96 @@
-"use client";
-
-import pb from "@/lib/pocketbase";
-import { emailValidationSchema } from "@/utils/form";
-import { yupResolver } from "@hookform/resolvers/yup";
-import React from "react";
-import { useForm } from "react-hook-form";
-import { toast } from "react-toastify";
-
-function Newsletter() {
- const {
- register,
- handleSubmit,
- formState: { errors },
- } = useForm({
- resolver: yupResolver(emailValidationSchema),
- });
-
- const onSubmit = async (data: { email: string }) => {
- try {
- await pb.collection("contact").create({ source: "newsletter", ...data });
- localStorage.setItem("newsletter", JSON.stringify(data));
- } 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",
- });
- }
- }
- };
-
- return (
-
-
- {/* CTA box */}
-
- {typeof window !== "undefined" &&
- !localStorage.getItem("newsletter") ? (
-
-
-
- Stay Ahead of the Curve
-
-
- Join our newsletter to get top news before anyone else.
-
-
-
-
-
- ) : (
-
-
- Thanks for subscribing. You won't regret it!
-
-
- )}
-
-
-
- );
-}
-
-export default Newsletter;
+"use client"
+
+import pb from "@/lib/pocketbase"
+import { emailValidationSchema } from "@/utils/form"
+import { yupResolver } from "@hookform/resolvers/yup"
+import React from "react"
+import { useForm } from "react-hook-form"
+import { toast } from "react-toastify"
+
+function Newsletter() {
+ const {
+ register,
+ handleSubmit,
+ formState: { errors }
+ } = useForm({
+ resolver: yupResolver(emailValidationSchema)
+ })
+
+ const onSubmit = async data => {
+ try {
+ await pb.collection("contact").create({ source: "newsletter", ...data })
+ localStorage.setItem("newsletter", JSON.stringify(data))
+ } 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"
+ })
+ }
+ }
+ }
+
+ return (
+
+
+ {/* CTA box */}
+
+ {typeof window !== "undefined" &&
+ !localStorage.getItem("newsletter") ? (
+
+
+
+ Stay Ahead of the Curve
+
+
+ Join our newsletter to get top news before anyone else.
+
+
+
+
+
+ ) : (
+
+
+ Thanks for subscribing. You won't regret it!
+
+
+ )}
+
+
+
+ )
+}
+
+export default Newsletter
diff --git a/Frontend/sections/PageHeader.tsx b/Frontend/sections/PageHeader.jsx
similarity index 50%
rename from Frontend/sections/PageHeader.tsx
rename to Frontend/sections/PageHeader.jsx
index 799ee3b..14b339c 100644
--- a/Frontend/sections/PageHeader.tsx
+++ b/Frontend/sections/PageHeader.jsx
@@ -1,11 +1,6 @@
-import React, { ReactNode } from "react";
+import React from "react"
-interface PageHeaderProps {
- title: string;
- subtitle?: ReactNode;
- className?: string;
-}
-function PageHeader({ title, subtitle, className }: PageHeaderProps) {
+function PageHeader({ title, subtitle, className }) {
return (
@@ -13,7 +8,7 @@ function PageHeader({ title, subtitle, className }: PageHeaderProps) {
{subtitle}
- );
+ )
}
-export default PageHeader;
+export default PageHeader
diff --git a/Frontend/sections/Payment.tsx b/Frontend/sections/Payment.jsx
similarity index 70%
rename from Frontend/sections/Payment.tsx
rename to Frontend/sections/Payment.jsx
index cff700f..0295dd0 100644
--- a/Frontend/sections/Payment.tsx
+++ b/Frontend/sections/Payment.jsx
@@ -1,19 +1,15 @@
"use client";
-import React, { useEffect } from "react";
-import { Product } from "@/types";
+import React, { useEffect, useState } from "react";
import PriceCard from "@/components/PriceCard";
-import { useState } from "react";
import PriceToggle from "@/components/PriceToggle";
-import { apiPrices } from "../app/(public)/pricing/actions";
+import { apiPrices } from "../app/(public)/pricing/action";
const Payment = ({
type = "one_time",
-}: {
- type?: "one_time" | "reoccuring";
}) => {
const [isAnnual, setIsAnnual] = useState(false);
- const [products, setProducts] = useState([]);
+ const [products, setProducts] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const handleToggle = () => {
setIsAnnual((prev) => !prev);
@@ -21,7 +17,7 @@ const Payment = ({
useEffect(() => {
setIsLoading(true);
(async () => {
- const resposeProducts: Product[] = await apiPrices();
+ const resposeProducts = await apiPrices();
setProducts(resposeProducts);
setIsLoading(false);
})();
@@ -39,17 +35,17 @@ const Payment = ({
>
{isLoading ? (
<>
-
-
-
+
+
+
>
) : (
- (products ?? [])
+ (products || [])
.filter((x) =>
type == "one_time" ? x.type == "one_time" : x.type != "one_time"
)
.map((x, i) => (
-
+
))
)}
@@ -59,3 +55,4 @@ const Payment = ({
};
export default Payment;
+
diff --git a/Frontend/sections/Testemonial/CardTestemonial.tsx b/Frontend/sections/Testemonial/CardTestemonial.jsx
similarity index 96%
rename from Frontend/sections/Testemonial/CardTestemonial.tsx
rename to Frontend/sections/Testemonial/CardTestemonial.jsx
index dc34ace..705a263 100644
--- a/Frontend/sections/Testemonial/CardTestemonial.tsx
+++ b/Frontend/sections/Testemonial/CardTestemonial.jsx
@@ -1,5 +1,5 @@
-import React from "react";
-import Image from "next/image";
+import React from "react"
+import Image from "next/image"
function CardTestemonial() {
return (
@@ -61,7 +61,7 @@ function CardTestemonial() {
{/* End Testimonials */}
>
- );
+ )
}
-export default CardTestemonial;
+export default CardTestemonial
diff --git a/Frontend/sections/Testimonial.tsx b/Frontend/sections/Testimonial.jsx
similarity index 98%
rename from Frontend/sections/Testimonial.tsx
rename to Frontend/sections/Testimonial.jsx
index b2ffb8d..786e2b7 100644
--- a/Frontend/sections/Testimonial.tsx
+++ b/Frontend/sections/Testimonial.jsx
@@ -1,4 +1,4 @@
-import React from "react";
+import React from "react"
export const Testimonial = () => {
return (
@@ -36,5 +36,5 @@ export const Testimonial = () => {
- );
-};
+ )
+}
diff --git a/Frontend/sections/Testing/Teste.jsx b/Frontend/sections/Testing/Teste.jsx
new file mode 100644
index 0000000..4cf3074
--- /dev/null
+++ b/Frontend/sections/Testing/Teste.jsx
@@ -0,0 +1,216 @@
+function Teste() {
+ return (
+ <>
+ {/* */}
+
+ {/* */}
+
+ {/* */}
+
+
+
+
+ Atlassian API
+
+
+ Atlassian
+
+
+ A software that develops products for software developers and
+ developments.
+
+
+
+
+ {/* */}
+
+ {/* */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Asana API
+
+
+ Asana
+
+
+ Track tasks and projects, use agile boards, measure progress.
+
+
+
+
+ {/* */}
+
+ {/* */}
+
+
+
+
+ Slack API
+
+
+ Slack
+
+
+ Email collaboration and email service desk made easy.
+
+
+
+
+ {/* */}
+
+ {/* */}
+
+ {/* */}
+ >
+ )
+ }
+
+ export default Teste
+
\ No newline at end of file
diff --git a/Frontend/sections/Testing/Teste.tsx b/Frontend/sections/Testing/Teste.tsx
deleted file mode 100644
index 1489811..0000000
--- a/Frontend/sections/Testing/Teste.tsx
+++ /dev/null
@@ -1,216 +0,0 @@
-function Teste() {
- return (
-
-<>
- {/* */}
-
- {/* */}
-
- {/* */}
-
-
-
-
- Atlassian API
-
-
- Atlassian
-
-
- A software that develops products for software developers and
- developments.
-
-
-
-
- {/* */}
-
- {/* */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Asana API
-
-
- Asana
-
-
- Track tasks and projects, use agile boards, measure progress.
-
-
-
-
- {/* */}
-
- {/* */}
-
-
-
-
- Slack API
-
-
- Slack
-
-
- Email collaboration and email service desk made easy.
-
-
-
-
- {/* */}
-
- {/* */}
-
- {/* */}
- >
- )
-}
-
-export default Teste
\ No newline at end of file
diff --git a/Frontend/sections/Video.tsx b/Frontend/sections/Video.jsx
similarity index 69%
rename from Frontend/sections/Video.tsx
rename to Frontend/sections/Video.jsx
index 714a7ba..f883dc1 100644
--- a/Frontend/sections/Video.tsx
+++ b/Frontend/sections/Video.jsx
@@ -1,41 +1,41 @@
-"use client";
-
-import YouTubeFrame from "@/components/Utilities/YoutubeEmbed";
-import React from "react";
-import { useState, useEffect } from "react";
-
-function Video() {
- const [windowWidth, setWindowWidth] = useState(0);
-
- useEffect(() => {
- setWindowWidth(window.innerWidth);
- }, []);
-
- return (
-
-
- {/* Hero image */}
-
- 425
- ? windowWidth > 800
- ? 800
- : 400
- : 280
- }
- height={!!windowWidth && windowWidth > 425 ? 500 : 240}
- />
-
-
-
- );
-}
-
-export default Video;
+"use client"
+
+import YouTubeFrame from "@/components/Utilities/YoutubeEmbed"
+import React from "react"
+import { useState, useEffect } from "react"
+
+function Video() {
+ const [windowWidth, setWindowWidth] = useState(0)
+
+ useEffect(() => {
+ setWindowWidth(window.innerWidth)
+ }, [])
+
+ return (
+
+
+ {/* Hero image */}
+
+ 425
+ ? windowWidth > 800
+ ? 800
+ : 400
+ : 280
+ }
+ height={!!windowWidth && windowWidth > 425 ? 500 : 240}
+ />
+
+
+
+ )
+}
+
+export default Video
diff --git a/Frontend/tailwind.config.js b/Frontend/tailwind.config.js
new file mode 100644
index 0000000..c7d0ef7
--- /dev/null
+++ b/Frontend/tailwind.config.js
@@ -0,0 +1,113 @@
+// const defaultTheme = require("tailwindcss/defaultTheme");
+
+const config = {
+ content: [
+ "./pages/**/*.{js,ts,jsx,tsx,mdx}",
+ "./components/**/*.{js,ts,jsx,tsx,mdx}",
+ "./sections/**/*.{js,ts,jsx,tsx,mdx}",
+ "./app/**/*.{js,ts,jsx,tsx,mdx}",
+ "./node_modules/preline/preline.js"
+ ],
+ theme: {
+ extend: {
+ fontFamily: {
+ heading: "var(--heading-font)",
+ body: "var(--heading-font)",
+ accent: "var(--accent-font)"
+ },
+ fontSize: {
+ xs: "0.75rem",
+ sm: "0.875rem",
+ base: "1rem",
+ lg: "1.125rem",
+ xl: "1.25rem",
+ "2xl": "1.5rem",
+ "3xl": "2rem",
+ "4xl": "2.5rem",
+ "5xl": "3.25rem",
+ "6xl": "4rem"
+ },
+ letterSpacing: {
+ tighter: "-0.02em",
+ tight: "-0.01em",
+ normal: "0",
+ wide: "0.01em",
+ wider: "0.02em",
+ widest: "0.4em"
+ },
+ typography: {
+ DEFAULT: {
+ css: {
+ p: {
+ fontFamily: "var(--body-font)"
+ },
+ h1: {
+ fontFamily: "var(--heading-font)"
+ },
+ h2: {
+ fontFamily: "var(--heading-font)"
+ },
+ h3: {
+ fontFamily: "var(--heading-font)"
+ },
+ h4: {
+ fontFamily: "var(--heading-font)"
+ },
+ h5: {
+ fontFamily: "var(--heading-font)"
+ },
+ h6: {
+ fontFamily: "var(--heading-font)"
+ }
+ }
+ }
+ }
+ }
+ },
+ daisyui: {
+ themes: [
+ {
+ light: {
+ primary: "#FD5469",
+ "primary-content": "#F5F5F5",
+ secondary: "#7082FF",
+ "secondary-content": "#000",
+ accent: "#fd0000",
+ neutral: "#28282e",
+ "base-100": "#FBFAFA",
+ "base-200": "#F9F8F8",
+ "base-300": "#F4F3F4",
+ "base-content": "#000",
+ info: "#00f5ff",
+ success: "#00ff8b",
+ warning: "#ff5100",
+ error: "#ff0051"
+ },
+ dark: {
+ primary: "#FD5469",
+ "primary-content": "#F5F5F5",
+ secondary: "#7082FF",
+ "secondary-content": "#fff",
+ accent: "#006cff",
+ neutral: "#060206",
+ "base-100": "#2a3130",
+ "base-200": "#2a2d2a",
+ "base-300": "#292924",
+ "base-content": "#fff",
+ info: "#009ae0",
+ success: "#76e200",
+ warning: "#eb9400",
+ error: "#be2133"
+ }
+ }
+ ]
+ },
+ plugins: [
+ require("@tailwindcss/forms"),
+ require("@tailwindcss/typography"),
+ require("daisyui"),
+ require("preline/plugin")
+ ]
+ }
+ export default config
+
\ No newline at end of file
diff --git a/Frontend/tailwind.config.ts b/Frontend/tailwind.config.ts
deleted file mode 100644
index ed57b89..0000000
--- a/Frontend/tailwind.config.ts
+++ /dev/null
@@ -1,113 +0,0 @@
-import type { Config } from "tailwindcss";
-// const defaultTheme = require("tailwindcss/defaultTheme");
-
-const config: Config = {
- content: [
- "./pages/**/*.{js,ts,jsx,tsx,mdx}",
- "./components/**/*.{js,ts,jsx,tsx,mdx}",
- "./sections/**/*.{js,ts,jsx,tsx,mdx}",
- "./app/**/*.{js,ts,jsx,tsx,mdx}",
- "./node_modules/preline/preline.js",
- ],
- theme: {
- extend: {
- fontFamily: {
- heading: 'var(--heading-font)',
- body: 'var(--heading-font)',
- accent: 'var(--accent-font)',
- },
- fontSize: {
- xs: "0.75rem",
- sm: "0.875rem",
- base: "1rem",
- lg: "1.125rem",
- xl: "1.25rem",
- "2xl": "1.5rem",
- "3xl": "2rem",
- "4xl": "2.5rem",
- "5xl": "3.25rem",
- "6xl": "4rem",
- },
- letterSpacing: {
- tighter: "-0.02em",
- tight: "-0.01em",
- normal: "0",
- wide: "0.01em",
- wider: "0.02em",
- widest: "0.4em",
- },
- typography: {
- DEFAULT: {
- css: {
- p: {
- fontFamily: 'var(--body-font)'
- },
- h1: {
- fontFamily: 'var(--heading-font)'
- },
- h2: {
- fontFamily: 'var(--heading-font)'
- },
- h3: {
- fontFamily: 'var(--heading-font)'
- },
- h4: {
- fontFamily: 'var(--heading-font)'
- },
- h5: {
- fontFamily: 'var(--heading-font)'
- },
- h6: {
- fontFamily: 'var(--heading-font)'
- }
- }
- }
- }
- },
- },
- daisyui: {
- themes: [
- {
- light: {
- primary: "#FD5469",
- "primary-content": "#F5F5F5",
- secondary: "#7082FF",
- "secondary-content": "#000",
- accent: "#fd0000",
- neutral: "#28282e",
- "base-100": "#FBFAFA",
- "base-200": "#F9F8F8",
- "base-300": "#F4F3F4",
- "base-content": "#000",
- info: "#00f5ff",
- success: "#00ff8b",
- warning: "#ff5100",
- error: "#ff0051",
- },
- dark: {
- primary: "#FD5469",
- "primary-content": "#F5F5F5",
- secondary: "#7082FF",
- "secondary-content": "#fff",
- accent: "#006cff",
- neutral: "#060206",
- "base-100": "#2a3130",
- "base-200": "#2a2d2a",
- "base-300": "#292924",
- "base-content": "#fff",
- info: "#009ae0",
- success: "#76e200",
- warning: "#eb9400",
- error: "#be2133",
- }
- },
- ],
- },
- plugins: [
- require("@tailwindcss/forms"),
- require("@tailwindcss/typography"),
- require("daisyui"),
- require("preline/plugin"),
- ],
-};
-export default config;
diff --git a/Frontend/tsconfig.json b/Frontend/tsconfig.json
index 1e857d3..b540054 100644
--- a/Frontend/tsconfig.json
+++ b/Frontend/tsconfig.json
@@ -35,7 +35,7 @@
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts"
-, "app/providers.js" ],
+, "app/providers.js", "app/actions.js", "sections/Payment.jsx", "sections/AccountContent.jsx" ],
"exclude": [
"node_modules"
]
diff --git a/Frontend/types/index.js b/Frontend/types/index.js
new file mode 100644
index 0000000..fcf4a52
--- /dev/null
+++ b/Frontend/types/index.js
@@ -0,0 +1,10 @@
+export let SourceModal
+
+;(function(SourceModal) {
+ SourceModal["SignUp"] = "SignUp"
+ SourceModal["SignUpViaPurchase"] = "SignUpViaPurchase"
+ SourceModal["BookDemo"] = "BookDemo"
+ SourceModal["LearnMore"] = "LearnMore"
+ SourceModal["TryIt"] = "TryIt"
+ SourceModal["Newsletter"] = "Newsletter"
+})(SourceModal || (SourceModal = {}))
diff --git a/Frontend/utils/colors.js b/Frontend/utils/colors.js
new file mode 100644
index 0000000..62d1cdb
--- /dev/null
+++ b/Frontend/utils/colors.js
@@ -0,0 +1,14 @@
+import tw from "../tailwind.config"
+
+export default tw.daisyui.themes[0]
+
+export function hexToRgb(hex) {
+ 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
+}
diff --git a/Frontend/utils/colors.ts b/Frontend/utils/colors.ts
deleted file mode 100644
index 7447797..0000000
--- a/Frontend/utils/colors.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-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;
- }
\ No newline at end of file
diff --git a/Frontend/utils/form.ts b/Frontend/utils/form.js
similarity index 65%
rename from Frontend/utils/form.ts
rename to Frontend/utils/form.js
index d6230b3..735aca4 100644
--- a/Frontend/utils/form.ts
+++ b/Frontend/utils/form.js
@@ -1,46 +1,42 @@
-import * as Yup from "yup";
-import YupPassword from "yup-password";
-YupPassword(Yup);
+import * as Yup from "yup"
+import YupPassword from "yup-password"
+YupPassword(Yup)
-declare module "yup" {
- interface StringSchema {
- mobileNumberValidation(errorMessage: string): StringSchema;
- }
-}
-
-const isValidMobileNumber = (mobileNumber: string | any[]) => {
+const isValidMobileNumber = mobileNumber => {
if (mobileNumber.length < 8 || mobileNumber.length > 12) {
return {
success: false,
- message: "Mobile Number should of 9 to 11 length",
- };
+ message: "Mobile Number should of 9 to 11 length"
+ }
} else if (isNaN(Number(mobileNumber))) {
return {
success: false,
- message: "Mobile Number should only contain numbers",
- };
- }
- return { success: true, message: "Valid Mobile Number" };
-};
-
-Yup.addMethod(Yup.string, "mobileNumberValidation", function (errorMessage) {
- return this.test(`test-mobile-number`, errorMessage, function (value) {
- const { path, createError } = this;
- if (!value) {
- return createError({ path, message: errorMessage });
+ message: "Mobile Number should only contain numbers"
}
- const validation = isValidMobileNumber(value);
+ }
+ return { success: true, message: "Valid Mobile Number" }
+}
+
+Yup.addMethod(Yup.string, "mobileNumberValidation", function(errorMessage) {
+ return this.test(`test-mobile-number`, errorMessage, function(value) {
+ const { path, createError } = this
+ if (!value) {
+ return createError({ path, message: errorMessage })
+ }
+ const validation = isValidMobileNumber(value)
return (
(value && validation.success) ||
createError({ path, message: validation.message })
- );
- });
-});
+ )
+ })
+})
const signUpValidationSchema = 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"),
+ email: Yup.string()
+ .email()
+ .required("E-mail is required"),
phoneNumber: Yup.string()
.required("Phone Number is required")
.mobileNumberValidation("Phone Number is not valid"),
@@ -50,51 +46,59 @@ const signUpValidationSchema = Yup.object().shape({
.password()
.required("Password is required.")
.min(8, "Password is too short - should be 8 characters minimum.")
-});
+})
const passwordValidationSchema = Yup.object().shape({
newPassword: Yup.string()
.password()
.required("Password is required.")
.min(8, "Password is too short - should be 8 characters minimum."),
- newPasswordConfirm: Yup.string()
+ newPasswordConfirm: Yup.string()
.password()
.required("Password is required.")
.min(8, "Password is too short - should be 8 characters minimum.")
-});
+})
const changeEmailValidationSchema = Yup.object().shape({
password: Yup.string()
.password()
.required("Password is required.")
- .min(8, "Password is too short - should be 8 characters minimum."),
-});
+ .min(8, "Password is too short - should be 8 characters minimum.")
+})
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"),
-});
+ 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"),
-});
+ .required("Phone Number is required")
+ .mobileNumberValidation("Phone Number is not valid"),
+ email: Yup.string()
+ .email()
+ .required("E-mail is required")
+})
const emailValidationSchema = Yup.object().shape({
- email: Yup.string().email().required("E-mail is required"),
-});
+ email: Yup.string()
+ .email()
+ .required("E-mail is required")
+})
const signInValidationSchema = Yup.object().shape({
- email: Yup.string().email().required("E-mail is required"),
+ email: Yup.string()
+ .email()
+ .required("E-mail is required"),
password: Yup.string()
.password()
.required("Password is required.")
.min(8, "Password is too short - should be 8 characters minimum.")
- .minUppercase(1, "password must contain at least 1 upper case letter"),
-});
+ .minUppercase(1, "password must contain at least 1 upper case letter")
+})
export {
emailValidationSchema,
@@ -104,4 +108,4 @@ export {
signInValidationSchema,
waitinglistValidationSchema,
contactUsValidationSchema
-};
+}
diff --git a/Frontend/utils/getPostMetaData.js b/Frontend/utils/getPostMetaData.js
new file mode 100644
index 0000000..b63a208
--- /dev/null
+++ b/Frontend/utils/getPostMetaData.js
@@ -0,0 +1,11 @@
+import pb from "@/lib/pocketbase"
+
+const getPostMetadata = async () => {
+ try {
+ return await pb.collection("blog").getFullList({ requestKey: "blogs" })
+ } catch (error) {
+ return []
+ }
+}
+
+export default getPostMetadata
diff --git a/Frontend/utils/getPostMetaData.ts b/Frontend/utils/getPostMetaData.ts
deleted file mode 100644
index 7580bff..0000000
--- a/Frontend/utils/getPostMetaData.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import pb from '@/lib/pocketbase';
-
-const getPostMetadata = async () => {
- try {
- return (await (pb.collection("blog").getFullList({requestKey:'blogs'})))
- } catch (error) {
- return []
- }
-};
-
-export default getPostMetadata;