Commit 3f6e1486 by jay

initial commit

0 parents
Showing 103 changed files with 3872 additions and 0 deletions
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# .gitignore
# dependencies
/node_modules
/.pnp
.pnp.js
ecosystem.config.js
# testing
/coverage
# next.js
.next
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# local env files
.env*.local
.env
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
# node
package.json
package-lock.json
\ No newline at end of file
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
## Harish notes
# Commands to bootstrap a new next app
mkdir bookit
mv bookit next-js-bookit
cd next-js-bookit
npx create-next-app .
code .
npm run dev
# Section 8: Let's start BookIT frontend.
Setting up _document: https://nextjs.org/docs/advanced-features/custom-document
Setting up header & footer
Setting up layout: https://nextjs.org/docs/basic-features/layouts
# Section 9: Data fetching & pre fetching in next.js
getStaticProps: https://nextjs.org/docs/basic-features/data-fetching/get-static-props (Static site generation)
getStaticPaths: https://nextjs.org/docs/basic-features/data-fetching/get-static-paths (Static site generation)
getServerSideProps: https://nextjs.org/docs/basic-features/data-fetching/get-server-side-props (Server-side rendering)
Here we will be using this resource - https://jsonplaceholder.typicode.com/users
# Section 10: Implementing redux for state management.
npm i redux redux-thunk redux-devtools-extension react-redux next-redux-wrapper --save
npm i axios
https://www.npmjs.com/package/react-toastify
npm i react-toastify
# Section 11: Adding pagination, search on frontend.
https://www.npmjs.com/package/react-js-pagination
npm i react-js-pagination
# Section 12: Authentication with next-auth
npm i validator
https://next-auth.js.org/
npm i next-auth
Reference for next auth and Strapi integration.
https://next-auth.js.org/
https://strapi.io/blog/user-authentication-in-next-js-with-strapi
https://medium.com/@tom555my/strapi-next-js-email-password-authentication-a8207f72b446
{/*
<div className="ml-4 dropdown d-line">
<a className="btn dropdown-toggle mr-4" id="dropDownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span>{user && user.email}</span>
</a>
<div className="dropdown-menu" aria-labelledby="dropDownMenuButton">
<Link href="/bookings/me">
<a className="dropdown-item">My Bookings</a>
</Link>
<Link href="/me/update">
<a className="dropdown-item">Profile</a>
</Link>
<Link href="/">
<a className="dropdown-item">Logout</a>
</Link>
</div>
</div>
*/}
# Section 13:
Reference for forgot password:
https://medium.com/@giuliamalaroda/authentication-with-next-js-and-strapi-part-3-forgotten-reset-password-48c7ee1e85d6
How to send email in Strapi:
https://github.com/strapi/strapi/tree/main/packages/providers/email-nodemailer
How to extend the user-permissions plugin to add update/me route:
https://medium.com/@fabian.froeschl/add-updateme-route-to-strapi-4-0s-users-permissons-plugin-fc31798df295
# Section 14:
https://reactdatepicker.com/
https://reactdatepicker.com/#example-date-range
npm i react-datepicker
# Section 15:
Install the stripe cli. The to test the webhooks we run the following command.
stripe listen --events checkout.session.completed --forward-to localhost:1337/api/bookings/webhook
stripe listen --events checkout.session.completed --forward-to localhost:1337/api/bookings/stripe-webhook --skip-verify
Stripe webhook require raw body, to get that we need to do this setting in the Strapi middleware.
https://github.com/strapi/strapi/issues/4720#issuecomment-1028953626
[
{
"id": "1",
"name": "Mumbai",
"state": "Maharashtra"
},
{
"id": "2",
"name": "Delhi",
"state": "Delhi"
},
{
"id": "3",
"name": "Bengaluru",
"state": "Karnataka"
},
{
"id": "4",
"name": "Ahmedabad",
"state": "Gujarat"
},
{
"id": "5",
"name": "Hyderabad",
"state": "Telangana"
},
{
"id": "6",
"name": "Chennai",
"state": "Tamil Nadu"
},
{
"id": "7",
"name": "Kolkata",
"state": "West Bengal"
},
{
"id": "8",
"name": "Pune",
"state": "Maharashtra"
},
{
"id": "9",
"name": "Jaipur",
"state": "Rajasthan"
},
{
"id": "10",
"name": "Surat",
"state": "Gujarat"
},
{
"id": "11",
"name": "Lucknow",
"state": "Uttar Pradesh"
},
{
"id": "12",
"name": "Kanpur",
"state": "Uttar Pradesh"
},
{
"id": "13",
"name": "Nagpur",
"state": "Maharashtra"
},
{
"id": "14",
"name": "Patna",
"state": "Bihar"
},
{
"id": "15",
"name": "Indore",
"state": "Madhya Pradesh"
},
{
"id": "16",
"name": "Thane",
"state": "Maharashtra"
},
{
"id": "17",
"name": "Bhopal",
"state": "Madhya Pradesh"
},
{
"id": "18",
"name": "Visakhapatnam",
"state": "Andhra Pradesh"
},
{
"id": "19",
"name": "Vadodara",
"state": "Gujarat"
},
{
"id": "20",
"name": "Firozabad",
"state": "Uttar Pradesh"
},
{
"id": "21",
"name": "Ludhiana",
"state": "Punjab"
},
{
"id": "22",
"name": "Rajkot",
"state": "Gujarat"
},
{
"id": "23",
"name": "Agra",
"state": "Uttar Pradesh"
},
{
"id": "24",
"name": "Siliguri",
"state": "West Bengal"
},
{
"id": "25",
"name": "Nashik",
"state": "Maharashtra"
},
{
"id": "26",
"name": "Faridabad",
"state": "Haryana"
},
{
"id": "27",
"name": "Patiala",
"state": "Punjab"
},
{
"id": "28",
"name": "Meerut",
"state": "Uttar Pradesh"
},
{
"id": "29",
"name": "Kalyan-Dombivali",
"state": "Maharashtra"
},
{
"id": "30",
"name": "Vasai-Virar",
"state": "Maharashtra"
},
{
"id": "31",
"name": "Varanasi",
"state": "Uttar Pradesh"
},
{
"id": "32",
"name": "Srinagar",
"state": "Jammu and Kashmir"
},
{
"id": "33",
"name": "Dhanbad",
"state": "Jharkhand"
},
{
"id": "34",
"name": "Jodhpur",
"state": "Rajasthan"
},
{
"id": "35",
"name": "Amritsar",
"state": "Punjab"
},
{
"id": "36",
"name": "Raipur",
"state": "Chhattisgarh"
},
{
"id": "37",
"name": "Allahabad",
"state": "Uttar Pradesh"
},
{
"id": "38",
"name": "Coimbatore",
"state": "Tamil Nadu"
},
{
"id": "39",
"name": "Jabalpur",
"state": "Madhya Pradesh"
},
{
"id": "40",
"name": "Gwalior",
"state": "Madhya Pradesh"
},
{
"id": "41",
"name": "Vijayawada",
"state": "Andhra Pradesh"
},
{
"id": "42",
"name": "Madurai",
"state": "Tamil Nadu"
},
{
"id": "43",
"name": "Guwahati",
"state": "Assam"
},
{
"id": "44",
"name": "Chandigarh",
"state": "Chandigarh"
},
{
"id": "45",
"name": "Hubli-Dharwad",
"state": "Karnataka"
},
{
"id": "46",
"name": "Amroha",
"state": "Uttar Pradesh"
},
{
"id": "47",
"name": "Moradabad",
"state": "Uttar Pradesh"
},
{
"id": "48",
"name": "Gurgaon",
"state": "Haryana"
},
{
"id": "49",
"name": "Aligarh",
"state": "Uttar Pradesh"
},
{
"id": "50",
"name": "Solapur",
"state": "Maharashtra"
},
{
"id": "51",
"name": "Ranchi",
"state": "Jharkhand"
},
{
"id": "52",
"name": "Jalandhar",
"state": "Punjab"
},
{
"id": "53",
"name": "Tiruchirappalli",
"state": "Tamil Nadu"
},
{
"id": "54",
"name": "Bhubaneswar",
"state": "Odisha"
},
{
"id": "55",
"name": "Salem",
"state": "Tamil Nadu"
},
{
"id": "56",
"name": "Warangal",
"state": "Telangana"
},
{
"id": "57",
"name": "Mira-Bhayandar",
"state": "Maharashtra"
},
{
"id": "58",
"name": "Thiruvananthapuram",
"state": "Kerala"
},
{
"id": "59",
"name": "Bhiwandi",
"state": "Maharashtra"
},
{
"id": "60",
"name": "Saharanpur",
"state": "Uttar Pradesh"
},
{
"id": "61",
"name": "Guntur",
"state": "Andhra Pradesh"
},
{
"id": "62",
"name": "Amravati",
"state": "Maharashtra"
},
{
"id": "63",
"name": "Bikaner",
"state": "Rajasthan"
},
{
"id": "64",
"name": "Noida",
"state": "Uttar Pradesh"
},
{
"id": "65",
"name": "Jamshedpur",
"state": "Jharkhand"
},
{
"id": "66",
"name": "Bhilai Nagar",
"state": "Chhattisgarh"
},
{
"id": "67",
"name": "Cuttack",
"state": "Odisha"
},
{
"id": "68",
"name": "Kochi",
"state": "Kerala"
},
{
"id": "69",
"name": "Udaipur",
"state": "Rajasthan"
},
{
"id": "70",
"name": "Bhavnagar",
"state": "Gujarat"
},
{
"id": "71",
"name": "Dehradun",
"state": "Uttarakhand"
},
{
"id": "72",
"name": "Asansol",
"state": "West Bengal"
},
{
"id": "73",
"name": "Nanded-Waghala",
"state": "Maharashtra"
},
{
"id": "74",
"name": "Ajmer",
"state": "Rajasthan"
},
{
"id": "75",
"name": "Jamnagar",
"state": "Gujarat"
},
{
"id": "76",
"name": "Ujjain",
"state": "Madhya Pradesh"
},
{
"id": "77",
"name": "Sangli",
"state": "Maharashtra"
},
{
"id": "78",
"name": "Loni",
"state": "Uttar Pradesh"
},
{
"id": "79",
"name": "Jhansi",
"state": "Uttar Pradesh"
},
{
"id": "80",
"name": "Pondicherry",
"state": "Puducherry"
},
{
"id": "81",
"name": "Nellore",
"state": "Andhra Pradesh"
},
{
"id": "82",
"name": "Jammu",
"state": "Jammu and Kashmir"
},
{
"id": "83",
"name": "Belagavi",
"state": "Karnataka"
},
{
"id": "84",
"name": "Raurkela",
"state": "Odisha"
},
{
"id": "85",
"name": "Mangaluru",
"state": "Karnataka"
},
{
"id": "86",
"name": "Tirunelveli",
"state": "Tamil Nadu"
},
{
"id": "87",
"name": "Malegaon",
"state": "Maharashtra"
},
{
"id": "88",
"name": "Gaya",
"state": "Bihar"
},
{
"id": "89",
"name": "Tiruppur",
"state": "Tamil Nadu"
},
{
"id": "90",
"name": "Davanagere",
"state": "Karnataka"
},
{
"id": "91",
"name": "Kozhikode",
"state": "Kerala"
},
{
"id": "92",
"name": "Akola",
"state": "Maharashtra"
},
{
"id": "93",
"name": "Kurnool",
"state": "Andhra Pradesh"
}
]
\ No newline at end of file
import React, { Fragment } from "react";
// import cities from "../../cities.json";
import users from "../../users.json";
const Home = () => {
// console.log(users);
// myAPIData()
const MyAPIData = () => {
users.map(mydata => {
return (
<div className="card">
<div className="content-section">
<h1>{mydata.first_name}</h1>
<p>{mydata.last_name}</p>
<p>{mydata.email}</p>
<div className="icon-group">
<span>F</span>
<span>T</span>
<span>I</span>
<span>Y</span>
</div>
<div className="btn-group">
<button>Message</button>
<button>Subscribe</button>
</div>
<div className="another-group">
<div>
<h3>20.4K</h3>
</div>
<div>
<h3>14.3K</h3>
</div>
<div>
<h3>12.8K</h3>
</div>
</div>
</div>
</div>
);
});
};
// console.log(users);
return (
<Fragment>
<main>
<div className="body-xyz">
{/* <MyAPIData /> */}
<div>Hello world!</div>
</div>
</main>
</Fragment>
);
};
export default Home;
import React from "react";
const ButtonLoader = () => {
return <div className="lds-dual-ring"></div>;
};
export default ButtonLoader;
import React from "react";
const Footer = () => {
return <footer className="py-1">
<div>
footer
</div>
</footer>;
};
export default Footer;
import { getSession, signOut } from "next-auth/react";
import Image from "next/image";
import Link from "next/link";
import React, { useEffect, useState } from "react";
import { useSelector } from "react-redux";
import { cleanImage } from "../../services/imageHandling";
const Header = () => {
return (
<header>
<div>
Header
</div>
</header>
);
};
export default Header;
import React from "react";
import Head from "next/head";
import Header from "./Header";
import Footer from "./Footer";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const Layout = ({ children, title = "", description = "" }) => {
return (
<div>
<Head>
<title>{title}</title>
<meta charSet="utf-8"></meta>
<meta name="viewport" content="initial-scale=1.0,width=device-width" />
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
</Head>
<Header></Header>
<ToastContainer position="bottom-right" />
{children}
<Footer></Footer>
</div>
);
};
export default Layout;
import React from "react";
const Loader = () => {
return (
<div className="lds-ellipsis">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
);
};
export default Loader;
sudo git pull
sudo npm run build
sudo pm2 stop nextapp
sudo pm2 start nextapp
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
env: {
stripePublishableKey: "pk_test_51LeAqWSD8iV80gmAKccLEZAm1mYnjlzkL1cJxWJKFaHEMPzArGRRECPOG64e8GX2Hd112zBq3vQ3xSVb5IZQCRmh00N3DRtRse"
},
images: {
domains: ["hoffersapi.logicloop.io", "hoffers.logicloop.io", "localhost"]
}
};
module.exports = nextConfig;
import "../styles/globals.css";
import { wrapper } from "../redux/store";
import { SessionProvider } from "next-auth/react";
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
return (
<SessionProvider session={session}>
<Component {...pageProps} />
</SessionProvider>
);
}
export default wrapper.withRedux(MyApp);
import Document, { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
class MyDocument extends Document {
static async getInitialProps(ctx) {
// Run the parent `getInitialProps`, it now includes the custom `renderPage`
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps };
}
render() {
return (
<Html lang="en">
<Head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" crossOrigin="anonymous" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx"
crossOrigin="anonymous"
/>
</Head>
<body>
<Main />
<NextScript />
<Script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.5/dist/umd/popper.min.js" crossorigin="anonymous"></Script>
<Script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.min.js" crossorigin="anonymous"></Script>
<Script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></Script>
</body>
</Html>
);
}
}
export default MyDocument;
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import axios from "axios";
/**
* Reference:
* https://next-auth.js.org/
* https://strapi.io/blog/user-authentication-in-next-js-with-strapi
* https://medium.com/@tom555my/strapi-next-js-email-password-authentication-a8207f72b446#id_token=eyJhbGciOiJSUzI1NiIsImtpZCI6IjQwMmYzMDViNzA1ODEzMjlmZjI4OWI1YjNhNjcyODM4MDZlY2E4OTMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2NjE5NDM4MzEsImF1ZCI6IjIxNjI5NjAzNTgzNC1rMWs2cWUwNjBzMnRwMmEyamFtNGxqZGNtczAwc3R0Zy5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjEwMzU4MDUxNzI0MDg5MTg5NDI5OSIsImVtYWlsIjoiaGFyaXNoLnJrLnBhdGVsQGdtYWlsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJhenAiOiIyMTYyOTYwMzU4MzQtazFrNnFlMDYwczJ0cDJhMmphbTRsamRjbXMwMHN0dGcuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJuYW1lIjoiSGFyaXNoIFBhdGVsIiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BRmRadWNxVlFSbE42TUQyeFJDVjhwMThlcXRSSjB0UmZpc2F1T21FeGVodFNnPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkhhcmlzaCIsImZhbWlseV9uYW1lIjoiUGF0ZWwiLCJpYXQiOjE2NjE5NDQxMzEsImV4cCI6MTY2MTk0NzczMSwianRpIjoiZDk1YzIyYzVkMjY1N2NmZWEwN2Q1M2QwMmZkMjY1NGVhMGE4NTA0OSJ9.F4xZZT2ebj3LvtOqFwC-EeneXUVzAEolss20Zz1JYpnWlfDmTAzJkStaXN_3n59X2jhppU2vLX426fihE1sjvfkbSFY3L--uMlGRjKbkKMzlhqppy2TUN1Qcsaqf8PSamLQxZx9Ta3qdmV4FCvf8FLXbiVmgX2KOYg3stitiL3vQpEDR2faAv-dlnaOSDbKU76elKf5VMVHGw9ed7dLeNF0qPRLXg_NrQ3dPBH1sDwfLh0g4elCMkneEtMjZY9ptLJxhc_bwuQpXs3xNwjlIAZA1gM60lhIiZESwlAnnpEBdIjPVsjoUeJEEM1bB8dP4hqndJPVwA80ZnqOOXiH8bQ
*/
export default NextAuth({
// Configure one or more authentication providers
providers: [
CredentialsProvider({
name: "Sign in with Email",
credentials: {
email: { label: "Email", type: "text" },
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
/**
* This function is used to define if the user is authenticated or not.
* If authenticated, the function should return an object contains the user data.
* If not, the function should return `null`.
*/
if (credentials == null) return null;
const { email, password } = credentials;
// Check if email and password is specified.
if (!email || !password) {
throw new Error("Please enter email and password to login.");
}
/**
* credentials is defined in the config above.
* We can expect it contains two properties: `email` and `password`
*/
try {
const {
data: { user, jwt }
} = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
identifier: email,
password: password
});
// console.log("Axios login returned with data:");
// console.log(user);
// console.log(jwt);
// Response from the above call can be
// 1. Incase of a successful authentication.
// {
// "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NCwiaWF0IjoxNjYxOTQzMzY1LCJleHAiOjE2NjQ1MzUzNjV9.kAN2ocQEqbjbR_-6-ogfZMplJIn1VHkCn3hoAW4QtmY",
// "user": {
// "id": 4,
// "username": "harish",
// "email": "harish@email.com",
// "provider": "local",
// "confirmed": true,
// "blocked": false,
// "createdAt": "2022-08-30T06:38:17.280Z",
// "updatedAt": "2022-08-31T10:03:59.430Z"
// }
// }
// 2. Incase of an invalid authentication.
// {
// "data": null,
// "error": {
// "status": 400,
// "name": "ValidationError",
// "message": "Invalid identifier or password",
// "details": {}
// }
// }
return { ...user, name: user.username, jwt };
} catch (error) {
console.log("Error while fetching credentials:");
console.log(error.response.data);
// Sign In Fail
// return null;
throw new Error(error.response.data.error.message);
}
}
})
],
callbacks: {
session: async ({ session, token }) => {
session.id = token.id;
session.jwt = token.jwt;
// console.log("session callback invoked: ");
// console.log(session);
return Promise.resolve(session);
},
jwt: async ({ token, user }) => {
const isSignIn = user ? true : false;
if (isSignIn) {
token.id = user.id;
token.jwt = user.jwt;
}
// console.log("jwt callback invoked: ");
// console.log(token);
return Promise.resolve(token);
}
}
});
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}
import Home from "../components/home/Home";
import Layout from "../components/layout/Layout";
import { wrapper } from "../redux/store";
export default function IndexPage() {
/** Client side rendering, traditional API call. */
// const dispatch = useDispatch();
// useEffect(() => {
// const fetchData = async () => {
// await dispatch(getProjects({ currentPage: 1, featuredOnHome: true }));
// };
// fetchData();
// });
return (
<Layout>
<Home />
</Layout>
);
}
/** For server side rendering */
export const getServerSideProps = wrapper.getServerSideProps(store => async ({ req, query }) => {
// Get the menu data.
// get the locations data.
return {
props: {}
};
});
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
This diff could not be displayed because it is too large.
No preview for this file type
No preview for this file type
No preview for this file type
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
</svg>
\ No newline at end of file
import axios from "axios";
import { FETCH_BANKING_PARTNERS_SUCCESS, FETCH_BANKING_PARTNERS_FAIL, CLEAR_ERRORS } from "../constants/bankingPartnersConstants";
import qs from "qs";
// Get room details
export const getBankingPartners = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["logo"],
sort: ["serialNumber:desc"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/banking-partners?${query}`, config);
dispatch({
type: FETCH_BANKING_PARTNERS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("getBankingPartners:");
console.log(error.response.data);
dispatch({
type: FETCH_BANKING_PARTNERS_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { BOOKING_DETAILS_SUCCESS, BOOKING_DETAILS_FAIL, FETCH_MY_BOOKINGS_SUCCESS, FETCH_MY_BOOKINGS_FAIL, CLEAR_ERRORS } from "../constants/bookingConstants";
import qs from "qs";
// Fetch room booked dates.
export const fetchMyBookings = session => async dispatch => {
// Note, when an action is going to be triggered on the server side, like this one is.
// then we cannot expect getSession() to give usa valid session, we need to instead use getSession({ req })
// and give it a req object instead.
// This action gets called from getServerSideProps on the me.js file.
// Hence here we have taken the session object from outside, instead of using getSession().
// Unlike a few other actions where we might have ended up using getSession directly, those actions like the loadUser & updateUser actions
// are all triggered on the UI using useEffect and from a submitHandler respectively.
if (!session) {
throw new Error("You are not authenticated currently. Only authenticated users can fetch their own bookings.");
}
try {
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session.jwt}`
}
};
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/my-bookings`, config);
dispatch({
type: FETCH_MY_BOOKINGS_SUCCESS,
payload: response.data.bookings
});
} catch (error) {
dispatch({
type: FETCH_MY_BOOKINGS_FAIL,
payload: error.response.data
});
}
};
// Get room details
export const getBookingDetails = (bookingId, session) => async dispatch => {
// const session = await getSession();
if (!session) {
throw new Error("You are not authenticated currently. Only authenticated users can fetch their own bookings.");
}
try {
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session.jwt}`
}
};
const query = qs.stringify(
{
populate: {
room: {
populate: ["images"]
},
user: {
populate: ["*"]
}
}
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/bookings/${bookingId}?${query}`, config);
dispatch({
type: BOOKING_DETAILS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("getBookingDetails:");
console.log(error.response.data);
dispatch({
type: BOOKING_DETAILS_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { FETCH_COMPANY_INFORMATION_SUCCESS, FETCH_COMPANY_INFORMATION_FAIL, CLEAR_ERRORS } from "../constants/companyInformationConstants";
import qs from "qs";
// Get room details
export const getCompanyInformation = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["logo"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/company-information?${query}`, config);
dispatch({
type: FETCH_COMPANY_INFORMATION_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while fetching company information");
console.log(error);
// console.log(error.response.data);
dispatch({
type: FETCH_COMPANY_INFORMATION_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { CLEAR_ERRORS, CONTACT_US_SUBMIT_FAIL, CONTACT_US_SUBMIT_REQUEST, CONTACT_US_SUBMIT_SUCCESS } from "../constants/contactUsConstants";
export const postContactUsDetails = contactUsData => async dispatch => {
try {
dispatch({
type: CONTACT_US_SUBMIT_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
const response = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/leads`,
{
data: {
fullName: contactUsData?.fullName,
email: contactUsData?.emailAddress,
mobileNumber: contactUsData?.mobileNumber,
project: contactUsData?.projects,
comments: contactUsData?.comments
}
},
config
);
dispatch({
type: CONTACT_US_SUBMIT_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while submitting referral details: ");
console.log(error);
dispatch({
type: CONTACT_US_SUBMIT_FAIL,
payload: error.response.data
});
}
};
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
\ No newline at end of file
import axios from "axios";
import { FETCH_CP_CONNECT_PAGE_SUCCESS, FETCH_CP_CONNECT_PAGE_FAIL, CLEAR_ERRORS } from "../constants/cpConnectPageConstants";
import qs from "qs";
// Get room details
export const getCPConnectPage = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["banner"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/cp-connect-page?${query}`, config);
dispatch({
type: FETCH_CP_CONNECT_PAGE_SUCCESS,
payload: response.data
});
} catch (error) {
console.log(error.response.data);
dispatch({
type: FETCH_CP_CONNECT_PAGE_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { CLEAR_ERRORS } from "../constants/cpLoginConstants";
export const finishChannelPartnerOtpLogin = async ({ mobileNumber, mahareraNumber, oneTimePassword }) => {
// 1. invoke the api to start the login with otp process.
const config = {
headers: {
"Content-Type": "application/json"
}
};
return await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users-permissions/users/channel-partner/finish-otp-login`,
{
mobileNumber,
mahareraNumber,
oneTimePassword
},
config
);
};
export const startChannelPartnerOtpLogin = async ({ mobileNumber, mahareraNumber }) => {
// 1. invoke the api to start the login with otp process.
const config = {
headers: {
"Content-Type": "application/json"
}
};
const startOtpLoginResponse = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users-permissions/users/channel-partner/start-otp-login`,
{
mobileNumber,
mahareraNumber
},
config
);
return startOtpLoginResponse;
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import { FETCH_DETAILS_FAIL, FETCH_DETAILS_SUCCESS, CLEAR_ERRORS } from "../constants/detailsConstants";
import axios from "axios";
import qs from "qs";
export const getDetails = detailsId => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["image"],
sort: ["serialNumber:desc"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/projects/${detailsId}?${query}`, config);
dispatch({
type: FETCH_DETAILS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while fetching Project details: ");
console.log(error.response.data);
dispatch({
type: FETCH_DETAILS_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import qs from "qs";
export const finishEndUserOtpLogin = async ({ mobileNumber, emailAddress, oneTimePassword }) => {
// 1. invoke the api to start the login with otp process.
const config = {
headers: {
"Content-Type": "application/json"
}
};
return await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users-permissions/users/end-user/finish-otp-login`,
{
mobileNumber,
emailAddress,
oneTimePassword
},
config
);
};
export const startEndUserOtpLogin = async ({ mobileNumber, emailAddress }) => {
// 1. invoke the api to start the login with otp process.
const config = {
headers: {
"Content-Type": "application/json"
}
};
const startOtpLoginResponse = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users-permissions/users/end-user/start-otp-login`,
{
mobileNumber,
emailAddress
},
config
);
return startOtpLoginResponse;
};
import { TOGGLE_DISPLAY_ENQUIRE_NOW_MODAL } from "../constants/enquireNowModalConstants";
export const setDisplayEnquireNowAction = displayEnquireNow => async dispatch => {
dispatch({
type: TOGGLE_DISPLAY_ENQUIRE_NOW_MODAL,
payload: displayEnquireNow
});
};
import axios from "axios";
import { CLEAR_ERRORS, ENQUIRY_SUBMIT_FAIL, ENQUIRY_SUBMIT_REQUEST, ENQUIRY_SUBMIT_SUCCESS } from "../constants/enquiryConstants";
export const postEnqiryDetails = enquiryData => async dispatch => {
try {
dispatch({
type: ENQUIRY_SUBMIT_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
const response = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/leads`,
{
data: {
fullName: enquiryData.fullName,
mobileNumber: enquiryData.mobileNumber,
email: enquiryData.email,
projects: enquiryData.projects,
comments: enquiryData.comments
}
},
config
);
dispatch({
type: ENQUIRY_SUBMIT_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while submitting enquiry details: ");
console.log(error);
dispatch({
type: ENQUIRY_SUBMIT_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { FETCH_HOME_BANNERS_SUCCESS, FETCH_HOME_BANNERS_FAIL, CLEAR_ERRORS } from "../constants/homeBannerConstants";
import qs from "qs";
// Get room details
export const getHomeBanners = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["image"],
sort: ["serialNumber:desc"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/home-banners?${query}`, config);
dispatch({
type: FETCH_HOME_BANNERS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while fetching home banners: ");
console.log(error.response.data);
dispatch({
type: FETCH_HOME_BANNERS_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { FETCH_HOME_CONTENT_SUCCESS, FETCH_HOME_CONTENT_FAIL, CLEAR_ERRORS } from "../constants/homeContentConstants";
import qs from "qs";
// Get room details
export const getHomeContent = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["image1", "image2", "image3"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/home-content?${query}`, config);
dispatch({
type: FETCH_HOME_CONTENT_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("getHomeContent:");
console.log(error.response.data);
dispatch({
type: FETCH_HOME_CONTENT_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { FETCH_HOME_DELIVERY_STATS_FAIL, FETCH_HOME_DELIVERY_STATS_SUCCESS, CLEAR_ERRORS } from "../constants/homeDeliveryStatsConstants";
import qs from "qs";
export const getHomeDeliveryStats = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
populate: ["backgroundImage"]
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/delivery-stat?${query}`, config);
dispatch({
type: FETCH_HOME_DELIVERY_STATS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while fetching delivery stats");
console.log(error.response.data);
dispatch({
type: FETCH_HOME_DELIVERY_STATS_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import { FETCH_LOCATIONS_SUCCESS, FETCH_LOCATIONS_FAIL, CLEAR_ERRORS } from "../constants/locationsConstants";
import qs from "qs";
// Get room details
export const getLocations = () => async dispatch => {
try {
const config = {
headers: {
"Content-Type": "application/json"
}
};
const query = qs.stringify(
{
filters: {},
populate: [],
pagination: {
pageSize: 100,
page: 1
}
},
{
encodeValuesOnly: true // prettify URL
}
);
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/locations?${query}`, config);
dispatch({
type: FETCH_LOCATIONS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while locations: ");
console.log(error);
dispatch({
type: FETCH_LOCATIONS_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import qs from "qs";
import { FETCH_MENU_ITEMS_REQUEST, FETCH_MENU_ITEMS_SUCCESS, FETCH_MENU_ITEMS_FAIL, CLEAR_ERRORS } from "../constants/menuItemsConstants";
export const getMenuItems =
({ menu = "Main", published = true }) =>
async dispatch => {
const fmir = `${FETCH_MENU_ITEMS_REQUEST}_${menu.toUpperCase()}`;
const fmis = `${FETCH_MENU_ITEMS_SUCCESS}_${menu.toUpperCase()}`;
const fmif = `${FETCH_MENU_ITEMS_FAIL}_${menu.toUpperCase()}`;
const ce = `${CLEAR_ERRORS}_${menu.toUpperCase()}`;
try {
dispatch({
type: fmir
});
const itemsPerPage = 100;
const query = {
filters: {
menu: {
name: {
$eq: menu
}
}
},
populate: ["parent"],
pagination: {
pageSize: itemsPerPage,
page: 1
},
sort: ['serialNumber:asc'],
// fields: ['title'],
// publicationState: 'live',
// locale: ['en'],
publicationState: published ? "live" : "preview"
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/menu-items?${queryString}`);
dispatch({
type: fmis,
payload: response.data
});
} catch (error) {
console.log("Error while fetching menu items: ");
console.log(error.response.data);
dispatch({
type: fmif,
payload: error.response.data
});
}
};
import axios from "axios";
import qs from "qs";
import {
FETCH_PROJECTS_REQUEST,
FETCH_PROJECTS_SUCCESS,
FETCH_PROJECTS_FAIL,
FETCH_PROJECT_REQUEST,
FETCH_PROJECT_SUCCESS,
FETCH_PROJECT_FAIL,
CLEAR_ERRORS,
FETCH_SIMILAR_PROJECTS_REQUEST,
FETCH_SIMILAR_PROJECTS_SUCCESS,
FETCH_SIMILAR_PROJECTS_FAIL
} from "../constants/projectsConstants";
export const getProjects =
({
loadedFrom = "home",
currentPage = 1,
resultsPerPage = 6,
featuredOnHome = null,
townshipId = null,
locationId = null,
projectType = null,
configuration = null,
published = true
}) =>
async dispatch => {
try {
// dispatch({
// type: published ? PUBLISHED_ROOMS_REQUEST : ADMIN_ROOMS_REQUEST
// });
dispatch({
type: FETCH_PROJECTS_REQUEST
});
const query = {
filters: {},
populate: ["projectImages", "projectImages.image", "location", "township"],
pagination: {
pageSize: resultsPerPage,
page: currentPage
},
// sort: ['title:asc'],
// fields: ['title'],
// publicationState: 'live',
// locale: ['en'],
publicationState: published ? "live" : "preview"
};
// Add all the optional filters.
if (featuredOnHome) query.filters["featuredOnHome"] = { $eq: featuredOnHome };
if (townshipId) query.filters["township"] = { id: { $eq: townshipId } };
if (locationId) query.filters["location"] = { id: { $eq: locationId } };
if (projectType) query.filters["projectType"] = { $eq: projectType };
if (configuration) {
query.filters["configurations"] = { bedrooms: { $in: Number(configuration) } };
}
/** If we are loading projects from anywhere other than the home page, then we load the configuration information also. */
if (loadedFrom !== "listing") {
query.populate.push("configurations");
}
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const endpoint = `${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/projects?${queryString}`;
console.log(`Final url: ${endpoint}`);
const response = await axios.get(endpoint);
dispatch({
// type: published ? PUBLISHED_ROOMS_SUCCESS : ADMIN_ROOMS_SUCCESS,
type: FETCH_PROJECTS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Real error is: ");
console.log(error.response.data);
dispatch({
// type: published ? PUBLISHED_ROOMS_FAIL : ADMIN_ROOMS_FAIL,
type: FETCH_PROJECTS_FAIL,
payload: error.response.data
});
}
};
export const getProject = projectId => async dispatch => {
try {
dispatch({
type: FETCH_PROJECT_REQUEST
});
const query = {
filters: {},
populate: ["projectImages", "projectImages.image", "location", "township","township.amenities","township.amenities.icon", "configurations","configurations.unitPlanImages","configurations.unitPlanImages.image", "amenities", "amenities.icon", "floorPlanImages.image","masterPlanImages.image"],
pagination: {}
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/projects/${projectId}?${queryString}`);
dispatch({
// type: published ? PUBLISHED_ROOMS_SUCCESS : ADMIN_ROOMS_SUCCESS,
type: FETCH_PROJECT_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Real error is: ");
console.log(error.response.data);
dispatch({
// type: published ? PUBLISHED_ROOMS_FAIL : ADMIN_ROOMS_FAIL,
type: FETCH_PROJECT_FAIL,
payload: error.response.data
});
}
};
export const getSimilarProjects = (townshipId, noOfBeds) => async dispatch => {
try {
dispatch({
type: FETCH_SIMILAR_PROJECTS_REQUEST
});
const query = {
filters: {
configurations: {
bedrooms: {
$in: noOfBeds
}
}
},
populate: ["projectImages", "projectImages.image", "location", "township", "configurations"],
pagination: {}
};
if (townshipId) query.filters["township"] = { id: { $eq: townshipId}};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/projects?${queryString}`);
dispatch({
// type: published ? PUBLISHED_ROOMS_SUCCESS : ADMIN_ROOMS_SUCCESS,
type: FETCH_SIMILAR_PROJECTS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Real error is: ");
console.log(error.response.data);
dispatch({
// type: published ? PUBLISHED_ROOMS_FAIL : ADMIN_ROOMS_FAIL,
type: FETCH_SIMILAR_PROJECTS_FAIL,
payload: error.response.data
});
}
};
import axios from "axios";
import { REFERRAL_SUBMIT_FAIL, REFERRAL_SUBMIT_REQUEST, REFERRAL_SUBMIT_SUCCESS, CLEAR_ERRORS } from "../constants/referralConstants";
export const postReferralDetails = referralData => async dispatch => {
try {
dispatch({
type: REFERRAL_SUBMIT_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
const response = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/referrals`,
{
data: {
fullName: referralData.fullName,
township: referralData.township,
mobileNumber: referralData.mobileNo,
project: referralData.building,
email: referralData.email,
wing: referralData.wing,
flatNumber: referralData.flatNo,
ownershipType: referralData.ownershipType,
purchasedYear: referralData.purchasedYear,
purchasedSource: referralData.purchasedSource,
referralName: referralData.referralName,
referralPhoneNo: referralData.referralMobileNo,
referralEmail: referralData.referralEmail,
projectReferredTo: referralData.projectReferredTo
}
},
config
);
dispatch({
type: REFERRAL_SUBMIT_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while submitting referral details: ");
console.log(error);
dispatch({
type: REFERRAL_SUBMIT_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import qs from "qs";
import {
ROOM_CHECK_AVAILABILITY_REQUEST,
ROOM_CHECK_AVAILABILITY_SUCCESS,
ROOM_CHECK_AVAILABILITY_RESET,
ROOM_CHECK_AVAILABILITY_FAIL,
ROOM_MAKE_REVIEW_REQUEST,
ROOM_MAKE_REVIEW_SUCCESS,
ROOM_MAKE_REVIEW_RESET,
ROOM_MAKE_REVIEW_FAIL,
ROOM_FETCH_BOOKED_DATES_SUCCESS,
ROOM_FETCH_BOOKED_DATES_FAIL,
ALL_ROOMS_FAIL,
ALL_ROOMS_SUCCESS,
ROOM_DETAILS_SUCCESS,
ROOM_DETAILS_FAIL,
CLEAR_ERRORS
} from "../constants/roomConstants";
import { getSession } from "next-auth/react";
// Get all rooms
export const getRooms =
(currentPage = 1, location = "", guests, category) =>
async dispatch => {
try {
const roomsPerPage = 4;
const query = {
filters: {
address: {
$contains: location
}
},
populate: ["images"],
pagination: {
pageSize: roomsPerPage,
page: currentPage
}
// sort: ['title:asc'],
// fields: ['title'],
// publicationState: 'live',
// locale: ['en'],
};
// Add all the optional filters.
if (guests) query.filters["guestCapacity"] = { $eq: guests };
if (category) query.filters["category"] = { $eq: category };
const queryString = qs.stringify(query, {
encodeValuesOnly: true // prettify URL
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/rooms?${queryString}`);
dispatch({
type: ALL_ROOMS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Real error is: ");
console.log(error);
dispatch({
type: ALL_ROOMS_FAIL,
payload: error.response.data
});
}
};
// Get room details
export const getRoomDetails = roomId => async dispatch => {
try {
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/rooms/${roomId}?populate[0]=images`);
dispatch({
type: ROOM_DETAILS_SUCCESS,
payload: response.data
});
} catch (error) {
dispatch({
type: ROOM_DETAILS_FAIL,
payload: error.response.data
});
}
};
// Check for room availability
export const checkRoomAvailability = (roomId, checkInDate, checkOutDate) => async dispatch => {
try {
dispatch({
type: ROOM_CHECK_AVAILABILITY_REQUEST
});
const response = await axios.get(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/rooms/check-availability?roomId=${roomId}&checkInDate=${checkInDate}&checkOutDate=${checkOutDate}`
);
dispatch({
type: ROOM_CHECK_AVAILABILITY_SUCCESS,
payload: response.data
});
} catch (error) {
// console.log("Error while check room availability");
// console.log(error);
dispatch({
type: ROOM_CHECK_AVAILABILITY_FAIL,
payload: error.response.data
});
}
};
// Fetch room booked dates.
export const fetchRoomBookedDates = roomId => async dispatch => {
try {
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/rooms/fetch-booked-dates?roomId=${roomId}`);
dispatch({
type: ROOM_FETCH_BOOKED_DATES_SUCCESS,
payload: response.data
});
} catch (error) {
dispatch({
type: ROOM_FETCH_BOOKED_DATES_FAIL,
payload: error.response.data
});
}
};
// update profile.
export const makeReview = reviewData => async dispatch => {
const session = await getSession();
if (!session) {
throw new Error("You need to be logged in before creating a review.");
}
try {
dispatch({
type: ROOM_MAKE_REVIEW_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session.jwt}`
}
};
const response = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/rooms/reviews`,
{
rating: reviewData.rating,
comment: reviewData.comment,
roomId: reviewData.roomId
},
config
);
dispatch({
type: ROOM_MAKE_REVIEW_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while making a review: ");
console.log(error);
dispatch({
type: ROOM_MAKE_REVIEW_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
import axios from "axios";
import qs from "qs";
import {
FETCH_TOWNSHIPS_REQUEST,
FETCH_TOWNSHIPS_SUCCESS,
FETCH_TOWNSHIPS_FAIL,
FETCH_TOWNSHIP_REQUEST,
FETCH_TOWNSHIP_SUCCESS,
FETCH_TOWNSHIP_FAIL,
CLEAR_ERRORS
} from "../constants/townshipsConstants";
export const getTownships =
({ currentPage = 1, resultsPerPage = 3, published = true }) =>
async dispatch => {
try {
dispatch({
type: FETCH_TOWNSHIPS_REQUEST
});
const query = {
filters: {},
populate: ["townshipImages", "townshipImages.image", "location"],
pagination: {
pageSize: resultsPerPage,
page: currentPage
},
publicationState: published ? "live" : "preview"
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/townships?${queryString}`);
dispatch({
type: FETCH_TOWNSHIPS_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Real error is: ");
console.log(error.response.data);
dispatch({
type: FETCH_TOWNSHIPS_FAIL,
payload: error.response.data
});
}
};
export const getTownship = townshipId => async dispatch => {
try {
dispatch({
type: FETCH_TOWNSHIP_REQUEST
});
const query = {
// filters: {},
populate: ["townshipImages", "townshipImages.image", "location","cpGuidelines"]
// pagination: {
// pageSize: resultsPerPage,
// page: currentPage
// },
// publicationState: published ? "live" : "preview"
};
const queryString = qs.stringify(query, {
encodeValuesOnly: true
});
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/townships/${townshipId}?${queryString}`);
dispatch({
type: FETCH_TOWNSHIP_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Real error is: ");
// console.log(error.response.data);
console.log(error);
dispatch({
type: FETCH_TOWNSHIP_FAIL,
payload: error.response.data
});
}
};
import {
LOAD_USER_REQUEST,
LOAD_USER_SUCCESS,
LOAD_USER_FAIL,
FORGOT_PASSWORD_REQUEST,
FORGOT_PASSWORD_SUCCESS,
FORGOT_PASSWORD_FAIL,
RESET_PASSWORD_REQUEST,
RESET_PASSWORD_SUCCESS,
RESET_PASSWORD_FAIL,
UPDATE_USER_PROFILE_REQUEST,
UPDATE_USER_PROFILE_SUCCESS,
UPDATE_USER_PROFILE_FAIL,
REGISTER_USER_REQUEST,
REGISTER_USER_SUCCESS,
REGISTER_USER_FAIL,
CLEAR_ERRORS
} from "../constants/userConstants";
import axios from "axios";
import { getSession } from "next-auth/react";
// register a new user.
export const registerUser = userData => async dispatch => {
try {
dispatch({
type: REGISTER_USER_REQUEST
});
// 1. # # # # # # # # # # # # #
// First save the main user record.
const config = {
headers: {
"Content-Type": "multipart/form-data"
}
};
const userFormData = new FormData();
userFormData.append("username", userData.username);
userFormData.append("email", userData.email);
userFormData.append("password", userData.password);
userFormData.append("role", userData.role);
const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local/register`, userFormData, config);
console.log(`Register user done:`);
console.log(response);
// Immediately after user creation based on the role of the user we need to create entry into the corresponding extension table.
if (userData.role === "Channel Partner") {
userData["userId"] = response.data.user.id;
await registerChannelPartner(userData);
}
if (userData.role === "End User") {
userData["userId"] = response.data.user.id;
await registerEndUser(userData);
}
console.log(`About to dispatch REGISTER_USER_SUCCESS`);
dispatch({
type: REGISTER_USER_SUCCESS
});
} catch (error) {
console.log("Error while registering a user: ");
console.log(error);
dispatch({
type: REGISTER_USER_FAIL,
payload: error.response.data
});
}
};
// register a new user.
export const loadUser = () => async dispatch => {
const session = await getSession();
if (session) {
try {
dispatch({
type: LOAD_USER_REQUEST
});
const config = {
headers: {
Authorization: `Bearer ${session.jwt}`
}
};
// Load the user.
const response = await axios.get(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users/me?populate[0]=profileImage`, config);
dispatch({
type: LOAD_USER_SUCCESS,
payload: { ...response.data }
});
} catch (error) {
console.log("Error while loading a user: ");
console.log(error);
dispatch({
type: LOAD_USER_FAIL,
payload: error.response.data
});
}
}
};
// update profile.
export const updateUserProfile = userData => async dispatch => {
const session = await getSession();
if (!session) {
throw new Error("You are not authenticated currently. Only authenticated users can update their own profile.");
}
try {
dispatch({
type: UPDATE_USER_PROFILE_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${session.jwt}`
}
};
const response = await axios.put(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/users-permissions/users/me`,
{
password: userData.password,
fullName: userData.fullName,
aboutMe: userData.aboutMe
},
config
);
const profileImageFormData = new FormData();
profileImageFormData.append("field", "profileImage");
profileImageFormData.append("ref", "plugin::users-permissions.user");
profileImageFormData.append("refId", response.data.id);
profileImageFormData.append("files", userData.avatarFiles[0]);
const profileImageUploadResponse = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/upload`, profileImageFormData, {
headers: {
Authorization: `Bearer ${session.jwt}`
}
});
// console.log("Profile image update response:");
// console.log(profileImageUploadResponse);
dispatch({
type: UPDATE_USER_PROFILE_SUCCESS,
payload: response.data
});
} catch (error) {
console.log("Error while updating a user profile: ");
console.log(error);
dispatch({
type: UPDATE_USER_PROFILE_FAIL,
payload: error.response.data
});
}
};
// forgot password.
export const forgotPassword = email => async dispatch => {
try {
dispatch({
type: FORGOT_PASSWORD_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
const response = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/forgot-password`,
{
email
},
config
);
dispatch({
type: FORGOT_PASSWORD_SUCCESS,
payload: response.data.ok ? "Please check your inbox for instructions to reset your password." : "Error generating reset password link"
});
} catch (error) {
console.log("Error while generating password reset link: ");
console.log(error);
dispatch({
type: FORGOT_PASSWORD_FAIL,
payload: error.response.data
});
}
};
// reset password.
export const resetPassword = (code, password, passwordConfirmation) => async dispatch => {
try {
dispatch({
type: RESET_PASSWORD_REQUEST
});
const config = {
headers: {
"Content-Type": "application/json"
}
};
const response = await axios.post(
`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/reset-password`,
{
code,
password,
passwordConfirmation
},
config
);
const { user, jwt } = response.data;
dispatch({
type: RESET_PASSWORD_SUCCESS,
payload: jwt ? "Password reset successfully." : "Error while resetting password."
});
} catch (error) {
console.log("Error while resetting password: ");
console.log(error);
dispatch({
type: RESET_PASSWORD_FAIL,
payload: error.response.data
});
}
};
// Clear errors
export const clearErrors = () => async dispatch => {
dispatch({
type: CLEAR_ERRORS
});
};
/** Channel partner record to be created alongwith user creation. */
/** This is an internal utility method which creates a CP when a user is created. */
const registerChannelPartner = async channelPartnerData => {
const {
data: { user, jwt }
} = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
identifier: channelPartnerData.email,
password: channelPartnerData.password
});
// First save the main cp record.
const config = {
headers: {
Authorization: `Bearer ${jwt}`,
"Content-Type": "application/json"
}
};
const cpData = {
data: {
companyName: channelPartnerData.companyName,
companyType: channelPartnerData.companyType,
contactPersonName: channelPartnerData.contactPersonName,
email: channelPartnerData.email,
communicationAddress: channelPartnerData.communicationAddress,
mobileNo: channelPartnerData.mobileNo,
city: channelPartnerData.city,
state: channelPartnerData.state,
reraNumber: channelPartnerData.reraNumber,
regionOfOperation: channelPartnerData.regionOfOperation,
sourcingManager: channelPartnerData.sourcingManager,
pan: channelPartnerData.pan,
memberOf: channelPartnerData.memberOf,
termsAndConditions: channelPartnerData.termsAndConditions,
/** userId is added after user is created in the registerUser method. */
user: channelPartnerData.userId,
publishedAt: null
}
};
const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/channel-partners`, cpData, config);
// Immediately after cp creation we can now go ahead and login with this user to generate a token, and use that to upload the image.
if (channelPartnerData.panFile && channelPartnerData.panFile.length !== 0) {
const panFileFormData = new FormData();
panFileFormData.append("field", "panFile");
panFileFormData.append("ref", "api::channel-partner.channel-partner");
panFileFormData.append("refId", response.data.data.id);
panFileFormData.append("files", channelPartnerData.panFile[0]);
await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/upload`, panFileFormData, {
headers: {
Authorization: `Bearer ${jwt}`,
"Content-Type": "multipart/form-data"
}
});
}
};
/** End user record to be created alongwith user creation. */
/** This is an internal utility method which creates a end user when a user is created. */
const registerEndUser = async euData => {
const {
data: { user, jwt }
} = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/auth/local`, {
identifier: euData.email,
password: euData.password
});
// First save the main cp record.
const config = {
headers: {
Authorization: `Bearer ${jwt}`,
"Content-Type": "application/json"
}
};
const endUserData = {
data: {
mobileNo: euData.mobileNo,
fullName: euData.fullName,
whatsappAccepted: euData.whatsappAccepted,
email: euData.email,
/** userId is added after user is created in the registerUser method. */
user: euData.userId,
publishedAt: null
}
};
const response = await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/end-users`, endUserData, config);
};
/** End user record to be created alongwith user creation. */
/** This is an internal utility method which creates a end user when a user is created. */
export const finishEndUserOtpVerification = async verificationData => {
// First save the main cp record.
const config = {
headers: {
"Content-Type": "application/json"
}
};
return await axios.post(`${process.env.NEXT_PUBLIC_BACKEND_API_URL}/api/end-users/finish-otp-verification`, verificationData, config);
};
export const FETCH_BANKING_PARTNERS_SUCCESS = "FETCH_BANKING_PARTNERS_SUCCESS";
export const FETCH_BANKING_PARTNERS_FAIL = "FETCH_BANKING_PARTNERS_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_MY_BOOKINGS_SUCCESS = "FETCH_MY_BOOKINGS_SUCCESS";
export const FETCH_MY_BOOKINGS_FAIL = "FETCH_MY_BOOKINGS_FAIL";
export const BOOKING_DETAILS_SUCCESS = "BOOKING_DETAILS_SUCCESS";
export const BOOKING_DETAILS_FAIL = "BOOKING_DETAILS_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_COMPANY_INFORMATION_SUCCESS = "FETCH_COMPANY_INFORMATION_SUCCESS";
export const FETCH_COMPANY_INFORMATION_FAIL = "FETCH_COMPANY_INFORMATION_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const CONTACT_US_SUBMIT_REQUEST = "CONTACT_US_SUBMIT_REQUEST";
export const CONTACT_US_SUBMIT_SUCCESS = "CONTACT_US_SUBMIT_SUCCESS";
export const CONTACT_US_SUBMIT_FAIL = "CONTACT_US_SUBMIT_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_CP_CONNECT_PAGE_SUCCESS = "FETCH_CP_CONNECT_PAGE_SUCCESS";
export const FETCH_CP_CONNECT_PAGE_FAIL = "FETCH_CP_CONNECT_PAGE_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const LOGIN_SUCCESS = "LOGIN_SUCCESS";
export const LOGIN_FAIL = "LOGIN_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_DETAILS_SUCCESS = "FETCH_CP_CONNECT_PAGE_SUCCESS";
export const FETCH_DETAILS_FAIL = "FETCH_CP_CONNECT_PAGE_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
/** Plural */
export const TOGGLE_DISPLAY_ENQUIRE_NOW_MODAL = "TOGGLE_DISPLAY_ENQUIRE_NOW_MODAL";
export const ENQUIRY_SUBMIT_REQUEST = "ENQUIRY_SUBMIT_REQUEST";
export const ENQUIRY_SUBMIT_SUCCESS = "ENQUIRY_SUBMIT_SUCCESS";
export const ENQUIRY_SUBMIT_FAIL = "ENQUIRY_SUBMIT_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
// export const TOGGLE_SUCCESS
\ No newline at end of file
export const FETCH_HOME_BANNERS_SUCCESS = "FETCH_HOME_BANNERS_SUCCESS";
export const FETCH_HOME_BANNERS_FAIL = "FETCH_HOME_BANNERS_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_HOME_CONTENT_SUCCESS = "FETCH_HOME_CONTENT_SUCCESS";
export const FETCH_HOME_CONTENT_FAIL = "FETCH_HOME_CONTENT_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_HOME_DELIVERY_STATS_SUCCESS = "FETCH_HOME_DELIVERY_STATS_SUCCESS";
export const FETCH_HOME_DELIVERY_STATS_FAIL = "FETCH_HOME_DELIVERY_STATS_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_LOCATIONS_SUCCESS = "FETCH_LOCATIONS_SUCCESS";
export const FETCH_LOCATIONS_FAIL = "FETCH_LOCATIONS_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_MENU_ITEMS_REQUEST = "FETCH_MENU_ITEMS_REQUEST";
export const FETCH_MENU_ITEMS_SUCCESS = "FETCH_MENU_ITEMS_SUCCESS";
export const FETCH_MENU_ITEMS_FAIL = "FETCH_MENU_ITEMS_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_PROJECTS_REQUEST = "FETCH_PROJECTS_REQUEST";
export const FETCH_PROJECTS_SUCCESS = "FETCH_PROJECTS_SUCCESS";
export const FETCH_PROJECTS_FAIL = "FETCH_PROJECTS_FAIL";
export const FETCH_PROJECT_REQUEST = "FETCH_PROJECT_REQUEST";
export const FETCH_PROJECT_SUCCESS = "FETCH_PROJECT_SUCCESS";
export const FETCH_PROJECT_FAIL = "FETCH_PROJECT_FAIL";
export const FETCH_SIMILAR_PROJECTS_REQUEST = "FETCH_SIMILAR_PROJECTS_REQUEST"
export const FETCH_SIMILAR_PROJECTS_SUCCESS = "FETCH_SIMILAR_PROJECTS_SUCCESS"
export const FETCH_SIMILAR_PROJECTS_FAIL = "FETCH_SIMILAR_PROJECTS_FAIL"
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const REFERRAL_SUBMIT_REQUEST = "REFERRAL_SUBMIT_REQUEST";
export const REFERRAL_SUBMIT_SUCCESS = "REFERRAL_SUBMIT_SUCCESS";
export const REFERRAL_SUBMIT_FAIL = "REFERRAL_SUBMIT_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const ALL_ROOMS_SUCCESS = "ALL_ROOMS_SUCCESS";
export const ALL_ROOMS_FAIL = "ALL_ROOMS_FAIL";
export const ROOM_DETAILS_SUCCESS = "ROOM_DETAILS_SUCCESS";
export const ROOM_DETAILS_FAIL = "ROOM_DETAILS_FAIL";
export const ROOM_CHECK_AVAILABILITY_REQUEST = "ROOM_CHECK_AVAILABILITY_REQUEST";
export const ROOM_CHECK_AVAILABILITY_SUCCESS = "ROOM_CHECK_AVAILABILITY_SUCCESS";
export const ROOM_CHECK_AVAILABILITY_RESET = "ROOM_CHECK_AVAILABILITY_RESET";
export const ROOM_CHECK_AVAILABILITY_FAIL = "ROOM_CHECK_AVAILABILITY_FAIL";
export const ROOM_MAKE_REVIEW_REQUEST = "ROOM_MAKE_REVIEW_REQUEST";
export const ROOM_MAKE_REVIEW_SUCCESS = "ROOM_MAKE_REVIEW_SUCCESS";
export const ROOM_MAKE_REVIEW_RESET = "ROOM_MAKE_REVIEW_RESET";
export const ROOM_MAKE_REVIEW_FAIL = "ROOM_MAKE_REVIEW_FAIL";
export const ROOM_FETCH_BOOKED_DATES_SUCCESS = "ROOM_FETCH_BOOKED_DATES_SUCCESS";
export const ROOM_FETCH_BOOKED_DATES_FAIL = "ROOM_FETCH_BOOKED_DATES_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const FETCH_TOWNSHIPS_REQUEST = "FETCH_TOWNSHIPS_REQUEST";
export const FETCH_TOWNSHIPS_SUCCESS = "FETCH_TOWNSHIPS_SUCCESS";
export const FETCH_TOWNSHIPS_FAIL = "FETCH_TOWNSHIPS_FAIL";
export const FETCH_TOWNSHIP_REQUEST = "FETCH_TOWNSHIP_REQUEST";
export const FETCH_TOWNSHIP_SUCCESS = "FETCH_TOWNSHIP_SUCCESS";
export const FETCH_TOWNSHIP_FAIL = "FETCH_TOWNSHIP_FAIL";
export const CLEAR_ERRORS = "CLEAR_ERRORS";
export const REGISTER_USER_REQUEST = "REGISTER_USER_REQUEST";
export const REGISTER_USER_SUCCESS = "REGISTER_USER_SUCCESS";
export const REGISTER_USER_FAIL = "REGISTER_USER_FAIL";
export const LOAD_USER_REQUEST = "LOAD_USER_REQUEST";
export const LOAD_USER_SUCCESS = "LOAD_USER_SUCCESS";
export const LOAD_USER_FAIL = "LOAD_USER_FAIL";
export const UPDATE_USER_PROFILE_REQUEST = "UPDATE_USER_PROFILE_REQUEST";
export const UPDATE_USER_PROFILE_SUCCESS = "UPDATE_USER_PROFILE_SUCCESS";
export const UPDATE_USER_PROFILE_RESET = "UPDATE_USER_PROFILE_RESET";
export const UPDATE_USER_PROFILE_FAIL = "UPDATE_USER_PROFILE_FAIL";
export const FORGOT_PASSWORD_REQUEST = "FORGOT_PASSWORD_REQUEST";
export const FORGOT_PASSWORD_SUCCESS = "FORGOT_PASSWORD_SUCCESS";
export const FORGOT_PASSWORD_FAIL = "FORGOT_PASSWORD_FAIL";
export const RESET_PASSWORD_REQUEST = "RESET_PASSWORD_REQUEST";
export const RESET_PASSWORD_SUCCESS = "RESET_PASSWORD_SUCCESS";
export const RESET_PASSWORD_FAIL = "RESET_PASSWORD_FAIL";
export const CLEAR_ERRORS = 'CLEAR_ERRORS';
import { FETCH_BANKING_PARTNERS_SUCCESS, FETCH_BANKING_PARTNERS_FAIL, CLEAR_ERRORS } from "../constants/bankingPartnersConstants";
// Room details reducer.
export const bankingPartnersReducer = (state = { bankingPartners: [] }, action) => {
switch (action.type) {
case FETCH_BANKING_PARTNERS_SUCCESS:
return {
bankingPartners: action.payload.data
};
case FETCH_BANKING_PARTNERS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { BOOKING_DETAILS_SUCCESS, BOOKING_DETAILS_FAIL, FETCH_MY_BOOKINGS_SUCCESS, FETCH_MY_BOOKINGS_FAIL, CLEAR_ERRORS } from "../constants/bookingConstants";
// Get all booked dates.
export const fetchMyBookingsReducer = (state = { bookings: [] }, action) => {
switch (action.type) {
case FETCH_MY_BOOKINGS_SUCCESS:
return {
loading: false,
bookings: action.payload
};
case FETCH_MY_BOOKINGS_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// Room details reducer.
export const bookingDetailsReducer = (state = { booking: {} }, action) => {
switch (action.type) {
case BOOKING_DETAILS_SUCCESS:
return {
booking: action.payload.data
};
case BOOKING_DETAILS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { FETCH_COMPANY_INFORMATION_SUCCESS, FETCH_COMPANY_INFORMATION_FAIL, CLEAR_ERRORS } from "../constants/companyInformationConstants";
// Room details reducer.
export const companyInformationReducer = (state = { companyInformation: {} }, action) => {
switch (action.type) {
case FETCH_COMPANY_INFORMATION_SUCCESS:
return {
companyInformation: action.payload.data
};
case FETCH_COMPANY_INFORMATION_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { CONTACT_US_SUBMIT_FAIL, CONTACT_US_SUBMIT_REQUEST, CONTACT_US_SUBMIT_SUCCESS } from "../constants/contactUsConstants";
export const contactUsReducer = (state = { contactUs: null }, action) => {
switch (action.type) {
case CONTACT_US_SUBMIT_REQUEST:
return {
loading: true,
success: false
};
case CONTACT_US_SUBMIT_SUCCESS:
return {
loading: false,
success: true,
referral: action.payload
};
case CONTACT_US_SUBMIT_FAIL:
return {
loading: false,
success: false,
error: action.payload.error.message
};
default:
return state;
}
};
import { FETCH_CP_CONNECT_PAGE_SUCCESS, FETCH_CP_CONNECT_PAGE_FAIL, CLEAR_ERRORS } from "../constants/cpConnectPageConstants";
// Room details reducer.
export const cpConnectPageReducer = (state = { cpConnectPage: {} }, action) => {
switch (action.type) {
case FETCH_CP_CONNECT_PAGE_SUCCESS:
return {
cpConnectPage: action.payload.data
};
case FETCH_CP_CONNECT_PAGE_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { LOGIN_SUCCESS, LOGIN_FAIL, CLEAR_ERRORS } from "../constants/cpLoginConstants";
// Room details reducer.
export const cpLoginReducer = (state = { cpLogin: {} }, action) => {
switch (action.type) {
case LOGIN_SUCCESS:
return {
cpLogin: action.payload.data
};
case LOGIN_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { FETCH_DETAILS_FAIL, FETCH_DETAILS_SUCCESS, CLEAR_ERRORS } from "../constants/detailsConstants";
export const detailReducer = (state = { details: [] }, action) => {
switch (action.type) {
case FETCH_DETAILS_SUCCESS:
return {
details: action.payload.data
};
case FETCH_DETAILS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { TOGGLE_DISPLAY_ENQUIRE_NOW_MODAL } from "../constants/enquireNowModalConstants";
export const displayEnquireNowReducer = (state = { displayEnquireNow: false }, action) => {
switch (action.type) {
case TOGGLE_DISPLAY_ENQUIRE_NOW_MODAL:
return {
displayEnquireNow: action.payload
};
default:
return state;
}
};
import { ENQUIRY_SUBMIT_FAIL, ENQUIRY_SUBMIT_REQUEST, ENQUIRY_SUBMIT_SUCCESS } from "../constants/enquiryConstants";
export const enquiryReducer = (state = { enquiry: null }, action) => {
switch (action.type) {
case ENQUIRY_SUBMIT_REQUEST:
return {
loading: true,
success: false
};
case ENQUIRY_SUBMIT_SUCCESS:
return {
loading: false,
success: true,
referral: action.payload
};
case ENQUIRY_SUBMIT_FAIL:
return {
loading: false,
success: false,
error: action.payload.error.message
};
default:
return state;
}
};
import { FETCH_HOME_BANNERS_SUCCESS, FETCH_HOME_BANNERS_FAIL, CLEAR_ERRORS } from "../constants/homeBannerConstants";
// Room details reducer.
export const homeBannerReducer = (state = { homeBanners: [] }, action) => {
switch (action.type) {
case FETCH_HOME_BANNERS_SUCCESS:
return {
homeBanners: action.payload.data
};
case FETCH_HOME_BANNERS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { FETCH_HOME_CONTENT_SUCCESS, FETCH_HOME_CONTENT_FAIL, CLEAR_ERRORS } from "../constants/homeContentConstants";
// Room details reducer.
export const homeContentReducer = (state = { homeContent: {} }, action) => {
switch (action.type) {
case FETCH_HOME_CONTENT_SUCCESS:
return {
homeContent: action.payload.data
};
case FETCH_HOME_CONTENT_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { CLEAR_ERRORS } from "../constants/homeDeliveryStatsConstants";
import { FETCH_HOME_DELIVERY_STATS_FAIL, FETCH_HOME_DELIVERY_STATS_SUCCESS } from "../constants/homeDeliveryStatsConstants";
export const homeDeliveryStatReducer = (state = { homeDeliveryStats: {} }, action) => {
switch (action.type) {
case FETCH_HOME_DELIVERY_STATS_SUCCESS:
return {
homeDeliveryStats: action.payload.data
};
case FETCH_HOME_DELIVERY_STATS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { FETCH_LOCATIONS_SUCCESS, FETCH_LOCATIONS_FAIL, CLEAR_ERRORS } from "../constants/locationsConstants";
// Room details reducer.
export const locationsReducer = (state = { locations: [] }, action) => {
switch (action.type) {
case FETCH_LOCATIONS_SUCCESS:
return {
locations: action.payload.data
};
case FETCH_LOCATIONS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { FETCH_MENU_ITEMS_REQUEST, FETCH_MENU_ITEMS_SUCCESS, FETCH_MENU_ITEMS_FAIL, CLEAR_ERRORS } from "../constants/menuItemsConstants";
// Room details reducer.
export const menuItemsReducer =
menu =>
(state = { menuItems: [] }, action) => {
const fmir = `${FETCH_MENU_ITEMS_REQUEST}_${menu.toUpperCase()}`;
const fmis = `${FETCH_MENU_ITEMS_SUCCESS}_${menu.toUpperCase()}`;
const fmif = `${FETCH_MENU_ITEMS_FAIL}_${menu.toUpperCase()}`;
const ce = `${CLEAR_ERRORS}_${menu.toUpperCase()}`;
switch (action.type) {
case fmir:
return {
loading: true
};
case fmis:
return {
loading: false,
totalCount: action.payload.meta.pagination.total,
resultsPerPage: action.payload.meta.pagination.pageSize,
menuItems: action.payload.data
};
case fmif:
return {
error: action.payload.error.message
};
case ce:
return {
...state,
error: null
};
default:
return state;
}
};
import {
FETCH_PROJECTS_REQUEST,
FETCH_PROJECTS_SUCCESS,
FETCH_PROJECTS_FAIL,
FETCH_PROJECT_REQUEST,
FETCH_PROJECT_SUCCESS,
FETCH_PROJECT_FAIL,
CLEAR_ERRORS,
FETCH_SIMILAR_PROJECTS_REQUEST,
FETCH_SIMILAR_PROJECTS_SUCCESS,
FETCH_SIMILAR_PROJECTS_FAIL
} from "../constants/projectsConstants";
// Room details reducer.
export const projectsReducer = (state = { projects: [] }, action) => {
switch (action.type) {
case FETCH_PROJECTS_REQUEST:
return {
loading: true
};
case FETCH_PROJECTS_SUCCESS:
return {
loading: false,
totalCount: action.payload.meta.pagination.total,
resultsPerPage: action.payload.meta.pagination.pageSize,
projects: action.payload.data
};
case FETCH_PROJECTS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
export const projectReducer = (state = { project: {} }, action) => {
switch (action.type) {
case FETCH_PROJECT_REQUEST:
return {
loading: true
};
case FETCH_PROJECT_SUCCESS:
return {
project: action.payload.data
};
case FETCH_PROJECT_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
export const similarProjectsReducer = (state = { similarProjects: [] }, action) => {
switch (action.type) {
case FETCH_SIMILAR_PROJECTS_REQUEST:
return {
loading: true
};
case FETCH_SIMILAR_PROJECTS_SUCCESS:
return {
similarProjects: action.payload.data
};
case FETCH_SIMILAR_PROJECTS_FAIL:
return {
error: action.payload.error.message
};
default:
return state;
}
};
import { combineReducers } from "redux";
import { bankingPartnersReducer } from "./bankingPartnersReducer";
import { companyInformationReducer } from "./companyInformationReducer";
import { cpConnectPageReducer } from "./cpConnectPageReducer";
import { detailReducer } from "./detailsReducer";
import { cpLoginReducer } from "./cpLoginReducer";
import { homeBannerReducer } from "./homeBannersReducer";
import { homeContentReducer } from "./homeContentReducer";
import { homeDeliveryStatReducer } from "./homeDeliveryStatsReducer";
import { locationsReducer } from "./locationsReducer";
import { menuItemsReducer } from "./menuItemsReducer";
import { projectReducer, projectsReducer, similarProjectsReducer } from "./projectsReducer";
import { townshipReducer, townshipsReducer } from "./townshipsReducer";
import { authReducer, forgotPasswordReducer, loadedUserReducer, resetPasswordReducer, userReducer } from "./userReducers";
import { referralReducer } from "./referralReducer";
import { contactUsReducer } from "./contactUsReducer";
import { enquiryReducer } from "./enquiryReducer";
import { displayEnquireNowReducer } from "./enquireNowModalReducer";
const reducers = combineReducers({
bankingPartners: bankingPartnersReducer,
homeContent: homeContentReducer,
homeBanners: homeBannerReducer,
townships: townshipsReducer,
township: townshipReducer,
projects: projectsReducer,
project: projectReducer,
companyInformation: companyInformationReducer,
mainMenuItems: menuItemsReducer("Main"),
footerMenuItems: menuItemsReducer("Footer"),
locations: locationsReducer,
homeDeliveryStats: homeDeliveryStatReducer,
cpConnectPage: cpConnectPageReducer,
auth: authReducer,
loadedUser: loadedUserReducer,
user: userReducer,
forgotPassword: forgotPasswordReducer,
resetPassword: resetPasswordReducer,
details: detailReducer,
cpLogin: cpLoginReducer,
referral: referralReducer,
similarProjects: similarProjectsReducer,
contactUs: contactUsReducer,
enquiry: enquiryReducer,
displayEnquireNow:displayEnquireNowReducer
});
export default reducers;
import { REFERRAL_SUBMIT_FAIL, REFERRAL_SUBMIT_REQUEST, REFERRAL_SUBMIT_SUCCESS } from "../constants/referralConstants";
export const referralReducer = (state = { referral: null }, action) => {
switch (action.type) {
case REFERRAL_SUBMIT_REQUEST:
return {
loading: true,
success: false
};
case REFERRAL_SUBMIT_SUCCESS:
return {
loading: false,
success: true,
referral: action.payload
};
case REFERRAL_SUBMIT_FAIL:
return {
loading: false,
success: false,
error: action.payload.error.message
};
default:
return state;
}
};
import {
ROOM_CHECK_AVAILABILITY_REQUEST,
ROOM_CHECK_AVAILABILITY_SUCCESS,
ROOM_CHECK_AVAILABILITY_RESET,
ROOM_CHECK_AVAILABILITY_FAIL,
ROOM_MAKE_REVIEW_REQUEST,
ROOM_MAKE_REVIEW_SUCCESS,
ROOM_MAKE_REVIEW_RESET,
ROOM_MAKE_REVIEW_FAIL,
ROOM_FETCH_BOOKED_DATES_SUCCESS,
ROOM_FETCH_BOOKED_DATES_FAIL,
ALL_ROOMS_FAIL,
ALL_ROOMS_SUCCESS,
ROOM_DETAILS_SUCCESS,
ROOM_DETAILS_FAIL,
CLEAR_ERRORS
} from "../constants/roomConstants";
// All rooms reducer.
export const allRoomsReducer = (state = { rooms: [] }, action) => {
switch (action.type) {
case ALL_ROOMS_SUCCESS:
return {
roomsCount: action.payload.meta.pagination.total,
resultsPerPage: action.payload.meta.pagination.pageSize,
filteredRoomsCount: 0,
rooms: action.payload.data
};
case ALL_ROOMS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// Room details reducer.
export const roomDetailsReducer = (state = { room: {} }, action) => {
switch (action.type) {
case ROOM_DETAILS_SUCCESS:
return {
room: action.payload.data
};
case ROOM_DETAILS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// room availability
export const checkRoomAvailabilityReducer = (state = { available: true }, action) => {
switch (action.type) {
case ROOM_CHECK_AVAILABILITY_REQUEST:
return {
loading: true
};
case ROOM_CHECK_AVAILABILITY_SUCCESS:
return {
loading: false,
available: action.payload.isAvailable
};
case ROOM_CHECK_AVAILABILITY_RESET:
return {
loading: false,
available: null
};
case ROOM_CHECK_AVAILABILITY_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// room availability
export const makeReviewReducer = (state = { review: null }, action) => {
switch (action.type) {
case ROOM_MAKE_REVIEW_REQUEST:
return {
loading: true
};
case ROOM_MAKE_REVIEW_SUCCESS:
return {
loading: false,
review: action.payload.review
};
case ROOM_MAKE_REVIEW_RESET:
return {
review: null
};
case ROOM_MAKE_REVIEW_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// Get all booked dates.
export const fetchRoomBookedDatesReducer = (state = { bookedDates: [] }, action) => {
switch (action.type) {
case ROOM_FETCH_BOOKED_DATES_SUCCESS:
return {
loading: false,
bookedDates: action.payload.bookedDates.map(bookedDate => new Date(bookedDate))
};
case ROOM_FETCH_BOOKED_DATES_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import {
FETCH_TOWNSHIPS_REQUEST,
FETCH_TOWNSHIPS_SUCCESS,
FETCH_TOWNSHIPS_FAIL,
FETCH_TOWNSHIP_REQUEST,
FETCH_TOWNSHIP_SUCCESS,
FETCH_TOWNSHIP_FAIL,
CLEAR_ERRORS
} from "../constants/townshipsConstants";
// Room details reducer.
export const townshipsReducer = (state = { townships: [] }, action) => {
switch (action.type) {
case FETCH_TOWNSHIPS_REQUEST:
return {
loading: true
};
case FETCH_TOWNSHIPS_SUCCESS:
return {
loading: false,
totalCount: action.payload.meta.pagination.total,
resultsPerPage: action.payload.meta.pagination.pageSize,
townships: action.payload.data
};
case FETCH_TOWNSHIPS_FAIL:
return {
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
export const townshipReducer = (state = { township: {} }, action) => {
switch (action.type) {
case FETCH_TOWNSHIP_REQUEST:
return {
loading: true
};
case FETCH_TOWNSHIP_SUCCESS:
return {
loading: false,
township: action.payload.data
};
case FETCH_TOWNSHIP_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import {
LOAD_USER_REQUEST,
LOAD_USER_SUCCESS,
LOAD_USER_FAIL,
FORGOT_PASSWORD_REQUEST,
FORGOT_PASSWORD_SUCCESS,
FORGOT_PASSWORD_FAIL,
RESET_PASSWORD_REQUEST,
RESET_PASSWORD_SUCCESS,
RESET_PASSWORD_FAIL,
UPDATE_USER_PROFILE_REQUEST,
UPDATE_USER_PROFILE_SUCCESS,
UPDATE_USER_PROFILE_RESET,
UPDATE_USER_PROFILE_FAIL,
REGISTER_USER_REQUEST,
REGISTER_USER_SUCCESS,
REGISTER_USER_FAIL,
CLEAR_ERRORS
} from "../constants/userConstants";
// Auth reducer
export const authReducer = (state = { loading: false, success: false, user: null }, action) => {
switch (action.type) {
case REGISTER_USER_REQUEST:
return {
loading: true
};
case REGISTER_USER_SUCCESS:
console.log(`Received dispatch REGISTER_USER_SUCCESS`);
return {
loading: false,
success: true
};
case REGISTER_USER_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// Load user reducer
export const loadedUserReducer = (state = { loading: true, success: false, user: null }, action) => {
switch (action.type) {
case LOAD_USER_REQUEST:
return {
loading: true,
isAuthenticated: false
};
case LOAD_USER_SUCCESS:
return {
loading: false,
isAuthenticated: true,
user: action.payload
};
case LOAD_USER_FAIL:
return {
loading: false,
isAuthenticated: true,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// User reducer
export const userReducer = (state = {}, action) => {
switch (action.type) {
case UPDATE_USER_PROFILE_REQUEST:
return {
loading: true
};
case UPDATE_USER_PROFILE_SUCCESS:
return {
loading: false,
isUpdated: action.payload
};
case UPDATE_USER_PROFILE_RESET:
return {
loading: false,
isUpdated: false
};
case UPDATE_USER_PROFILE_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// Forgot password reducer
export const forgotPasswordReducer = (state = {}, action) => {
switch (action.type) {
case FORGOT_PASSWORD_REQUEST:
return {
loading: true
};
case FORGOT_PASSWORD_SUCCESS:
return {
loading: false,
message: action.payload
};
case FORGOT_PASSWORD_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
// Reset password reducer
export const resetPasswordReducer = (state = {}, action) => {
switch (action.type) {
case RESET_PASSWORD_REQUEST:
return {
loading: true
};
case RESET_PASSWORD_SUCCESS:
return {
loading: false,
message: action.payload
};
case RESET_PASSWORD_FAIL:
return {
loading: false,
error: action.payload.error.message
};
case CLEAR_ERRORS:
return {
...state,
error: null
};
default:
return state;
}
};
import { createStore, applyMiddleware } from "redux";
import { HYDRATE, createWrapper } from "next-redux-wrapper";
import thunkMiddleware from "redux-thunk";
// import { ThunkMiddleware } from 'redux-thunk';
import reducers from "./reducers/reducers";
const bindMiddleware = middleware => {
if (process.env.NODE_ENV !== "production") {
const { composerWithDevTools, composeWithDevTools } = require("redux-devtools-extension");
return composeWithDevTools(applyMiddleware(...middleware));
}
return applyMiddleware(...middleware);
};
const reducer = (state, action) => {
if (action.type === HYDRATE) {
const nextState = { ...state, ...action.payload };
return nextState;
} else {
return reducers(state, action);
}
};
const initStore = () => {
return createStore(reducer, bindMiddleware([thunkMiddleware]));
};
export const wrapper = createWrapper(initStore);
export const cleanImage = originalImage => {
let imageUrl = "/images/default.svg";
if (originalImage) {
/** When the AWS S3 plugin is activated, images are uploaded to S3 rather than local file system. */
if (originalImage.url.startsWith("http")) {
imageUrl = originalImage.url;
} else {
/** If now S3, then images are stored under the public/uploads directory of Strapi */
imageUrl = `${process.env.NEXT_PUBLIC_BACKEND_API_URL}${originalImage.url}`;
}
}
return imageUrl;
};
import { loadStripe } from '@stripe/stripe-js';
let stripePromise;
const getStripe = () => {
if (!stripePromise) {
stripePromise = loadStripe(process.env.stripePublishableKey)
}
return stripePromise;
}
export default getStripe;
.container {
padding: 0 2rem;
}
.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.footer {
display: flex;
flex: 1;
padding: 2rem 0;
border-top: 1px solid #eaeaea;
justify-content: center;
align-items: center;
}
.footer a {
display: flex;
justify-content: center;
align-items: center;
flex-grow: 1;
}
.title a {
color: #0070f3;
text-decoration: none;
}
.title a:hover,
.title a:focus,
.title a:active {
text-decoration: underline;
}
.title {
margin: 0;
line-height: 1.15;
font-size: 4rem;
}
.title,
.description {
text-align: center;
}
.description {
margin: 4rem 0;
line-height: 1.5;
font-size: 1.5rem;
}
.code {
background: #fafafa;
border-radius: 5px;
padding: 0.75rem;
font-size: 1.1rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 800px;
}
.card {
margin: 1rem;
padding: 1.5rem;
text-align: left;
color: inherit;
text-decoration: none;
border: 1px solid #eaeaea;
border-radius: 10px;
transition: color 0.15s ease, border-color 0.15s ease;
max-width: 300px;
}
.card:hover,
.card:focus,
.card:active {
color: #0070f3;
border-color: #0070f3;
}
.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
.logo {
height: 1em;
margin-left: 0.5rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}
@media (prefers-color-scheme: dark) {
.card,
.footer {
border-color: #222;
}
.code {
background: #111;
}
.logo img {
filter: invert(1);
}
}
@font-face {
font-family: 'Inter Regular';
font-style: normal;
font-weight: normal;
src: local('Inter Regular'), url('../public/fonts/Inter-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'Inter SemiBold';
font-style: normal;
font-weight: normal;
src: local('Inter SemiBold'), url('../public/fonts/Inter-SemiBold.ttf') format('truetype');
}
@font-face {
font-family: 'Inter Bold';
font-style: normal;
font-weight: normal;
src: local('Inter Bold'), url('../public/fonts/Inter-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Inter Black';
font-style: normal;
font-weight: normal;
src: local('Inter Black'), url('../public/fonts/Inter-Black.ttf') format('truetype');
}
@font-face {
font-family: 'Inter Medium';
font-style: normal;
font-weight: normal;
src: local('Inter Medium'), url('../public/fonts/Inter-Medium.ttf') format('truetype');
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!