├── .gitignore
├── LICENSE
├── README.md
├── functions
└── update.js
├── package-lock.json
├── package.json
├── public
├── _redirects
├── apple-touch-icon.png
├── arrowdown.svg
├── contact-mail.svg
├── favicon-16x16.png
├── favicon-32x32.png
├── favicon.ico
├── google-2.svg
├── google-21.svg
├── icon.svg
├── icon1.svg
├── icon2.svg
├── icon3.svg
├── iconoutlinearrowright.svg
├── iconoutlinearrowright1.svg
├── iconoutlinearrowright5.svg
├── iconoutlinearrowright6.svg
├── iconoutlineplay.svg
├── icons.svg
├── illustration.svg
├── image-1@2x.png
├── index.html
├── left-icon.svg
├── lines.svg
├── logo.svg
├── logo192.png
├── logo512.png
├── logofbsimple-2.svg
├── logogithub-1.svg
├── logoinstagram-1.svg
├── logotwitter-2.svg
├── manifest.json
├── morevertical.svg
├── og.png
├── robots.txt
├── send@2x.png
├── vector.svg
└── vector1.svg
└── src
├── App.js
├── components
├── EmailsTable.js
├── Features.js
├── Footer.js
├── Hero.js
├── Input.js
├── PopUp.js
├── ProtectedDashboard.js
├── Sidebar.js
└── Spinner.js
├── index.js
├── pages
├── Home.js
├── Overview.js
├── PageNotFound.js
├── Profile.js
├── SignIn.js
└── SignUp.js
└── styles
├── components
├── Input.module.css
├── Popup.module.css
└── Spinner.module.css
├── global.css
└── pages
├── Dashboard.module.css
├── Home.module.css
├── PageNotFound.module.css
├── Profile.module.css
├── SignIn.module.css
└── SignUp.module.css
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Aashish Panthi
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Mailsbe
2 |
3 | **Suppose**, you have applied for a job through an email. You have sent the email two days ago but you haven't gotten any response. And you don't know if the employer read your email or not. Well no need to worry now because I have a solution for that, **introducing Mailsbe**.
4 |
5 | ## Introduction
6 |
7 | **Mailsbe** is an MIT Licensed open source project and a platform with the help of which you can find out if the Email sent by you has **been read or not**. It is a simple platform that has been designed by keeping the **user's privacy **in mind. We don't ask for full email read/write access. Instead, we provide a simple way to find the status if your email **respecting your privacy**.
8 |
9 | ## Tech stack
10 |
11 | It doesn't involve a very much complicated tech stack. Instead, it uses only a few technologies like React and Nhost.
12 |
13 | - **React** -> For frontend part
14 | - **Nhost** -> For user authentication, database, hosting and serverless function
15 |
16 | > If you don't know about Nhost then simply put it as a firebase alternative. Even officially, Nhost is called an open-source Firebase alternative with GraphQL.
17 |
18 | ## Process
19 |
20 | I am not going to explain all of the technical jargon here, instead, I will take you through the working process of the project.
21 |
22 | First of all, you need to create an account. Then only you can access your dashboard. Inside of your dashboard, you will see the list of emails you have sent and complete detail about them. If you haven't sent any emails then you can send one by clicking on compose button on the top left side of the page.
23 |
24 | No, you can't send emails from here. Instead, you will be provided an image (1x1 transparent pixel) which you can copy and paste to the email client from where you are sending the email. Then fill out some more information about the email (it will make it easy to find the email in the future) and click save.
25 |
26 | After you sent your email, you can now access the status of the email on the dashboard. The status is either _seen_ or _unseen_. The status will be updated when the receiver opens up the email you sent. And the serverless function helps to do that by accepting the receiver's request and updating it on the database.
27 |
28 | > This detailed guide will help you: https://blog.aashish-panthi.com.np/make-an-email-tracker-using-nhost-serverless-functions
29 |
--------------------------------------------------------------------------------
/functions/update.js:
--------------------------------------------------------------------------------
1 | import { NhostClient } from "@nhost/nhost-js";
2 |
3 | const accessToken = process.env.NHOST_ADMIN_SECRET;
4 | const backendUrl = process.env.NHOST_BACKEND_URL;
5 |
6 | const nhost = new NhostClient({
7 | backendUrl: backendUrl,
8 | });
9 |
10 | nhost.graphql.setAccessToken(accessToken);
11 |
12 | export default async (req, res) => {
13 | // get the data from the request
14 | const imgText = req.query.text;
15 | console.log("imgText", imgText);
16 |
17 | if (!imgText) {
18 | return res.status(500).json({ error: "No image token provided" });
19 | }
20 |
21 | // make a get query to get email id using imgText
22 | const GET_EMAIL_ID = `
23 | query getId($text: String!) {
24 | emails(where: {img_text: {_eq: $text}}) {
25 | id
26 | seen
27 | }
28 | }`;
29 |
30 | // update query with the email id
31 | const UPDATE_QUERY = `
32 | mutation UpdateEmail($id: Int!, $date: timestamptz!) {
33 | update_emails(where: {id: {_eq: $id}}, _set: {seen: true, seen_at: $date}) {
34 | affected_rows
35 | }
36 | }`;
37 |
38 | try {
39 | const { data, error } = await nhost.graphql.request(GET_EMAIL_ID, {
40 | text: imgText,
41 | });
42 |
43 | if (error) {
44 | return res.status(500).json({ error: error.message });
45 | }
46 |
47 | if (!data) {
48 | return res.status(500).json({ error: "No email found" });
49 | }
50 |
51 | // extract the email id from the response
52 | const emailId = data.emails[0].id;
53 | const seen = data.emails[0].seen;
54 |
55 | if (seen) {
56 | return res.status(500).json({ error: "Kaam hogaya vai" });
57 | }
58 |
59 | //update the seen column in emails table
60 | const { data: updatedData, error: updateError } =
61 | await nhost.graphql.request(UPDATE_QUERY, {
62 | id: emailId,
63 | date: new Date(),
64 | });
65 |
66 | if (updateError) {
67 | return res.status(500).json({ error: error.message });
68 | }
69 |
70 | res.status(404).send({ error: "Bye bye" });
71 | } catch (error) {
72 | console.log(error);
73 | res.status(500).json({ error });
74 | }
75 | };
76 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mailsbe",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@apollo/client": "^3.7.0",
7 | "@emotion/react": "^11.10.4",
8 | "@emotion/styled": "^11.10.4",
9 | "@headlessui/react": "^1.7.3",
10 | "@heroicons/react": "^1.0.6",
11 | "@mui/icons-material": "^5.10.9",
12 | "@mui/lab": "^5.0.0-alpha.103",
13 | "@mui/material": "^5.10.9",
14 | "@mui/styled-engine": "^5.10.8",
15 | "@nhost/react": "^0.13.0",
16 | "@nhost/react-apollo": "^4.7.6",
17 | "@testing-library/jest-dom": "^5.16.5",
18 | "@testing-library/react": "^13.4.0",
19 | "@testing-library/user-event": "^13.5.0",
20 | "@types/jest": "^27.0.3",
21 | "@types/node": "^16.11.14",
22 | "@types/react": "^18.0.17",
23 | "@types/react-dom": "^18.0.6",
24 | "classnames": "^2.3.2",
25 | "express": "^4.18.2",
26 | "graphql": "^16.6.0",
27 | "react": "^18.2.0",
28 | "react-dom": "^18.2.0",
29 | "react-helmet": "^6.1.0",
30 | "react-hot-toast": "^2.4.0",
31 | "react-router-dom": "^6.4.2",
32 | "react-scripts": "^5.0.1",
33 | "web-vitals": "^2.1.4"
34 | },
35 | "scripts": {
36 | "start": "react-scripts start",
37 | "build": "react-scripts build",
38 | "test": "react-scripts test",
39 | "eject": "react-scripts eject"
40 | },
41 | "eslintConfig": {
42 | "extends": [
43 | "react-app",
44 | "react-app/jest"
45 | ]
46 | },
47 | "browserslist": {
48 | "production": [
49 | ">0.2%",
50 | "not dead",
51 | "not op_mini all"
52 | ],
53 | "development": [
54 | "last 1 chrome version",
55 | "last 1 firefox version",
56 | "last 1 safari version"
57 | ]
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/public/_redirects:
--------------------------------------------------------------------------------
1 | /* /index.html 200
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/public/arrowdown.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/contact-mail.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/favicon-16x16.png
--------------------------------------------------------------------------------
/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/favicon-32x32.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/favicon.ico
--------------------------------------------------------------------------------
/public/google-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/google-21.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icon1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icon2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icon3.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/iconoutlinearrowright.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/iconoutlinearrowright1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/iconoutlinearrowright5.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/iconoutlinearrowright6.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/iconoutlineplay.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icons.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/image-1@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/image-1@2x.png
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | Mailsbe, your email partner
17 |
18 |
19 | You need to enable JavaScript to run this app.
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/public/left-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/lines.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/logo512.png
--------------------------------------------------------------------------------
/public/logofbsimple-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logogithub-1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logoinstagram-1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/logotwitter-2.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Mailsbe",
3 | "name": "Email status",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/morevertical.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/og.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/og.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/send@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aashishpanthi/mailsbe/9ea788a17fa916381ea4206cb22c0f127348b001/public/send@2x.png
--------------------------------------------------------------------------------
/public/vector.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/vector1.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import { BrowserRouter, Routes, Route } from "react-router-dom";
2 | import { Toaster } from "react-hot-toast";
3 | import { NhostClient, NhostReactProvider } from "@nhost/react";
4 | import { NhostApolloProvider } from "@nhost/react-apollo";
5 |
6 | import SignUp from "./pages/SignUp";
7 | import SignIn from "./pages/SignIn";
8 | import Home from "./pages/Home";
9 | import Profile from "./pages/Profile";
10 | import PageNotFound from "./pages/PageNotFound";
11 | import ProtectedDashboard from "./components/ProtectedDashboard";
12 | import Overview from "./pages/Overview";
13 |
14 | const App = () => {
15 | const nhost = new NhostClient({
16 | subdomain: process.env.REACT_APP_NHOST_SUBDOMAIN,
17 | region: process.env.REACT_APP_NHOST_REGION,
18 | });
19 |
20 | return (
21 |
22 |
23 |
24 |
25 | } />
26 | } />
27 | } />
28 |
29 | }>
30 | } />
31 | } />
32 |
33 | } />
34 |
35 |
36 |
37 |
38 |
39 |
40 | );
41 | };
42 |
43 | export default App;
44 |
--------------------------------------------------------------------------------
/src/components/EmailsTable.js:
--------------------------------------------------------------------------------
1 | import { Delete } from "@mui/icons-material";
2 | import { IconButton } from "@mui/material";
3 | import { gql, useLazyQuery, useMutation } from "@apollo/client";
4 | import { useUserData } from "@nhost/react";
5 | import { CircularProgress } from "@mui/material";
6 | import toast from "react-hot-toast";
7 | import { useEffect, useState } from "react";
8 |
9 | const GET_EMAILS = gql`
10 | query getEmails($user: String) {
11 | emails(order_by: { created_at: desc }, where: { user: { _eq: $user } }) {
12 | created_at
13 | description
14 | email
15 | id
16 | img_text
17 | seen
18 | seen_at
19 | }
20 | }
21 | `;
22 |
23 | const DELETE_EMAIL = gql`
24 | mutation deleteEmail($id: Int) {
25 | delete_emails(where: { id: { _eq: $id } }) {
26 | affected_rows
27 | }
28 | }
29 | `;
30 |
31 | const EmailsTable = ({ styles }) => {
32 | const user = useUserData();
33 | const [emails, setEmails] = useState([]);
34 |
35 | const [getEmails, { loading, error, data }] = useLazyQuery(GET_EMAILS, {
36 | variables: { user: user.id },
37 | });
38 |
39 | const [deleteTodo, { loading: deleting, error: deleteError }] =
40 | useMutation(DELETE_EMAIL);
41 |
42 | const fetchEmails = async () => {
43 | try {
44 | await getEmails({
45 | variables: { user: user.id },
46 | });
47 |
48 | // toast.success("Emails fetched successfully");
49 | setEmails(data.emails);
50 | } catch (err) {
51 | console.log(err);
52 | }
53 | };
54 |
55 | useEffect(() => {
56 | fetchEmails();
57 | }, [data, user]);
58 |
59 | const deleteEmail = async (id) => {
60 | const confirmation = window.confirm(
61 | "Are you sure you want to delete this?"
62 | );
63 | if (!confirmation) {
64 | return;
65 | }
66 |
67 | try {
68 | await deleteTodo({
69 | variables: {
70 | id: id,
71 | },
72 | });
73 |
74 | toast.success("Email deleted successfully");
75 | window.location.reload();
76 | } catch (err) {
77 | toast.error("Unable to delete email");
78 | }
79 | };
80 |
81 | if (loading) {
82 | return (
83 |
84 |
85 |
86 | );
87 | }
88 |
89 | if (emails.length === 0) {
90 | return No emails found
;
91 | }
92 |
93 | return (
94 |
95 |
96 |
101 | {emails.map((email) => (
102 |
103 |
{email.email}
104 |
105 | ))}
106 |
107 |
108 |
113 | {emails.map(({ seen, id }) => (
114 |
115 |
116 |
117 |
118 | {seen ? `Seen` : `Unseen`}
119 |
120 |
121 |
122 |
123 | ))}
124 |
125 |
126 |
131 | {emails.map(({ description, id }) => (
132 |
133 |
{description}
134 |
135 | ))}
136 |
137 |
138 |
143 |
144 | {emails.map(({ created_at, id }) => (
145 |
146 |
147 | {new Date(created_at).toLocaleString()}
148 |
149 |
150 | ))}
151 |
152 |
153 |
158 | {emails.map(({ seen_at, id, seen }) => (
159 |
160 |
161 | {seen ? new Date(seen_at).toLocaleString() : "Not seen"}
162 |
163 |
164 | ))}
165 |
166 |
167 |
168 | {emails.map(({ id }) => (
169 |
170 | deleteEmail(id)}>
171 |
172 |
173 |
174 | ))}
175 |
176 |
177 | );
178 | };
179 |
180 | export default EmailsTable;
181 |
--------------------------------------------------------------------------------
/src/components/Features.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function Features({ styles }) {
4 | return (
5 |
6 |
7 |
Use email like a geek
8 |
9 | Explore the unexplored potential of email
10 |
11 |
12 |
13 |
14 |
15 |
Send
16 |
17 | Compose a new email with pixel tracking enabled.
18 |
19 |
20 |
21 |
22 |
Status
23 |
24 | Know if the user read the email or not.
25 |
26 |
27 |
28 |
29 |
History
30 |
31 | Find out exactly when the receiver read your mail.
32 |
33 |
34 |
35 |
36 | );
37 | }
38 |
39 | export default Features;
40 |
--------------------------------------------------------------------------------
/src/components/Footer.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function Footer({ styles }) {
4 | return (
5 |
6 |
26 |
27 |
28 |
29 |
About Mailsbe
30 |
31 | We are here to help you suceed in your digital journey by helping
32 | you in your everyday journey. We help you to find out if the
33 | receiver has read the email or not.
34 |
35 |
77 |
78 |
90 |
91 |
Help
92 |
93 |
94 | Customer Support
95 |
96 |
97 | Service Details
98 |
99 |
100 | {`Terms & Conditions`}
101 |
102 |
103 | Privacy Policy
104 |
105 |
106 |
107 |
108 |
109 | );
110 | }
111 |
112 | export default Footer;
113 |
--------------------------------------------------------------------------------
/src/components/Hero.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 |
4 | function Hero({ styles }) {
5 | const handleScroll = () => {
6 | const videoContainer = document.getElementById("video-container");
7 | videoContainer.scrollIntoView({ behavior: "smooth" });
8 | };
9 |
10 | return (
11 |
12 |
13 |
14 | mailsbe
15 |
16 |
17 |
18 | Login
19 |
20 |
21 |
22 |
Sign up
23 |
24 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Smart email status finder, made for Everyone
37 |
38 |
39 | Know if your email has been read
40 |
41 |
42 |
43 |
44 |
Get started now
45 |
46 |
51 |
52 |
53 |
54 |
59 |
60 |
61 |
66 |
67 |
Watch a demo
68 |
69 |
70 |
71 |
72 | Create your account. For free of cost
73 |
74 |
75 |
76 | );
77 | }
78 |
79 | export default Hero;
80 |
--------------------------------------------------------------------------------
/src/components/Input.js:
--------------------------------------------------------------------------------
1 | import styles from '../styles/components/Input.module.css';
2 |
3 | const Input = ({ type = 'text', label = '', ...props }) => {
4 | return (
5 |
6 | {label ? {label} : null}
7 |
8 |
9 | );
10 | };
11 |
12 | export default Input;
13 |
--------------------------------------------------------------------------------
/src/components/PopUp.js:
--------------------------------------------------------------------------------
1 | import {
2 | TextField,
3 | Typography,
4 | IconButton,
5 | FormHelperText,
6 | FormControl,
7 | } from "@mui/material";
8 | import LoadingButton from "@mui/lab/LoadingButton";
9 | import SaveIcon from "@mui/icons-material/Save";
10 | import HighlightOffIcon from "@mui/icons-material/HighlightOff";
11 | import toast from "react-hot-toast";
12 | import { useUserData } from "@nhost/react";
13 |
14 | import styles from "../styles/components/Popup.module.css";
15 | import { useState, useEffect, useRef } from "react";
16 | import { gql, useMutation } from "@apollo/client";
17 |
18 | const ADD_EMAIL = gql`
19 | mutation addEmail(
20 | $email: String
21 | $description: String
22 | $img_text: String
23 | $user: String
24 | ) {
25 | insert_emails(
26 | objects: {
27 | description: $description
28 | email: $email
29 | img_text: $img_text
30 | user: $user
31 | }
32 | ) {
33 | affected_rows
34 | }
35 | }
36 | `;
37 |
38 | const PopUp = ({ setPopUp }) => {
39 | //get the user data
40 | const user = useUserData();
41 |
42 | const [email, setEmail] = useState("");
43 | const [description, setDescription] = useState("");
44 | const [name, setName] = useState(user.displayName);
45 | const [imgText, setImgText] = useState("");
46 |
47 | const [addEmail, { data, loading, error }] = useMutation(ADD_EMAIL);
48 |
49 | const ref = useRef();
50 |
51 | const handleSubmit = async (e) => {
52 | e.preventDefault();
53 |
54 | try {
55 | await addEmail({
56 | variables: {
57 | email: email,
58 | description: description,
59 | img_text: imgText.split("=")[1],
60 | user: user.id,
61 | },
62 | });
63 | toast.success("Email added successfully");
64 | setPopUp(false);
65 | window.location.reload();
66 | } catch (err) {
67 | toast.error("Unable to add email");
68 | }
69 | };
70 |
71 | useEffect(() => {
72 | const time = new Date().getTime();
73 | setImgText(
74 | `https://tkjfsvqlulofoefmacvj.nhost.run/v1/functions/update?text=${time}`
75 | );
76 | }, []);
77 |
78 | return (
79 |
80 |
81 |
82 |
83 | Enter new email details
84 |
85 |
86 | setPopUp(false)}>
87 |
88 |
89 |
90 |
167 |
168 |
169 | );
170 | };
171 |
172 | export default PopUp;
173 |
--------------------------------------------------------------------------------
/src/components/ProtectedDashboard.js:
--------------------------------------------------------------------------------
1 | import Sidebar from "../components/Sidebar";
2 | import { Outlet, Navigate, useLocation } from "react-router-dom";
3 | import styles from "../styles/pages/Dashboard.module.css";
4 | import { useAuthenticationStatus, useUserData } from "@nhost/react";
5 | import Spinner from "./Spinner";
6 | import { useState } from "react";
7 | import PopUp from "./PopUp";
8 |
9 | function ProtectedDashboard() {
10 | const user = useUserData();
11 | const { isAuthenticated, isLoading } = useAuthenticationStatus();
12 | const location = useLocation();
13 |
14 | const [popUp, setPopUp] = useState(false);
15 |
16 | if (isLoading) {
17 | return (
18 |
19 |
20 |
21 | );
22 | }
23 |
24 | if (!isAuthenticated) {
25 | return ;
26 | }
27 |
28 | return (
29 |
30 |
31 |
32 | {popUp &&
}
33 |
34 | );
35 | }
36 |
37 | export default ProtectedDashboard;
38 |
--------------------------------------------------------------------------------
/src/components/Sidebar.js:
--------------------------------------------------------------------------------
1 | import { Link, useNavigate } from "react-router-dom";
2 | import { useCallback } from "react";
3 | import { useSignOut } from "@nhost/react";
4 |
5 | const Sidebar = ({ styles, user, setPopUp }) => {
6 | const navigate = useNavigate();
7 | const { signOut } = useSignOut();
8 |
9 | const onLogOutButtonClick = useCallback(() => {
10 | signOut();
11 | navigate("/");
12 | }, [navigate]);
13 |
14 | const name = user?.metadata?.name ? user?.metadata?.name : user.displayName;
15 | const email = user.email;
16 |
17 | const image = user.avatarUrl.includes("gravatar.com")
18 | ? user.avatarUrl
19 | : `https://img.icons8.com/external-linector-lineal-linector/344/external-avatar-man-avatar-linector-lineal-linector-6.png`;
20 |
21 | return (
22 |
23 |
24 |
29 |
MAILSBE
30 |
31 |
setPopUp(true)}
35 | >
36 |
37 | Compose mail
38 |
39 |
40 |
Menu
41 |
42 |
43 |
44 |
Overview
45 |
46 |
47 |
48 |
49 |
50 |
Settings
51 |
52 |
53 |
54 |
Profile
55 |
56 |
61 |
62 |
{name}
63 |
{email}
64 |
65 |
66 |
67 |
68 |
73 |
76 |
77 |
78 | );
79 | };
80 |
81 | export default Sidebar;
82 |
--------------------------------------------------------------------------------
/src/components/Spinner.js:
--------------------------------------------------------------------------------
1 | import styles from '../styles/components/Spinner.module.css';
2 |
3 | import classNames from 'classnames';
4 |
5 | const Spinner = ({ size = '' }) => (
6 |
11 | );
12 |
13 | export default Spinner;
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import App from "./App";
4 | import "./styles/global.css";
5 |
6 | const root = ReactDOM.createRoot(document.getElementById("root"));
7 | root.render(
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/src/pages/Home.js:
--------------------------------------------------------------------------------
1 | import styles from "../styles/pages/Home.module.css";
2 | import Hero from "../components/Hero";
3 | import Features from "../components/Features";
4 | import Footer from "../components/Footer";
5 | import { useAuthenticationStatus } from "@nhost/react";
6 | import Spinner from "../components/Spinner";
7 | import { Navigate, useLocation } from "react-router-dom";
8 | import { Helmet } from "react-helmet";
9 |
10 | const Home = () => {
11 | const { isAuthenticated, isLoading } = useAuthenticationStatus();
12 | const location = useLocation();
13 |
14 | if (isLoading) {
15 | return (
16 |
17 |
18 |
19 | );
20 | }
21 |
22 | if (isAuthenticated) {
23 | return ;
24 | }
25 |
26 | return (
27 | <>
28 |
29 | Mailsbe - Track your emails
30 |
31 |
32 |
33 |
34 |
35 | VIDEO
41 |
42 |
43 |
44 |
45 | >
46 | );
47 | };
48 |
49 | export default Home;
50 |
--------------------------------------------------------------------------------
/src/pages/Overview.js:
--------------------------------------------------------------------------------
1 | import styles from "../styles/pages/Dashboard.module.css";
2 | import EmailsTable from "../components/EmailsTable";
3 | import { Helmet } from "react-helmet";
4 |
5 | const Overview = () => {
6 | return (
7 | <>
8 |
9 | Overview - Mailsbe
10 |
11 |
12 |
13 |
14 |
15 |
Emails
16 |
17 | These are the email you sent using mailbes in the last 12
18 | months.
19 |
20 |
21 |
22 |
23 |
24 |
25 | >
26 | );
27 | };
28 |
29 | export default Overview;
30 |
--------------------------------------------------------------------------------
/src/pages/PageNotFound.js:
--------------------------------------------------------------------------------
1 | import { useCallback } from "react";
2 | import { Helmet } from "react-helmet";
3 | import { useNavigate } from "react-router-dom";
4 | import styles from "../styles/pages/PageNotFound.module.css";
5 |
6 | const PageNotFound = () => {
7 | const navigate = useNavigate();
8 |
9 | const onCTAButtonClick = useCallback(() => {
10 | navigate("/");
11 | }, [navigate]);
12 |
13 | return (
14 | <>
15 |
16 | Page Not Found - Mailsbe
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
30 |
404 Error
31 |
32 |
Page not Found
33 |
34 |
35 | Sorry, the page you are looking for doesn’t exist or has been
36 | removed. Keep exploring out site:
37 |
38 |
39 |
44 | Return to home page
45 |
46 |
47 |
48 |
49 | >
50 | );
51 | };
52 |
53 | export default PageNotFound;
54 |
--------------------------------------------------------------------------------
/src/pages/Profile.js:
--------------------------------------------------------------------------------
1 | import styles from "../styles/pages/Profile.module.css";
2 |
3 | import { useState } from "react";
4 | import { Helmet } from "react-helmet";
5 | import { useOutletContext } from "react-router-dom";
6 | import Input from "../components/Input";
7 | import { gql, useMutation } from "@apollo/client";
8 | import { toast } from "react-hot-toast";
9 |
10 | const UPDATE_USER_MUTATION = gql`
11 | mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
12 | updateUser(
13 | pk_columns: { id: $id }
14 | _set: { displayName: $displayName, metadata: $metadata }
15 | ) {
16 | id
17 | displayName
18 | metadata
19 | }
20 | }
21 | `;
22 |
23 | const Profile = () => {
24 | const { user } = useOutletContext();
25 | const [mutateUser, { loading: updatingProfile }] =
26 | useMutation(UPDATE_USER_MUTATION);
27 |
28 | const [name, setname] = useState(user?.metadata?.name ?? "");
29 | console.log(name);
30 |
31 | const isNameDirty = name !== user?.metadata?.name;
32 |
33 | const updateUserProfile = async (e) => {
34 | e.preventDefault();
35 |
36 | try {
37 | await mutateUser({
38 | variables: {
39 | id: user.id,
40 | displayName: name.trim(),
41 | metadata: {
42 | name,
43 | },
44 | },
45 | });
46 | toast.success("Updated successfully", { id: "updateProfile" });
47 |
48 | window.location.reload();
49 | } catch (error) {
50 | toast.error("Unable to update profile", { id: "updateProfile" });
51 | }
52 | };
53 |
54 | return (
55 | <>
56 |
57 | Profile - Mailsbe
58 |
59 |
60 |
61 |
62 |
Profile
63 |
Update your personal information.
64 |
65 |
66 |
101 |
102 | >
103 | );
104 | };
105 |
106 | export default Profile;
107 |
--------------------------------------------------------------------------------
/src/pages/SignIn.js:
--------------------------------------------------------------------------------
1 | import { useSignInEmailPassword } from "@nhost/react";
2 | import { Link, Navigate } from "react-router-dom";
3 | import Spinner from "../components/Spinner";
4 | import { useState } from "react";
5 |
6 | import styles from "../styles/pages/SignIn.module.css";
7 | import { Helmet } from "react-helmet";
8 |
9 | const SignIn = ({ nhost }) => {
10 | const [email, setEmail] = useState("");
11 | const [password, setPassword] = useState("");
12 |
13 | const {
14 | signInEmailPassword,
15 | isLoading,
16 | isSuccess,
17 | needsEmailVerification,
18 | isError,
19 | error,
20 | } = useSignInEmailPassword();
21 |
22 | const handleOnSubmit = (e) => {
23 | e.preventDefault();
24 | signInEmailPassword(email, password);
25 | };
26 |
27 | const handleGoogleSignIn = () => {
28 | nhost.auth.signIn({
29 | provider: "google",
30 | });
31 | };
32 |
33 | if (isSuccess) {
34 | return ;
35 | }
36 |
37 | const disableForm = isLoading || needsEmailVerification;
38 |
39 | return (
40 | <>
41 |
42 | Sign In - Mailsbe
43 |
44 |
45 | {needsEmailVerification ? (
46 |
47 | Please check your mailbox and follow the verification link to verify
48 | your email.
49 |
50 | ) : (
51 |
52 |
53 |
Welcome back 👋
54 |
55 | FIll in the required details to start using your account, and
56 | enjoy mailsbe.
57 |
58 |
59 |
60 |
61 |
62 | Sign in with Google
63 |
64 |
65 |
70 |
71 |
72 |
73 |
78 |
79 |
80 |
153 |
154 | )}
155 |
156 | >
157 | );
158 | };
159 |
160 | export default SignIn;
161 |
--------------------------------------------------------------------------------
/src/pages/SignUp.js:
--------------------------------------------------------------------------------
1 | import { Link, Navigate } from "react-router-dom";
2 | import styles from "../styles/pages/SignUp.module.css";
3 | import { useSignUpEmailPassword } from "@nhost/react";
4 | import { useState } from "react";
5 | import Spinner from "../components/Spinner";
6 | import { Helmet } from "react-helmet";
7 |
8 | const SignUp = ({ nhost }) => {
9 | const [name, setName] = useState("");
10 | const [email, setEmail] = useState("");
11 | const [password, setPassword] = useState("");
12 |
13 | const {
14 | signUpEmailPassword,
15 | isLoading,
16 | isSuccess,
17 | needsEmailVerification,
18 | isError,
19 | error,
20 | } = useSignUpEmailPassword();
21 |
22 | const handleOnSubmit = (e) => {
23 | e.preventDefault();
24 |
25 | signUpEmailPassword(email, password, {
26 | displayName: name,
27 | metadata: {
28 | name,
29 | },
30 | });
31 | };
32 |
33 | const handleGoogleSignUp = () => {
34 | nhost.auth.signIn({
35 | provider: "google",
36 | });
37 | };
38 |
39 | if (isSuccess) {
40 | return ;
41 | }
42 |
43 | const disableForm = isLoading || needsEmailVerification;
44 |
45 | return (
46 | <>
47 |
48 | Sign Up - Mailsbe
49 |
50 |
51 | {needsEmailVerification ? (
52 |
53 | Please check your mailbox and follow the verification link to verify
54 | your email.
55 |
56 | ) : (
57 |
58 |
59 |
Join us today 👋
60 |
61 | Create an account to start using mailsbe from today, completely
62 | free.
63 |
64 |
65 |
66 |
67 |
68 | {" "}
69 | Sign up with Google
70 |
71 |
72 |
77 |
78 |
79 |
80 |
85 |
86 |
87 |
180 |
181 | )}
182 |
183 | >
184 | );
185 | };
186 |
187 | export default SignUp;
188 |
--------------------------------------------------------------------------------
/src/styles/components/Input.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | width: 100%;
3 | display: flex;
4 | flex-direction: column;
5 | }
6 | .container > * + * {
7 | margin-top: 0.25rem;
8 | }
9 |
10 | .label {
11 | color: rgb(55, 65, 81);
12 | font-weight: 500;
13 | font-size: 0.875rem;
14 | line-height: 1.25rem;
15 | }
16 |
17 | .input {
18 | border-width: 1px;
19 | border-radius: 0.375rem;
20 | border-color: rgb(209, 213, 219);
21 | padding: 0.75rem;
22 | box-shadow: 0 0 #0000, 0 0 #0000, 0 1px 2px 0 rgba(0, 0, 0, 0.05);
23 | }
24 | .input:focus {
25 | border-color: rgb(59, 130, 246);
26 | /* remove default outline */
27 | outline: 2px solid transparent;
28 | outline-offset: 2px;
29 | /* add outline with shadow */
30 | box-shadow: 0 0 0 calc(4px) rgba(59, 130, 246, 0.2), 0 0 #0000;
31 | /* transition */
32 | transition-property: border-color, box-shadow;
33 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
34 | transition-duration: 150ms;
35 | }
36 | .input:disabled {
37 | opacity: 0.5;
38 | cursor: not-allowed;
39 | }
40 | .input:read-only {
41 | opacity: 0.5;
42 | cursor: not-allowed;
43 | }
44 | .input:read-only:focus {
45 | border-color: rgb(209, 213, 219);
46 | box-shadow: none;
47 | }
48 |
--------------------------------------------------------------------------------
/src/styles/components/Popup.module.css:
--------------------------------------------------------------------------------
1 | .groupForm {
2 | position: relative;
3 | width: 100%;
4 | flex-shrink: 0;
5 | }
6 | .popUpDiv {
7 | position: absolute;
8 | top: 50%;
9 | left: 50%;
10 | transform: translate(-50%, -50%);
11 | background-color: #fff;
12 | min-height: 300px;
13 | display: flex;
14 | flex-direction: column;
15 | padding: var(--padding-xs) 15px;
16 | box-sizing: border-box;
17 | align-items: center;
18 | justify-content: flex-start;
19 | width: 90%;
20 | max-height: 90%;
21 | max-width: 500px;
22 | border: 2px solid var(--neutral-300);
23 | border-radius: 5px;
24 | box-shadow: rgba(99, 99, 99, 0.2) 0px 2px 8px 0px;
25 | }
26 |
27 | .popup {
28 | position: absolute;
29 | top: 0;
30 | left: 0;
31 | width: 100%;
32 | height: 100%;
33 | background-color: rgba(0, 0, 0, 0.5);
34 | }
35 |
36 | .textAreaOutlinedTextField {
37 | margin: 20px 0 !important;
38 | }
39 |
40 | .buttonContainedText {
41 | display: flex;
42 | margin: 20px auto !important;
43 | }
44 |
45 | .header {
46 | display: flex;
47 | justify-content: space-between;
48 | align-items: center;
49 | width: 100%;
50 | height: 50px;
51 | padding: 0 10px;
52 | margin-bottom: 20px;
53 | }
54 |
55 | .copyBox {
56 | display: flex;
57 | position: relative;
58 | margin: 20px 0;
59 | width: 100%;
60 | }
61 |
62 | .imgDiv {
63 | width: 100%;
64 | flex: 1;
65 | background-color: transparent;
66 | border: 1px solid blueviolet;
67 | height: 60px;
68 | border-radius: 5px;
69 | display: flex;
70 | justify-content: center;
71 | align-items: center;
72 | font-family: "Roboto", "Helvetica", "Arial", sans-serif;
73 | }
74 |
75 | .imgHelperText {
76 | position: absolute;
77 | top: 105%;
78 | left: 10px;
79 | margin: 0;
80 | padding: 0;
81 | font-size: 12px;
82 | color: var(--neutral-500);
83 | }
84 |
85 | .pixelImg {
86 | opacity: 0;
87 | }
88 |
--------------------------------------------------------------------------------
/src/styles/components/Spinner.module.css:
--------------------------------------------------------------------------------
1 | .spinner {
2 | display: inline-block;
3 | border-color: rgb(209, 213, 219);
4 | border-top-color: rgb(30, 58, 138);
5 | border-radius: 9999px;
6 | animation: spin 1s linear infinite;
7 | border-width: 3px;
8 | width: 2.5rem;
9 | height: 2.5rem;
10 | }
11 |
12 | .spinner-sm {
13 | composes: spinner;
14 | border-width: 2px;
15 | width: 1.25rem;
16 | height: 1.25rem;
17 | }
18 |
19 | @keyframes spin {
20 | to {
21 | transform: rotate(360deg);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/styles/global.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap");
2 | @import url("https://fonts.googleapis.com/css2?family=Manrope:wght@400;600;800&display=swap");
3 | @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&display=swap");
4 | @import url("https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;700;800&display=swap");
5 | body {
6 | margin: 0;
7 | line-height: normal;
8 | }
9 | :root {
10 | /* fonts */
11 | --font-manrope: Manrope;
12 | --inter-regular-18px: Inter;
13 | --bold-52px: Poppins;
14 | --regular-13px1: "Plus Jakarta Sans";
15 |
16 | /* font sizes */
17 | --text-xs-medium-size: 12px;
18 | --regular-13px1-size: 14px;
19 | --bold-16px1-size: 16px;
20 | --pj-regular-18px-size: 18px;
21 | --pj-bold-21px-size: 21px;
22 | --bold-32px-size: 32px;
23 | --pj-bold-42px-size: 42px;
24 | --pj-bold-52px-size: 52px;
25 |
26 | /* Colors */
27 | --shades-white: #fff;
28 | --gray-50: #f9fafb;
29 | --success-50: #ecfdf3;
30 | --gray-100: #f2f4f7;
31 | --color-gray-400: #eaecf0;
32 | --gray-200: #e4e4e7;
33 | --neutral-200: #d0d5dd;
34 | --gray-400: #a1a1aa;
35 | --color-gray-800: #94a3b8;
36 | --neutral-500: #64748b;
37 | --gray-500: #667085;
38 | --gray-600: #52525b;
39 | --blue-gray-700: #334155;
40 | --gray-700: #344054;
41 | --blue-gray-800: #1e293b;
42 | --color-gray-1500: #27272a;
43 | --neutral-800: #191d23;
44 | --gray-900: #18181b;
45 | --gray-900: #101828;
46 | --blue-gray-900: #0f172a;
47 | --success-green-700: #047857;
48 | --success-700: #027a48;
49 | --blue-600: #2563eb;
50 | --base-black: #000;
51 |
52 | /* Gaps */
53 | --gap-2xs: 4px;
54 | --gap-xs: 8px;
55 | --gap-sm: 9px;
56 | --gap-md: 10px;
57 | --gap-lg: 16px;
58 | --gap-xl: 24px;
59 |
60 | /* Paddings */
61 | --padding-3xs: 2px;
62 | --padding-2xs: 8px;
63 | --padding-xs: 10px;
64 | --padding-sm: 12px;
65 | --padding-md: 16px;
66 | --padding-lg: 17px;
67 | --padding-xl: 22px;
68 | --padding-2xl: 24px;
69 | --padding-3xl: 26px;
70 |
71 | /* border radiuses */
72 | --br-2xs: 4px;
73 | --br-xs: 5px;
74 | --br-sm: 10px;
75 | --br-md: 16px;
76 | --br-lg: 35px;
77 | --br-xl: 50px;
78 |
79 | /* Effects */
80 | --shadow-md: 0px 4px 8px -2px rgba(16, 24, 40, 0.1),
81 | 0px 2px 4px -2px rgba(16, 24, 40, 0.06);
82 | }
83 |
--------------------------------------------------------------------------------
/src/styles/pages/Dashboard.module.css:
--------------------------------------------------------------------------------
1 | .supportingTextDiv,
2 | .textDiv {
3 | align-self: stretch;
4 | position: relative;
5 | display: inline-block;
6 | }
7 | .textDiv {
8 | line-height: 28px;
9 | font-weight: 500;
10 | }
11 | .supportingTextDiv {
12 | font-size: var(--regular-13px1-size);
13 | line-height: 20px;
14 | color: var(--gray-500);
15 | }
16 | .cardHeaderDiv,
17 | .contentDiv,
18 | .textAndSupportingText {
19 | display: flex;
20 | align-items: flex-start;
21 | justify-content: flex-start;
22 | }
23 | .textAndSupportingText {
24 | flex: 1;
25 | flex-direction: column;
26 | gap: var(--gap-2xs);
27 | }
28 | .cardHeaderDiv,
29 | .contentDiv {
30 | align-self: stretch;
31 | }
32 | .contentDiv {
33 | flex-direction: row;
34 | padding: 20px var(--padding-2xl) 19px;
35 | box-sizing: border-box;
36 | }
37 | .cardHeaderDiv {
38 | background-color: var(--shades-white);
39 | flex-direction: column;
40 | }
41 | .textDiv1 {
42 | position: relative;
43 | line-height: 18px;
44 | font-weight: 500;
45 | display: inline-block;
46 | }
47 | .arrowDownIcon {
48 | position: relative;
49 | width: 16px;
50 | height: 16px;
51 | flex-shrink: 0;
52 | overflow: hidden;
53 | }
54 | .tableHeaderCell,
55 | .tableHeaderDiv {
56 | display: flex;
57 | flex-direction: row;
58 | align-items: center;
59 | justify-content: flex-start;
60 | }
61 | .tableHeaderDiv {
62 | gap: var(--gap-2xs);
63 | }
64 | .tableHeaderCell {
65 | align-self: stretch;
66 | background-color: var(--gray-50);
67 | border-top: 0 solid var(--color-gray-400);
68 | border-right: 0 solid var(--color-gray-400);
69 | border-bottom: 1px solid var(--color-gray-400);
70 | border-left: 0 solid var(--color-gray-400);
71 | box-sizing: border-box;
72 | position: relative;
73 | height: 44px;
74 | flex-shrink: 0;
75 | padding: var(--padding-sm) var(--padding-2xl);
76 | font-size: var(--text-xs-medium-size);
77 | color: var(--gray-500);
78 | }
79 | .supportingTextDiv1,
80 | .textDiv2 {
81 | position: relative;
82 | line-height: 20px;
83 | display: inline-block;
84 | }
85 | .textDiv2 {
86 | font-weight: 500;
87 | }
88 | .supportingTextDiv1 {
89 | color: var(--gray-500);
90 | }
91 | .tableCellDiv {
92 | align-self: stretch;
93 | border-top: 0 solid var(--color-gray-400);
94 | border-right: 0 solid var(--color-gray-400);
95 | border-bottom: 1px solid var(--color-gray-400);
96 | border-left: 0 solid var(--color-gray-400);
97 | box-sizing: border-box;
98 | position: relative;
99 | height: 72px;
100 | flex-shrink: 0;
101 | flex-direction: row;
102 | padding: var(--padding-md) var(--padding-2xl);
103 | align-items: center;
104 | }
105 | .columnDiv,
106 | .tableCellDiv,
107 | .tableHeaderDiv1 {
108 | display: flex;
109 | justify-content: flex-start;
110 | }
111 | .columnDiv {
112 | min-width: 250px;
113 | flex-shrink: 0;
114 | flex-direction: column;
115 | align-items: flex-start;
116 | color: var(--gray-900);
117 | }
118 | .tableHeaderDiv1 {
119 | flex-direction: row;
120 | align-items: center;
121 | }
122 | .badgeBaseDiv,
123 | .tableHeaderCell1 {
124 | box-sizing: border-box;
125 | align-items: center;
126 | }
127 | .tableHeaderCell1 {
128 | align-self: stretch;
129 | background-color: var(--gray-50);
130 | border-top: 0 solid var(--color-gray-400);
131 | border-right: 0 solid var(--color-gray-400);
132 | border-bottom: 1px solid var(--color-gray-400);
133 | border-left: 0 solid var(--color-gray-400);
134 | position: relative;
135 | height: 44px;
136 | flex-shrink: 0;
137 | display: flex;
138 | flex-direction: row;
139 | padding: var(--padding-sm) var(--padding-2xl);
140 | justify-content: flex-start;
141 | text-align: left;
142 | color: var(--gray-500);
143 | }
144 | .badgeBaseDiv {
145 | border-radius: var(--br-md);
146 | background-color: var(--success-50);
147 | padding: var(--padding-3xs) var(--padding-2xs);
148 | justify-content: center;
149 | }
150 | .badgeBaseDiv,
151 | .badgeBaseDiv1,
152 | .badgeDiv {
153 | display: flex;
154 | flex-direction: row;
155 | }
156 | .badgeDiv {
157 | align-items: flex-start;
158 | justify-content: flex-start;
159 | mix-blend-mode: multiply;
160 | }
161 | .badgeBaseDiv1 {
162 | border-radius: var(--br-md);
163 | background-color: var(--gray-100);
164 | padding: var(--padding-3xs) var(--padding-2xs);
165 | box-sizing: border-box;
166 | align-items: center;
167 | justify-content: center;
168 | }
169 | .columnDiv1,
170 | .tableCellDiv8 {
171 | flex-shrink: 0;
172 | display: flex;
173 | justify-content: flex-start;
174 | }
175 | .tableCellDiv8 {
176 | align-self: stretch;
177 | border-top: 0 solid var(--color-gray-400);
178 | border-right: 0 solid var(--color-gray-400);
179 | border-bottom: 1px solid var(--color-gray-400);
180 | border-left: 0 solid var(--color-gray-400);
181 | box-sizing: border-box;
182 | position: relative;
183 | height: 72px;
184 | flex-direction: row;
185 | padding: var(--padding-md) var(--padding-2xl);
186 | align-items: center;
187 | color: var(--gray-700);
188 | }
189 | .columnDiv1 {
190 | min-width: 75px;
191 | flex-direction: column;
192 | align-items: flex-start;
193 | text-align: center;
194 | font-size: var(--text-xs-medium-size);
195 | color: var(--success-700);
196 | }
197 | .textDiv18 {
198 | position: relative;
199 | line-height: 20px;
200 | display: inline-block;
201 | }
202 | .textAndSupportingText8 {
203 | align-self: stretch;
204 | flex-direction: column;
205 | align-items: flex-start;
206 | }
207 | .columnDiv2,
208 | .dateDiv,
209 | .textAndSupportingText8 {
210 | display: flex;
211 | justify-content: flex-start;
212 | }
213 | .columnDiv2 {
214 | min-width: 275px;
215 | flex-shrink: 0;
216 | flex-direction: column;
217 | align-items: flex-start;
218 | color: var(--gray-900);
219 | }
220 | .dateDiv {
221 | flex: 1;
222 | align-self: stretch;
223 | flex-direction: row;
224 | align-items: center;
225 | }
226 | .columnDiv3,
227 | .tableHeaderCell5 {
228 | flex-shrink: 0;
229 | display: flex;
230 | justify-content: flex-start;
231 | }
232 | .columnDiv3 {
233 | min-width: 200px;
234 | flex-direction: column;
235 | align-items: flex-start;
236 | color: var(--gray-700);
237 | }
238 | .tableHeaderCell5 {
239 | align-self: stretch;
240 | background-color: var(--gray-50);
241 | border-top: 0 solid var(--color-gray-400);
242 | border-right: 0 solid var(--color-gray-400);
243 | border-bottom: 1px solid var(--color-gray-400);
244 | border-left: 0 solid var(--color-gray-400);
245 | box-sizing: border-box;
246 | position: relative;
247 | height: 44px;
248 | flex-direction: row;
249 | padding: var(--padding-sm) var(--padding-2xl);
250 | align-items: center;
251 | font-size: var(--text-xs-medium-size);
252 | }
253 | .columnDiv5 {
254 | display: none;
255 | flex-direction: column;
256 | align-items: flex-start;
257 | justify-content: flex-start;
258 | }
259 | .tableHeaderCell8 {
260 | align-self: stretch;
261 | background-color: var(--gray-50);
262 | border-top: 0 solid var(--color-gray-400);
263 | border-right: 0 solid var(--color-gray-400);
264 | border-bottom: 1px solid var(--color-gray-400);
265 | border-left: 0 solid var(--color-gray-400);
266 | box-sizing: border-box;
267 | position: relative;
268 | height: 44px;
269 | flex-shrink: 0;
270 | }
271 |
272 | .tableCellButton {
273 | display: flex;
274 | flex-direction: column;
275 | align-items: flex-start;
276 | justify-content: flex-start;
277 | }
278 | .tableCellButton {
279 | border: 0;
280 | padding: var(--padding-md) var(--padding-2xl);
281 | background-color: transparent;
282 | align-self: stretch;
283 | border-top: 0 solid var(--color-gray-400);
284 | border-right: 0 solid var(--color-gray-400);
285 | border-bottom: 1px solid var(--color-gray-400);
286 | border-left: 0 solid var(--color-gray-400);
287 | box-sizing: border-box;
288 | position: relative;
289 | height: 72px;
290 | flex-shrink: 0;
291 | flex-direction: row;
292 | align-items: center;
293 | }
294 | .contentDiv1,
295 | .tableDiv {
296 | background-color: var(--shades-white);
297 | display: flex;
298 | align-items: flex-start;
299 | justify-content: flex-start;
300 | }
301 | .contentDiv1 {
302 | align-self: stretch;
303 | flex-direction: row;
304 | font-size: var(--regular-13px1-size);
305 | color: var(--gray-500);
306 | }
307 | .tableDiv {
308 | border-radius: 8px;
309 | box-shadow: var(--shadow-md);
310 | border: 1px solid var(--color-gray-400);
311 | box-sizing: border-box;
312 | min-width: 950px;
313 | flex-direction: column;
314 | margin-left: 25px;
315 | }
316 | .contactMailIcon {
317 | position: relative;
318 | width: 41px;
319 | height: 41px;
320 | flex-shrink: 0;
321 | overflow: hidden;
322 | }
323 | .mAILBESDiv {
324 | position: relative;
325 | font-weight: 800;
326 | background: linear-gradient(-88.11deg, #059669, #00d995);
327 | -webkit-background-clip: text;
328 | background-clip: text;
329 | -webkit-text-fill-color: transparent;
330 | display: inline-block;
331 | }
332 | .logoA {
333 | cursor: pointer;
334 | text-decoration: none;
335 | align-self: stretch;
336 | display: flex;
337 | flex-direction: row;
338 | align-items: center;
339 | justify-content: flex-start;
340 | gap: var(--gap-xs);
341 | font-size: 24px;
342 | }
343 | .buttonDiv {
344 | position: relative;
345 | font-size: var(--bold-16px1-size);
346 | font-weight: 600;
347 | font-family: var(--font-manrope);
348 | color: var(--shades-white);
349 | text-align: left;
350 | display: inline-block;
351 | }
352 | .cTAButton {
353 | cursor: pointer;
354 | border: 0;
355 | padding: var(--padding-2xs) var(--padding-sm);
356 | background-color: var(--success-green-700);
357 | align-self: stretch;
358 | border-radius: var(--br-2xs);
359 | height: 44px;
360 | flex-shrink: 0;
361 | display: flex;
362 | flex-direction: row;
363 | box-sizing: border-box;
364 | align-items: center;
365 | justify-content: center;
366 | gap: var(--gap-md);
367 | }
368 | .titleDiv {
369 | align-self: stretch;
370 | position: relative;
371 | font-weight: 600;
372 | display: inline-block;
373 | }
374 | .icon1 {
375 | position: relative;
376 | width: 24px;
377 | height: 24px;
378 | flex-shrink: 0;
379 | overflow: hidden;
380 | }
381 | .overviewDiv {
382 | flex: 1;
383 | position: relative;
384 | font-weight: 600;
385 | display: inline-block;
386 | }
387 | .menuDiv,
388 | .navDiv,
389 | .overviewA {
390 | align-self: stretch;
391 | display: flex;
392 | justify-content: flex-start;
393 | }
394 | .overviewA {
395 | text-decoration: none;
396 | border-radius: var(--br-2xs);
397 | background-color: var(--neutral-100);
398 | flex-direction: row;
399 | padding: var(--padding-sm);
400 | box-sizing: border-box;
401 | align-items: center;
402 | gap: var(--gap-xs);
403 | color: inherit;
404 | }
405 | .menuDiv,
406 | .navDiv {
407 | flex-direction: column;
408 | align-items: flex-start;
409 | }
410 | .navDiv {
411 | color: var(--neutral-800);
412 | }
413 | .menuDiv {
414 | gap: var(--gap-lg);
415 | }
416 | .div {
417 | position: relative;
418 | font-weight: 600;
419 | display: inline-block;
420 | }
421 | .frameDiv,
422 | .notifications {
423 | display: flex;
424 | box-sizing: border-box;
425 | justify-content: flex-start;
426 | }
427 | .frameDiv {
428 | border-radius: var(--br-2xs);
429 | background-color: var(--success-green-700);
430 | flex-direction: column;
431 | padding: 0 var(--padding-xs);
432 | align-items: flex-start;
433 | color: var(--shades-white);
434 | }
435 | .notifications {
436 | text-decoration: none;
437 | align-self: stretch;
438 | flex-direction: row;
439 | padding: var(--padding-2xs) var(--padding-sm);
440 | align-items: center;
441 | gap: var(--gap-xs);
442 | color: var(--neutral-800);
443 | }
444 | .divider,
445 | .image1Icon {
446 | position: relative;
447 | flex-shrink: 0;
448 | }
449 | .divider {
450 | border-top: 1px solid var(--neutral-200);
451 | box-sizing: border-box;
452 | width: 252px;
453 | height: 1px;
454 | }
455 | .image1Icon {
456 | width: 42px;
457 | height: 42.03px;
458 | object-fit: cover;
459 | }
460 | .aashishpanthi11gmailcomDiv {
461 | align-self: stretch;
462 | position: relative;
463 | font-weight: 600;
464 | color: var(--neutral-400);
465 | display: inline-block;
466 | }
467 | .frameDiv2,
468 | .labelDiv {
469 | color: var(--neutral-800);
470 | }
471 | .frameDiv2 {
472 | align-self: stretch;
473 | display: flex;
474 | flex-direction: row;
475 | align-items: center;
476 | justify-content: flex-start;
477 | gap: var(--gap-xs);
478 | }
479 | .labelDiv {
480 | position: relative;
481 | font-size: var(--bold-16px1-size);
482 | font-weight: 600;
483 | font-family: var(--font-manrope);
484 | text-align: left;
485 | display: inline-block;
486 | }
487 | .layoutDiv,
488 | .logOutButton {
489 | display: flex;
490 | flex-direction: row;
491 | box-sizing: border-box;
492 | align-items: center;
493 | justify-content: center;
494 | }
495 | .layoutDiv {
496 | overflow: hidden;
497 | padding: 0 4px;
498 | }
499 | .logOutButton {
500 | cursor: pointer;
501 | border: 0;
502 | padding: 6px var(--padding-2xs);
503 | background-color: var(--gray-100);
504 | align-self: stretch;
505 | border-radius: var(--br-2xs);
506 | gap: var(--gap-2xs);
507 | }
508 | .dashboardDiv,
509 | .sideBarDiv {
510 | background-color: var(--shades-white);
511 | }
512 | .sideBarDiv {
513 | border-radius: var(--br-2xs);
514 | max-width: 300px;
515 | width: 100%;
516 | min-width: 200px;
517 | display: flex;
518 | flex-direction: column;
519 | padding: var(--padding-2xl);
520 | box-sizing: border-box;
521 | align-items: center;
522 | justify-content: flex-start;
523 | gap: var(--gap-xl);
524 | font-size: var(--bold-16px1-size);
525 | color: var(--neutral-500);
526 | font-family: var(--font-manrope);
527 | border-right: 1px solid var(--color-gray-400);
528 | }
529 | .dashboardDiv {
530 | position: relative;
531 | width: 100%;
532 | min-height: 100vh;
533 | overflow: hidden;
534 | text-align: left;
535 | font-size: var(--pj-regular-18px-size);
536 | color: var(--gray-900);
537 | font-family: var(--inter-regular-18px);
538 | display: flex;
539 | }
540 |
541 | .loader {
542 | width: 100%;
543 | height: 100%;
544 | display: flex;
545 | justify-content: center;
546 | align-items: center;
547 | }
548 |
--------------------------------------------------------------------------------
/src/styles/pages/Home.module.css:
--------------------------------------------------------------------------------
1 | .hELPMENUB,
2 | .weAreHereToHelpYouSuceed {
3 | display: inline-block;
4 | }
5 | .weAreHereToHelpYouSuceed {
6 | line-height: 22px;
7 | width: 396px;
8 | height: 98px;
9 | }
10 | .hELPMENUB {
11 | font-size: var(--bold-16px1-size);
12 | line-height: 24px;
13 | color: var(--gray-900);
14 | }
15 | .a,
16 | .logoTwitter2Icon {
17 | width: 16px;
18 | height: 12.87px;
19 | }
20 | .a {
21 | text-decoration: none;
22 | top: 3.86px;
23 | }
24 | .a1,
25 | .logoFbSimple2Icon {
26 | width: 9.05px;
27 | height: 17.35px;
28 | }
29 | .a1 {
30 | text-decoration: none;
31 | top: 1.29px;
32 | left: 50.34px;
33 | }
34 | .a2,
35 | .logoInstagram1Icon {
36 | width: 19.4px;
37 | height: 19.31px;
38 | }
39 | .a2 {
40 | text-decoration: none;
41 | left: 93.73px;
42 | }
43 | .a3,
44 | .logoGithub1Icon {
45 | width: 18.56px;
46 | height: 18.02px;
47 | }
48 | .a3 {
49 | text-decoration: none;
50 | left: 147.46px;
51 | }
52 |
53 | .socialDiv {
54 | display: flex;
55 | width: 100px;
56 | justify-content: space-between;
57 | }
58 |
59 | .widgetsDiv {
60 | display: flex;
61 | justify-content: space-between;
62 | width: 100%;
63 | margin-top: 25px;
64 | }
65 |
66 | .widget0Div {
67 | max-width: 396px;
68 | color: var(--gray-600);
69 | padding: 10px;
70 | }
71 | .career {
72 | display: inline-block;
73 | }
74 | .career,
75 | .features,
76 | .worksA {
77 | text-decoration: none;
78 | line-height: 40px;
79 | color: inherit;
80 | }
81 | .worksA {
82 | display: inline-block;
83 | }
84 |
85 | .about,
86 | .features,
87 | .hELPMENUB1 {
88 | display: inline-block;
89 | }
90 | .about {
91 | text-decoration: none;
92 | top: 45px;
93 | line-height: 40px;
94 | color: inherit;
95 | }
96 | .hELPMENUB1 {
97 | top: 0;
98 | font-size: var(--bold-16px1-size);
99 | line-height: 24px;
100 | }
101 | .widget1Div {
102 | width: 77px;
103 | height: 205px;
104 | }
105 | .customerSupport,
106 | .serviceDetails {
107 | margin-block-start: 0;
108 | margin-block-end: 0;
109 | }
110 | .serviceDetails {
111 | color: var(--gray-900);
112 | }
113 | .privacyPolicy {
114 | margin: 0;
115 | }
116 | .aboutFeaturesWorks {
117 | line-height: 40px;
118 | white-space: pre-wrap;
119 | display: inline-block;
120 | }
121 | .widget2Div {
122 | width: 128px;
123 | height: 205px;
124 | color: var(--color-gray-1500);
125 | }
126 | .pricingPlans {
127 | line-height: 42px;
128 | display: inline-block;
129 | width: 405px;
130 | }
131 | .buttonName {
132 | position: relative;
133 | font-size: var(--regular-13px1-size);
134 | line-height: 22px;
135 | display: inline-block;
136 | font-family: var(--regular-13px1);
137 | color: var(--shades-white);
138 | text-align: right;
139 | }
140 | .iconOutlinearrowRight {
141 | position: relative;
142 | width: 18px;
143 | height: 18px;
144 | flex-shrink: 0;
145 | }
146 | .iconDiv {
147 | display: none;
148 | flex-direction: row;
149 | align-items: center;
150 | justify-content: center;
151 | }
152 | .buttonPrimaryWithIcon,
153 | .frameDiv {
154 | display: flex;
155 | align-items: center;
156 | justify-content: center;
157 | }
158 | .frameDiv {
159 | flex-direction: row;
160 | gap: var(--gap-sm);
161 | }
162 | .buttonPrimaryWithIcon {
163 | cursor: pointer;
164 | text-decoration: none;
165 | border: 1.5px solid var(--gray-900);
166 | padding: var(--padding-md);
167 | background-color: var(--gray-900);
168 | border-radius: 60px;
169 | box-sizing: border-box;
170 | height: 50px;
171 | flex-direction: column;
172 | }
173 | .contentDiv,
174 | .lineDiv {
175 | width: 100%;
176 | }
177 |
178 | .contentDiv {
179 | min-height: 84px;
180 | font-size: var(--bold-32px-size);
181 | display: flex;
182 | align-items: center;
183 | justify-content: space-between;
184 | padding: 10px;
185 | }
186 | .lineDiv {
187 | top: 220.5px;
188 | left: 151.5px;
189 | border-top: 1px solid var(--gray-200);
190 | box-sizing: border-box;
191 | height: 1px;
192 | }
193 | .footer {
194 | max-width: 1200px;
195 | min-height: 200px;
196 | margin: 0 auto;
197 | text-align: left;
198 | font-size: var(--regular-13px1-size);
199 | color: var(--gray-900);
200 | font-family: var(--regular-13px1);
201 | margin-top: 100px;
202 | }
203 | .sendB,
204 | .sendEmailDirectlyFromTheD {
205 | line-height: 28px;
206 | display: inline-block;
207 | width: 315px;
208 | }
209 | .sendEmailDirectlyFromTheD {
210 | font-size: var(--bold-16px1-size);
211 | line-height: 26px;
212 | color: var(--gray-600);
213 | width: 283px;
214 | }
215 |
216 | .sendIcon {
217 | width: 63px;
218 | height: 63px;
219 | object-fit: cover;
220 | }
221 | .div {
222 | position: relative;
223 | width: 315px;
224 | height: 195px;
225 | }
226 | .knowIfTheUserReadTheEmai,
227 | .statusB {
228 | line-height: 28px;
229 | display: inline-block;
230 | width: 315px;
231 | }
232 | .knowIfTheUserReadTheEmai {
233 | font-size: var(--bold-16px1-size);
234 | line-height: 26px;
235 | color: var(--gray-600);
236 | width: 240px;
237 | }
238 | .vectorIcon {
239 | height: 24.8%;
240 | width: 14.6%;
241 | max-width: 100%;
242 | overflow: hidden;
243 | max-height: 100%;
244 | }
245 | .div1 {
246 | position: relative;
247 | width: 315px;
248 | height: 193px;
249 | }
250 | .findOutExactlyWhenTheRece,
251 | .historyB {
252 | line-height: 28px;
253 | display: inline-block;
254 | width: 315px;
255 | }
256 | .findOutExactlyWhenTheRece {
257 | font-size: var(--bold-16px1-size);
258 | line-height: 26px;
259 | color: var(--gray-600);
260 | width: 290px;
261 | }
262 | .vectorIcon1 {
263 | height: 19.47%;
264 | width: 13.02%;
265 | max-width: 100%;
266 | overflow: hidden;
267 | max-height: 100%;
268 | }
269 | .div2 {
270 | position: relative;
271 | width: 315px;
272 | height: 187px;
273 | }
274 |
275 | .listDiv {
276 | display: flex;
277 | max-width: 996px;
278 | flex-wrap: wrap;
279 | }
280 |
281 | .exploreTheUnexploredPotenti {
282 | font-size: var(--pj-regular-18px-size);
283 | color: var(--gray-600);
284 | margin-bottom: 30px;
285 | }
286 |
287 | .contentDiv1 {
288 | max-width: 616px;
289 | margin: 0 auto;
290 | margin-top: 100px;
291 | font-size: var(--pj-bold-42px-size);
292 | }
293 | .featureDiv {
294 | max-width: 996px;
295 | position: relative;
296 | margin: 25px auto;
297 | margin-top: 50px;
298 | }
299 | .bGIframe,
300 | .videoNav {
301 | width: 880px;
302 | height: 526px;
303 | margin: 0 auto;
304 | margin-top: 50px;
305 | }
306 | .bGIframe {
307 | top: 0;
308 | left: 0;
309 | border-radius: var(--br-sm);
310 | background-color: var(--shades-white);
311 | box-shadow: 0 24px 164px -20px rgba(35, 40, 105, 0.15);
312 | }
313 |
314 | .knowIfYourEmailHasBeenRe {
315 | line-height: 62px;
316 | font-weight: 800;
317 | font-family: var(--regular-13px1);
318 | display: inline-block;
319 | width: 627px;
320 | }
321 | .createYourAccountForFree,
322 | .smartEmailStatusFinderMa {
323 | font-size: var(--pj-regular-18px-size);
324 | line-height: 28px;
325 | color: var(--gray-600);
326 | display: inline-block;
327 | width: 533px;
328 | }
329 | .createYourAccountForFree {
330 | font-size: var(--bold-16px1-size);
331 | line-height: 26px;
332 | color: var(--gray-5001);
333 | }
334 | .buttonName1 {
335 | position: relative;
336 | font-size: var(--pj-regular-18px-size);
337 | line-height: 24px;
338 | display: inline-block;
339 | font-family: var(--regular-13px1);
340 | color: var(--shades-white);
341 | text-align: right;
342 | }
343 | .buttonPrimaryWithIcon1,
344 | .iconDiv2 {
345 | display: flex;
346 | align-items: center;
347 | justify-content: center;
348 | }
349 | .buttonPrimaryWithIcon1 {
350 | text-decoration: none;
351 | cursor: pointer;
352 | border: 0;
353 | padding: var(--padding-md);
354 | background-color: var(--base-black);
355 | border-radius: var(--br-sm);
356 | width: 222px;
357 | height: 56px;
358 | flex-direction: column;
359 | box-sizing: border-box;
360 | margin-right: 10px;
361 | }
362 | .iconDiv2 {
363 | flex-direction: row;
364 | }
365 | .buttonName2 {
366 | position: relative;
367 | font-size: var(--pj-regular-18px-size);
368 | line-height: 24px;
369 | display: inline-block;
370 | font-family: var(--regular-13px1);
371 | color: var(--gray-900);
372 | text-align: right;
373 | }
374 | .buttonPrimaryWithIconLeft,
375 | .frameDiv2 {
376 | display: flex;
377 | align-items: center;
378 | justify-content: center;
379 | }
380 | .frameDiv2 {
381 | flex-direction: row;
382 | gap: var(--gap-md);
383 | }
384 | .buttonPrimaryWithIconLeft {
385 | cursor: pointer;
386 | border: 2px solid var(--gray-400);
387 | padding: var(--padding-md);
388 | background-color: transparent;
389 | border-radius: var(--br-sm);
390 | box-sizing: border-box;
391 | width: 246px;
392 | height: 56px;
393 | flex-direction: column;
394 | }
395 | .buttonsDiv {
396 | display: flex;
397 | align-items: center;
398 | }
399 | .contentDiv2 {
400 | width: 100%;
401 | min-height: 324px;
402 | display: flex;
403 | align-items: center;
404 | justify-content: center;
405 | flex-direction: column;
406 | margin: 50px 0 20px 0;
407 | }
408 |
409 | .contentDiv2 > div {
410 | margin-bottom: 15px;
411 | }
412 |
413 | .mailbes {
414 | font-size: var(--bold-16px1-size);
415 | letter-spacing: 3px;
416 | line-height: 30px;
417 | text-transform: uppercase;
418 | display: inline-block;
419 | font-family: var(--regular-13px1);
420 | color: var(--gray-900);
421 | text-align: left;
422 | }
423 |
424 | .logoA {
425 | text-decoration: none;
426 | }
427 | .loginButton {
428 | cursor: pointer;
429 | border: 0;
430 | padding: 0;
431 | background-color: transparent;
432 | font-size: var(--bold-16px1-size);
433 | line-height: 24px;
434 | font-weight: 500;
435 | font-family: var(--regular-13px1);
436 | color: var(--gray-900);
437 | text-align: right;
438 | display: inline-block;
439 | }
440 | .menuDiv {
441 | display: flex;
442 | align-items: center;
443 | }
444 |
445 | .buttonName3 {
446 | position: relative;
447 | font-size: var(--bold-16px1-size);
448 | line-height: 28px;
449 | display: inline-block;
450 | font-family: var(--regular-13px1);
451 | color: var(--shades-white);
452 | text-align: right;
453 | }
454 | .buttonPrimaryWithIcon2 {
455 | cursor: pointer;
456 | border: 0;
457 | padding: var(--padding-md);
458 | background-color: var(--base-black);
459 | border-radius: var(--br-sm);
460 | width: 114px;
461 | height: 45px;
462 | display: flex;
463 | flex-direction: column;
464 | box-sizing: border-box;
465 | align-items: center;
466 | justify-content: center;
467 | }
468 |
469 | .heroDiv {
470 | font-size: var(--pj-bold-52px-size);
471 | font-family: var(--inter-regular-18px);
472 | min-height: 500px;
473 | }
474 |
475 | .headerNav {
476 | display: flex;
477 | justify-content: space-between;
478 | align-items: center;
479 | padding: 0 20px;
480 | height: 80px;
481 | max-width: 1200px;
482 | margin: 0 auto;
483 | }
484 |
485 | .headerNav .buttonPrimaryWithIcon2,
486 | .headerNav .loginButton {
487 | margin-left: 15px;
488 | text-decoration: none;
489 | }
490 |
491 | .homeDiv {
492 | position: relative;
493 | background-color: #fafafa;
494 | width: 100%;
495 | min-height: 100vh;
496 | text-align: center;
497 | font-size: var(--pj-bold-21px-size);
498 | color: var(--gray-900);
499 | font-family: var(--regular-13px1);
500 | }
501 |
--------------------------------------------------------------------------------
/src/styles/pages/PageNotFound.module.css:
--------------------------------------------------------------------------------
1 | .illustrationIcon {
2 | position: relative;
3 | width: 182.93px;
4 | height: 118.15px;
5 | flex-shrink: 0;
6 | }
7 | .icons,
8 | .textDiv {
9 | position: relative;
10 | }
11 | .icons {
12 | width: 12px;
13 | height: 12px;
14 | flex-shrink: 0;
15 | }
16 | .textDiv {
17 | font-weight: 600;
18 | display: inline-block;
19 | }
20 | .badgeDiv {
21 | border-radius: var(--br-2xs);
22 | background-color: var(--error-red-50);
23 | display: flex;
24 | flex-direction: row;
25 | padding: var(--padding-3xs) var(--padding-xs);
26 | box-sizing: border-box;
27 | align-items: center;
28 | justify-content: flex-start;
29 | gap: var(--gap-xs);
30 | }
31 | .titleDiv {
32 | align-self: stretch;
33 | position: relative;
34 | font-size: 20px;
35 | font-weight: 600;
36 | color: var(--neutral-800);
37 | text-align: center;
38 | display: inline-block;
39 | }
40 | .headingDiv {
41 | align-self: stretch;
42 | display: flex;
43 | flex-direction: column;
44 | align-items: center;
45 | justify-content: flex-start;
46 | gap: var(--gap-xs);
47 | }
48 | .paragraphDiv {
49 | align-self: stretch;
50 | position: relative;
51 | font-size: var(--bold-16px1-size);
52 | color: var(--neutral-500);
53 | text-align: center;
54 | display: inline-block;
55 | }
56 | .contentDiv {
57 | align-self: stretch;
58 | display: flex;
59 | flex-direction: column;
60 | align-items: center;
61 | justify-content: flex-start;
62 | gap: var(--gap-lg);
63 | }
64 | .labelDiv {
65 | position: absolute;
66 | top: calc(50% - 10px);
67 | left: calc(50% - 81.5px);
68 | font-size: var(--bold-16px1-size);
69 | line-height: 20px;
70 | font-weight: 600;
71 | font-family: var(--font-manrope);
72 | color: var(--shades-white);
73 | text-align: center;
74 | display: inline-block;
75 | }
76 | .cTAButton {
77 | cursor: pointer;
78 | border: 0;
79 | padding: 0;
80 | background-color: var(--neutral-800);
81 | position: relative;
82 | border-radius: var(--br-2xs);
83 | width: 227px;
84 | height: 40px;
85 | flex-shrink: 0;
86 | overflow: hidden;
87 | }
88 | .containerDiv {
89 | align-self: stretch;
90 | flex-shrink: 0;
91 | display: flex;
92 | flex-direction: column;
93 | align-items: center;
94 | justify-content: center;
95 | gap: var(--gap-xl);
96 | }
97 | .errorDiv,
98 | .pageNotFound {
99 | background-color: var(--shades-white);
100 | }
101 | .errorDiv {
102 | border-radius: var(--br-2xs);
103 | max-width: 528px;
104 | display: flex;
105 | flex-direction: column;
106 | padding: 80px 32px;
107 | box-sizing: border-box;
108 | align-items: center;
109 | justify-content: flex-start;
110 | gap: var(--gap-xl);
111 | }
112 | .pageNotFound {
113 | position: relative;
114 | width: 100%;
115 | min-height: 100vh;
116 | font-size: 10px;
117 | color: var(--error-red-800);
118 | font-family: var(--font-manrope);
119 | display: flex;
120 | align-items: center;
121 | justify-content: center;
122 | }
123 |
--------------------------------------------------------------------------------
/src/styles/pages/Profile.module.css:
--------------------------------------------------------------------------------
1 | .container {
2 | display: flex;
3 | flex-direction: column;
4 | gap: 2rem;
5 | margin-left: 25px;
6 | min-width: 300px;
7 | width: 100%;
8 | box-sizing: border-box;
9 | }
10 |
11 | .info > h2 {
12 | font-size: 1.125rem;
13 | line-height: 1.75rem;
14 | }
15 | .info > p {
16 | margin-top: 0.25rem;
17 | color: rgb(107, 114, 128);
18 | line-height: 1.25;
19 | }
20 |
21 | @media (min-width: 640px) {
22 | .info {
23 | min-width: 320px;
24 | }
25 | .info > h2 {
26 | font-size: 1.25rem;
27 | line-height: 1.75rem;
28 | }
29 | }
30 |
31 | .card {
32 | width: 100%;
33 | max-width: 950px;
34 | background-color: rgb(255, 255, 255);
35 | border-width: 1px;
36 | border-radius: 0.375rem;
37 | border-color: rgba(229, 231, 235, 0.5);
38 | box-shadow: 0 0 #0000, 0 0 #0000, 0 4px 6px -1px rgb(0 0 0 / 0.1),
39 | 0 2px 4px -2px rgb(0 0 0 / 0.1);
40 | }
41 |
42 | .form-fields {
43 | display: flex;
44 | flex-direction: column;
45 | padding: 10px 20px;
46 | gap: 1rem;
47 | }
48 |
49 | .form-footer {
50 | width: 100%;
51 | display: flex;
52 | justify-content: flex-end;
53 | background-color: rgb(249, 250, 251);
54 | }
55 |
56 | .button {
57 | color: rgb(255, 255, 255);
58 | background-color: rgb(55, 65, 81);
59 | border-radius: 0.375rem;
60 | transition-property: color, background-color, opacity;
61 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
62 | transition-duration: 150ms;
63 | width: 100px;
64 | height: 40px;
65 | cursor: pointer;
66 | margin: 10px 20px;
67 | }
68 | .button:hover {
69 | background-color: rgb(75, 85, 99);
70 | }
71 | .button:focus {
72 | outline: 2px solid transparent;
73 | outline-offset: 2px;
74 | box-shadow: 0 0 0 calc(4px) rgb(55 65 81 / 0.2), 0 0 #0000;
75 | }
76 | .button:disabled {
77 | cursor: not-allowed;
78 | opacity: 0.5;
79 | }
80 | .button:disabled:hover {
81 | background-color: rgb(55, 65, 81);
82 | }
83 |
--------------------------------------------------------------------------------
/src/styles/pages/SignIn.module.css:
--------------------------------------------------------------------------------
1 | .formDiv {
2 | border-radius: var(--br-sm);
3 | background-color: var(--blue-gray-900);
4 | min-width: 350px;
5 | max-width: 450px;
6 | width: 100%;
7 | padding: 20px 25px;
8 | }
9 |
10 | .fIllInTheRequiredDetailsT {
11 | display: inline-block;
12 | }
13 | .welcomeBack {
14 | letter-spacing: -2px;
15 | line-height: 62px;
16 | font-weight: 600;
17 | }
18 | .fIllInTheRequiredDetailsT {
19 | margin: 12px 0;
20 | font-size: var(--pj-regular-18px-size);
21 | color: var(--color-gray-800);
22 | max-width: 450px;
23 | }
24 | .buttonNameDiv {
25 | position: relative;
26 | letter-spacing: -0.2px;
27 | line-height: 28px;
28 | font-weight: 600;
29 | display: inline-block;
30 | }
31 | .iconOutlinearrowRight {
32 | position: relative;
33 | width: 18px;
34 | height: 18px;
35 | flex-shrink: 0;
36 | overflow: hidden;
37 | }
38 | .iconDiv {
39 | display: none;
40 | flex-direction: row;
41 | align-items: center;
42 | justify-content: center;
43 | }
44 | .buttonPrimaryWithIconDiv,
45 | .frameDiv {
46 | display: flex;
47 | align-items: center;
48 | justify-content: center;
49 | }
50 | .frameDiv {
51 | flex-direction: row;
52 | gap: var(--gap-sm);
53 | }
54 | .buttonPrimaryWithIconDiv {
55 | border-radius: var(--br-lg);
56 | background-color: var(--blue-gray-800);
57 | width: 444px;
58 | flex-direction: column;
59 | padding: var(--padding-md);
60 | box-sizing: border-box;
61 | }
62 |
63 | .google2Icon {
64 | position: absolute;
65 | top: 19px;
66 | left: 106.7px;
67 | width: 23px;
68 | height: 23px;
69 | }
70 | .buttonDiv {
71 | position: relative;
72 | height: 60px;
73 | text-align: right;
74 | font-size: var(--bold-16px1-size);
75 | cursor: pointer;
76 | }
77 | .titleDiv {
78 | width: 100%;
79 | text-align: center;
80 | margin: 10px 0 30px 0;
81 | }
82 | .inputLabelDiv {
83 | position: relative;
84 | font-size: var(--regular-13px1-size);
85 | line-height: 22px;
86 | font-family: var(--bold-52px);
87 | color: var(--gray-200);
88 | text-align: left;
89 | display: inline-block;
90 | margin-bottom: 5px;
91 | }
92 | .frameInput {
93 | border: 1px solid var(--blue-gray-700);
94 | background-color: transparent;
95 | align-self: stretch;
96 | border-radius: var(--br-lg);
97 | box-sizing: border-box;
98 | position: relative;
99 | height: 60px;
100 | flex-shrink: 0;
101 | display: flex;
102 | flex-direction: row;
103 | padding: var(--padding-lg) var(--padding-xl);
104 | align-items: center;
105 | justify-content: flex-start;
106 | outline: none;
107 | color: white;
108 | }
109 | .inputTextStyle {
110 | width: 100%;
111 | flex-direction: column;
112 | align-items: flex-start;
113 | justify-content: center;
114 | margin: 15px 0;
115 | }
116 | .frameInput,
117 | .inputTextStyle {
118 | border-radius: var(--br-lg);
119 | display: flex;
120 | }
121 |
122 | .checkDiv {
123 | display: flex;
124 | margin: 12px 0;
125 | }
126 |
127 | .rememberMeDiv {
128 | font-size: var(--regular-13px1-size);
129 | font-family: var(--bold-52px);
130 | color: var(--shades-white);
131 | text-align: left;
132 | display: inline-block;
133 | margin-left: 5px;
134 | cursor: pointer;
135 | }
136 |
137 | .shapeInput {
138 | cursor: pointer;
139 | border-radius: var(--br-xs);
140 | border: 1px solid var(--blue-gray-700);
141 | box-sizing: border-box;
142 | width: 19px;
143 | height: 19px;
144 | }
145 |
146 | .buttonNameDiv1 {
147 | position: relative;
148 | font-size: var(--bold-16px1-size);
149 | letter-spacing: -0.2px;
150 | line-height: 28px;
151 | font-weight: 600;
152 | font-family: var(--bold-52px);
153 | color: var(--shades-white);
154 | text-align: center;
155 | display: inline-block;
156 | }
157 |
158 | .buttonPrimaryWithIcon {
159 | cursor: pointer;
160 | border: 0;
161 | padding: var(--padding-md);
162 | background-color: var(--blue-600);
163 | border-radius: var(--br-xl);
164 | width: 200px;
165 | height: 55px;
166 | display: flex;
167 | flex-direction: column;
168 | box-sizing: border-box;
169 | align-items: center;
170 | justify-content: center;
171 | }
172 | .createFreeAccount,
173 | .dontHaveAn {
174 | font-family: var(--bold-52px);
175 | color: var(--neutral-500);
176 | }
177 | .createFreeAccount {
178 | font-weight: 600;
179 | color: var(--blue-600);
180 | text-decoration: none;
181 | }
182 | .dontHaveAnContainer {
183 | line-break: anywhere;
184 | width: 100%;
185 | margin-top: 10px;
186 | }
187 | .dontHaveAnAccountCreate {
188 | cursor: pointer;
189 | text-decoration: none;
190 | font-size: var(--regular-13px1-size);
191 | line-height: 22px;
192 | text-align: left;
193 | display: flex;
194 | align-items: center;
195 | width: 444px;
196 | }
197 |
198 | .signInDiv {
199 | position: relative;
200 | background-color: var(--shades-white);
201 | min-height: 100vh;
202 | display: flex;
203 | align-items: center;
204 | justify-content: center;
205 | overflow: hidden;
206 | text-align: left;
207 | font-size: var(--pj-bold-52px-size);
208 | color: var(--shades-white);
209 | font-family: var(--bold-52px);
210 | padding: 10px;
211 | }
212 |
213 | .error {
214 | color: red;
215 | font-size: var(--bold-16px1-size);
216 | }
217 |
--------------------------------------------------------------------------------
/src/styles/pages/SignUp.module.css:
--------------------------------------------------------------------------------
1 | .formDiv {
2 | border-radius: var(--br-sm);
3 | background-color: var(--blue-gray-900);
4 | min-width: 350px;
5 | max-width: 450px;
6 | width: 100%;
7 | padding: 20px 25px;
8 | }
9 |
10 | .createAnAccountToStartUsi,
11 | .joinUsToday {
12 | display: inline-block;
13 | }
14 | .joinUsToday {
15 | letter-spacing: -2px;
16 | line-height: 62px;
17 | font-weight: 600;
18 | }
19 | .createAnAccountToStartUsi {
20 | font-size: var(--pj-regular-18px-size);
21 | line-height: 30px;
22 | color: var(--color-gray-800);
23 | width: 449px;
24 | }
25 | .buttonNameDiv {
26 | position: relative;
27 | font-size: var(--bold-16px1-size);
28 | letter-spacing: -0.2px;
29 | line-height: 28px;
30 | font-weight: 600;
31 | font-family: var(--bold-52px);
32 | color: var(--shades-white);
33 | text-align: right;
34 | display: inline-block;
35 | }
36 | .iconOutlinearrowRight {
37 | position: relative;
38 | width: 18px;
39 | height: 18px;
40 | flex-shrink: 0;
41 | overflow: hidden;
42 | }
43 | .iconDiv {
44 | display: none;
45 | flex-direction: row;
46 | align-items: center;
47 | justify-content: center;
48 | }
49 | .buttonPrimaryWithIconDiv,
50 | .frameDiv {
51 | display: flex;
52 | align-items: center;
53 | justify-content: center;
54 | }
55 | .frameDiv {
56 | flex-direction: row;
57 | gap: var(--gap-sm);
58 | }
59 | .buttonPrimaryWithIconDiv {
60 | border-radius: var(--br-lg);
61 | background-color: var(--blue-gray-800);
62 | flex-direction: column;
63 | padding: var(--padding-md);
64 | box-sizing: border-box;
65 | }
66 |
67 | .google2Icon {
68 | position: absolute;
69 | top: 19px;
70 | left: 106.7px;
71 | width: 23px;
72 | height: 23px;
73 | }
74 | .button {
75 | position: relative;
76 | cursor: pointer;
77 | border: 0;
78 | padding: 0;
79 | background-color: transparent;
80 | width: 100%;
81 | height: 60px;
82 | }
83 |
84 | .titleDiv {
85 | width: 100%;
86 | margin-bottom: 30px;
87 | text-align: center;
88 | }
89 | .inputLabelDiv {
90 | position: relative;
91 | font-size: var(--regular-13px1-size);
92 | margin-bottom: 7px;
93 | font-family: var(--bold-52px);
94 | color: var(--gray-200);
95 | text-align: left;
96 | display: inline-block;
97 | }
98 | .frameInput {
99 | border: 1px solid var(--blue-gray-700);
100 | background-color: transparent;
101 | align-self: stretch;
102 | border-radius: var(--br-lg);
103 | box-sizing: border-box;
104 | position: relative;
105 | height: 60px;
106 | flex-shrink: 0;
107 | display: flex;
108 | flex-direction: row;
109 | padding: var(--padding-lg) var(--padding-xl);
110 | align-items: center;
111 | justify-content: flex-start;
112 | color: var(--shades-white);
113 | outline: none;
114 | width: 100%;
115 | }
116 |
117 | .rememberMeDiv {
118 | font-size: var(--regular-13px1-size);
119 | font-family: var(--bold-52px);
120 | color: var(--shades-white);
121 | text-align: left;
122 | display: inline-block;
123 | margin-left: 5px;
124 | }
125 |
126 | .shapeInput {
127 | cursor: pointer;
128 | border-radius: var(--br-xs);
129 | border: 1px solid var(--blue-gray-700);
130 | box-sizing: border-box;
131 | width: 19px;
132 | height: 19px;
133 | }
134 |
135 | .checkDiv {
136 | display: flex;
137 | margin: 20px 0;
138 | cursor: pointer;
139 | }
140 |
141 | .buttonPrimaryWithIcon {
142 | cursor: pointer;
143 | border: 0;
144 | padding: var(--padding-md);
145 | background-color: var(--blue-600);
146 | border-radius: var(--br-xl);
147 | width: 200px;
148 | height: 55px;
149 | display: flex;
150 | flex-direction: column;
151 | box-sizing: border-box;
152 | align-items: center;
153 | justify-content: center;
154 | color: var(--shades-white);
155 | }
156 | .alreadyHaveAn,
157 | .signInSpan {
158 | font-family: var(--bold-52px);
159 | color: var(--neutral-500);
160 | }
161 | .signInSpan {
162 | font-weight: 600;
163 | color: var(--blue-600);
164 | text-decoration: none;
165 | }
166 | .alreadyHaveAnContainer {
167 | line-break: anywhere;
168 | width: 100%;
169 | }
170 | .alreadyHaveAnAccountSign {
171 | cursor: pointer;
172 | font-size: var(--regular-13px1-size);
173 | text-align: left;
174 | display: flex;
175 | align-items: center;
176 | margin: 10px 0;
177 | }
178 |
179 | .signUpDiv {
180 | position: relative;
181 | background-color: var(--shades-white);
182 | min-height: 100vh;
183 | display: flex;
184 | align-items: center;
185 | justify-content: center;
186 | overflow: hidden;
187 | text-align: left;
188 | font-size: var(--pj-bold-52px-size);
189 | color: var(--shades-white);
190 | font-family: var(--bold-52px);
191 | padding: 10px;
192 | }
193 |
194 | .inputBox {
195 | width: 100%;
196 | height: 100%;
197 | color: var(--shades-white);
198 | font-size: var(--pj-bold-52px-size);
199 | font-family: var(--bold-52px);
200 | outline: none;
201 | display: flex;
202 | flex-direction: column;
203 | margin-top: 15px;
204 | }
205 |
206 | .inputContentForm {
207 | width: 100%;
208 | }
209 |
210 | .verification {
211 | font-size: var(--bold-32px-size);
212 | color: var(--base-black);
213 | }
214 |
215 | .error {
216 | color: red;
217 | font-size: var(--bold-16px1-size);
218 | }
219 |
--------------------------------------------------------------------------------