mirror of
https://github.com/rjNemo/React-SaaS-sample
synced 2026-06-06 05:06:38 +00:00
template
This commit is contained in:
parent
fee97cf1fd
commit
d501c9d04f
129 changed files with 8042 additions and 6434 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,5 +1,3 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
|
|
|
|||
143
README.md
143
README.md
|
|
@ -1,68 +1,119 @@
|
|||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
### <p align="center"><b>This project was created with [Divjoy](https://divjoy.com?ref=readme) ✨</b></p>
|
||||
|
||||
## Available Scripts
|
||||
## 👉 Get Started
|
||||
Install dependencies
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
In the project directory, you can run:
|
||||
Run the development server
|
||||
```
|
||||
npm run start
|
||||
```
|
||||
When the above command completes you'll be able to view your website at `http://localhost:3000`
|
||||
|
||||
### `npm start`
|
||||
## 🥞 Stack
|
||||
This project uses the following libraries and services:
|
||||
- Framework - [Create React App](https://create-react-app.dev) with React Router
|
||||
- Styling - [Bulma](https://bulma.io) with custom SASS styles
|
||||
- Authentication - [Firebase Auth](https://firebase.google.com/products/auth)
|
||||
- Analytics - [Google Analytics](https://googleanalytics.com)
|
||||
- Hosting - [ZEIT Now](https://zeit.co)
|
||||
|
||||
Runs the app in the development mode.<br>
|
||||
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
|
||||
|
||||
The page will reload if you make edits.<br>
|
||||
You will also see any lint errors in the console.
|
||||
## 📚 Guide
|
||||
<details>
|
||||
<summary><b>Styles</b></summary>
|
||||
<p>
|
||||
You can edit Bulma SASS variables in the global stylesheet located at <code><a href="src/styles/global.scss">src/styles/global.scss</a></code>. Variables allow you to control global styles (like colors and fonts), as well as element specific styles (like button padding). Before overriding Bulma elements with custom style check the <a href="https://bulma.io/documentation">Bulma docs</a> to see if you can do what need by tweaking a SASS variable.
|
||||
</p>
|
||||
<p>
|
||||
Custom styles are located in their related component's directory. For example, if any custom style is applied to the Navbar component you'll find it in <code>src/components/Navbar/styles.scss</code>. We ensure custom styles are scoped to their component by prepending the classname with the component name (such as <code>.Navbar__brand</code>). This ensures styles never affect elements in other components. If styles need to be re-used in multiple components consider creating a new component that encapsulates that style and structure and using that component in multiple places.
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### `npm test`
|
||||
<details>
|
||||
<summary><b>Routing</b></summary>
|
||||
<p>
|
||||
This project uses <a target="_blank" href="https://reacttraining.com/react-router/web/guides/quick-start">React Router</a> and includes a convenient <code>useRouter</code> hook (located in <code><a href="src/util/router.js">src/util/router.js</a></code>) that wraps React Router and gives all the route methods and data you need.
|
||||
|
||||
Launches the test runner in the interactive watch mode.<br>
|
||||
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
|
||||
```jsx
|
||||
import { Link, useRouter } from './../util/router.js';
|
||||
|
||||
### `npm run build`
|
||||
function MyComponent(){
|
||||
// Get the router object
|
||||
const router = useRouter();
|
||||
|
||||
Builds the app for production to the `build` folder.<br>
|
||||
It correctly bundles React in production mode and optimizes the build for the best performance.
|
||||
// Get value from query string (?postId=123) or route param (/:postId)
|
||||
console.log(router.query.postId);
|
||||
|
||||
The build is minified and the filenames include the hashes.<br>
|
||||
Your app is ready to be deployed!
|
||||
// Get current pathname
|
||||
console.log(router.pathname)
|
||||
|
||||
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
|
||||
// Navigate with the <Link> component or with router.push()
|
||||
return (
|
||||
<div>
|
||||
<Link to="/about">About</Link>
|
||||
<button onClick={(e) => router.push('/about')}>About</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### `npm run eject`
|
||||
<details>
|
||||
<summary><b>Authentication</b></summary>
|
||||
|
||||
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
|
||||
<p>
|
||||
This project uses <a href="https://firebase.google.com">Firebase Auth</a> and includes a convenient <code>useAuth</code> hook (located in <code><a href="src/util/auth.js">src/util/auth.js</a></code>) that wraps Firebase and gives you common authentication methods. Depending on your needs you may want to edit this file and expose more Firebase functionality.
|
||||
|
||||
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
|
||||
```js
|
||||
import { useAuth } from './../util/auth.js';
|
||||
|
||||
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
|
||||
function MyComponent(){
|
||||
// Get the auth object in any component
|
||||
const auth = useAuth();
|
||||
|
||||
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
|
||||
// Depending on auth state show signin or signout button
|
||||
// auth.user will either be an object, null when loading, or false if signed out
|
||||
return (
|
||||
<div>
|
||||
{auth.user ? (
|
||||
<button onClick={(e) => auth.signout()}>Signout</button>
|
||||
) : (
|
||||
<button onClick={(e) => auth.signin('hello@divjoy.com', 'yolo')}>Signin</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
</p>
|
||||
</details>
|
||||
|
||||
## Learn More
|
||||
<details>
|
||||
<summary><b>Deployment</b></summary>
|
||||
<p>
|
||||
Install the ZEIT Now CLI
|
||||
|
||||
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
|
||||
```
|
||||
npm install -g now
|
||||
```
|
||||
|
||||
To learn React, check out the [React documentation](https://reactjs.org/).
|
||||
Then run this command in your project directory to deploy to ZEIT Now
|
||||
|
||||
### Code Splitting
|
||||
```
|
||||
now
|
||||
```
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
|
||||
See the <a target="_blank" href="https://zeit.co/docs">ZEIT docs</a> for more details.
|
||||
</p>
|
||||
</details>
|
||||
|
||||
### Analyzing the Bundle Size
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
|
||||
|
||||
### Making a Progressive Web App
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
|
||||
|
||||
### Advanced Configuration
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
|
||||
|
||||
### Deployment
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
|
||||
|
||||
### `npm run build` fails to minify
|
||||
|
||||
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
|
||||
<details>
|
||||
<summary><b>Other</b></summary>
|
||||
<p>
|
||||
The <a href="https://create-react-app.dev">Create React App documention</a> covers many other topics.
|
||||
This project was initially created using <a href="https://divjoy.com?ref=readme_other">Divjoy</a>, a React codebase generator. Feel free to ask questions in the <a href="https://spectrum.chat/divjoy">Divjoy forum</a> and we'll do our best to help you out.
|
||||
</p>
|
||||
</details>
|
||||
3036
divjoy-project.json
3036
divjoy-project.json
File diff suppressed because it is too large
Load diff
10058
package-lock.json
generated
10058
package-lock.json
generated
File diff suppressed because it is too large
Load diff
20
package.json
20
package.json
|
|
@ -7,21 +7,19 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"@analytics/google-analytics": "0.2.0",
|
||||
"analytics": "0.2.2",
|
||||
"aws-sdk": "2.533.0",
|
||||
"body-parser": "1.19.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.25",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.11.2",
|
||||
"@fortawesome/react-fontawesome": "^0.1.7",
|
||||
"analytics": "0.2.6",
|
||||
"bulma": "0.7.5",
|
||||
"css-loader": "^3.2.0",
|
||||
"express": "4.17.1",
|
||||
"firebase": "6.6.2",
|
||||
"mailchimp-api-v3": "1.13.1",
|
||||
"node-sass": "^4.12.0",
|
||||
"node-sass": "4.12.0",
|
||||
"query-string": "6.8.3",
|
||||
"react": "16.9.0",
|
||||
"react-dom": "16.9.0",
|
||||
"react": "16.10.2",
|
||||
"react-dom": "16.10.2",
|
||||
"react-rainbow-components": "^1.9.0",
|
||||
"react-router-dom": "5.1.0",
|
||||
"react-scripts": "3.1.2",
|
||||
"resolve-url-loader": "^3.1.0"
|
||||
"react-scripts": "3.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
|
|
|
|||
|
|
@ -10,11 +10,6 @@
|
|||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!-- Font Awesome icons -->
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://use.fontawesome.com/releases/v5.10.1/css/all.css"
|
||||
/>
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import React, { useState } from "react";
|
||||
import FormStatus from "./../FormStatus";
|
||||
import FormField from "./../FormField";
|
||||
import SectionButton from "./../SectionButton";
|
||||
import { Link } from "./../../util/router.js";
|
||||
import "./styles.scss";
|
||||
import FormStatus from "./FormStatus";
|
||||
import FormField from "./FormField";
|
||||
import SectionButton from "./SectionButton";
|
||||
import { Link } from "./../util/router.js";
|
||||
import "./Auth.scss";
|
||||
|
||||
function Auth(props) {
|
||||
// State for all inputs
|
||||
13
src/components/Auth.scss
Normal file
13
src/components/Auth.scss
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
.Auth {
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
margin: 0 auto;
|
||||
|
||||
&__bottom-link {
|
||||
margin-top: 1rem;
|
||||
font-size: 0.9rem;
|
||||
a {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
.Auth {
|
||||
width: 100%;
|
||||
max-width: 450px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.Auth__bottom-link {
|
||||
margin-top: 1rem;
|
||||
font-size: 0.9rem;
|
||||
a {
|
||||
margin: 0 0.5rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
|
||||
function Avatar(props) {
|
||||
const { image, size, alt, ...otherProps } = props;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
import "./BackgroundImage.scss";
|
||||
|
||||
function BackgroundImage(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
|
||||
function CenteredColumns(props) {
|
||||
return (
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import Auth from "./../Auth";
|
||||
import { useAuth } from "./../../util/auth.js";
|
||||
import "./styles.scss";
|
||||
import Auth from "./Auth";
|
||||
import { useAuth } from "./../util/auth.js";
|
||||
|
||||
function ChangePass(props) {
|
||||
const auth = useAuth();
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import ChangePass from "./../ChangePass";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import ChangePass from "./ChangePass";
|
||||
|
||||
function ChangePassSection(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
import "./Clients.scss";
|
||||
|
||||
function Clients(props) {
|
||||
return (
|
||||
9
src/components/Clients.scss
Normal file
9
src/components/Clients.scss
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
.Clients {
|
||||
&__logo {
|
||||
margin: 0 12px;
|
||||
img {
|
||||
// Removes extra space under image
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
.Clients__logo {
|
||||
margin: 0 12px;
|
||||
img {
|
||||
// Removes extra space under image
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import Clients from "./../Clients";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import Clients from "./Clients";
|
||||
|
||||
function ClientsSection(props) {
|
||||
return (
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import ContactForm from "./../ContactForm";
|
||||
import contact from "./../../util/contact.js";
|
||||
import "./styles.scss";
|
||||
import ContactForm from "./ContactForm";
|
||||
import contact from "./../util/contact.js";
|
||||
|
||||
function Contact(props) {
|
||||
const [status, setStatus] = useState();
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
import FormStatus from "./../FormStatus";
|
||||
import FormField from "./../FormField";
|
||||
import SectionButton from "./../SectionButton";
|
||||
import "./styles.scss";
|
||||
import FormStatus from "./FormStatus";
|
||||
import FormField from "./FormField";
|
||||
import SectionButton from "./SectionButton";
|
||||
|
||||
function ContactForm(props) {
|
||||
// State for input values
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import Contact from "./../Contact";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import Contact from "./Contact";
|
||||
import "./ContactSection.scss";
|
||||
|
||||
function ContactSection(props) {
|
||||
return (
|
||||
5
src/components/ContactSection.scss
Normal file
5
src/components/ContactSection.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.ContactSection {
|
||||
&__container {
|
||||
max-width: 850px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
.ContactSection__container {
|
||||
max-width: 850px;
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
|
||||
function ContentSection(props) {
|
||||
return (
|
||||
148
src/components/DashboardSection.js
Normal file
148
src/components/DashboardSection.js
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import React from "react";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
|
||||
import {
|
||||
Application,
|
||||
ButtonGroup,
|
||||
ButtonIcon,
|
||||
ButtonMenu,
|
||||
MenuDivider,
|
||||
MenuItem,
|
||||
Avatar,
|
||||
Card,
|
||||
Button,
|
||||
Input,
|
||||
} from 'react-rainbow-components';
|
||||
|
||||
// more details about how to use react-font-awesome
|
||||
// visit https://github.com/FortAwesome/react-fontawesome
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import {
|
||||
faSearch,
|
||||
faTasks,
|
||||
faShareAlt,
|
||||
faHeart,
|
||||
faAngleDown,
|
||||
faPencilAlt,
|
||||
faBell,
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
const iconContainerStyles = {
|
||||
width: '2rem',
|
||||
height: '2rem',
|
||||
};
|
||||
|
||||
const inputStyles = {
|
||||
width: 260,
|
||||
};
|
||||
|
||||
function DashboardSection(props) {
|
||||
return (
|
||||
<Section color={props.color} size={props.size}>
|
||||
<div className="container">
|
||||
<SectionHeader
|
||||
title={props.title}
|
||||
subtitle={props.subtitle}
|
||||
centered={true}
|
||||
size={3}
|
||||
/>
|
||||
</div>
|
||||
<section>
|
||||
<header className="rainbow-align-content_space-between rainbow-background-color_white rainbow-p-vertical_medium react-rainbow-golbal-header">
|
||||
<img
|
||||
src="images/rainbow-logo.svg"
|
||||
alt="rainbow logo"
|
||||
className="rainbow-m-left_medium react-rainbow-global-header_logo"
|
||||
/>
|
||||
|
||||
<article className="rainbow-flex rainbow-align_center">
|
||||
<ButtonGroup>
|
||||
<ButtonIcon
|
||||
variant="border"
|
||||
disabled
|
||||
icon={<FontAwesomeIcon icon={faPencilAlt} />}
|
||||
/>
|
||||
<ButtonIcon
|
||||
variant="border"
|
||||
disabled
|
||||
icon={<FontAwesomeIcon icon={faBell} />}
|
||||
/>
|
||||
<ButtonMenu
|
||||
menuSize="x-small"
|
||||
menuAlignment="right"
|
||||
icon={<FontAwesomeIcon icon={faAngleDown} />}
|
||||
>
|
||||
<MenuItem label="Options" variant="header" />
|
||||
<MenuItem label="Menu Item" />
|
||||
<MenuItem label="Menu Item" />
|
||||
<MenuDivider variant="space" />
|
||||
<MenuItem
|
||||
label="Right Icon"
|
||||
icon={<FontAwesomeIcon icon={faTasks} />}
|
||||
iconPosition="right"
|
||||
/>
|
||||
</ButtonMenu>
|
||||
</ButtonGroup>
|
||||
|
||||
<Avatar
|
||||
src="images/user/user2.jpg"
|
||||
variant="circle"
|
||||
className="rainbow-m-horizontal_medium"
|
||||
/>
|
||||
</article>
|
||||
</header>
|
||||
<section className="rainbow-m-horizontal_large rainbow-m-top_large rainbow-m-bottom_xx-large">
|
||||
<Card
|
||||
title="Tasks"
|
||||
icon={
|
||||
<span
|
||||
className="rainbow-background-color_brand rainbow-border-radius_circle rainbow-align-content_center"
|
||||
style={iconContainerStyles}
|
||||
>
|
||||
<FontAwesomeIcon icon={faTasks} size="lg" className="rainbow-color_white" />
|
||||
</span>
|
||||
}
|
||||
footer={
|
||||
<div className="rainbow-align-content_space-between">
|
||||
<div className="rainbow-flex">
|
||||
<ButtonIcon
|
||||
icon={<FontAwesomeIcon icon={faHeart} />}
|
||||
className="rainbow-m-right_xx-small"
|
||||
/>
|
||||
<ButtonIcon icon={<FontAwesomeIcon icon={faShareAlt} />} />
|
||||
</div>
|
||||
<ButtonIcon icon={<FontAwesomeIcon icon={faAngleDown} />} />
|
||||
</div>
|
||||
}
|
||||
actions={<Button variant="neutral" label="New" />}
|
||||
>
|
||||
<div className="rainbow-p-bottom_large">
|
||||
<Input
|
||||
label="aplication component search"
|
||||
hideLabel
|
||||
placeholder="Search"
|
||||
icon={<FontAwesomeIcon icon={faSearch} className="rainbow-color_gray-3" />}
|
||||
type="search"
|
||||
className="rainbow-p-around_small"
|
||||
style={inputStyles}
|
||||
/>
|
||||
<div className="rainbow-p-horizontal_xx-large rainbow-flex_column rainbow-align-content_center">
|
||||
<img
|
||||
src="images/illustrations/Illustration-rainbow-1.svg"
|
||||
className="rainbow-p-top_x-large rainbow-align_absolute-center"
|
||||
alt="the rainbow"
|
||||
/>
|
||||
<p className="rainbow-p-top_medium rainbow-font-size-heading_small rainbow-color_gray-4">
|
||||
No new tasks
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</section>
|
||||
</section>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardSection;
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import "./styles.scss";
|
||||
|
||||
function DashboardSection(props) {
|
||||
return (
|
||||
<Section color={props.color} size={props.size}>
|
||||
<div className="container">
|
||||
<SectionHeader
|
||||
title={props.title}
|
||||
subtitle={props.subtitle}
|
||||
centered={true}
|
||||
size={3}
|
||||
/>
|
||||
</div>
|
||||
</Section>
|
||||
);
|
||||
}
|
||||
|
||||
export default DashboardSection;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import React from "react";
|
||||
import FaqItem from "./../FaqItem";
|
||||
import "./styles.scss";
|
||||
import FaqItem from "./FaqItem";
|
||||
|
||||
function Faq(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React, { useState } from "react";
|
||||
import "./styles.scss";
|
||||
import "./FaqItem.scss";
|
||||
|
||||
function FaqItem(props) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
|
|
@ -5,8 +5,8 @@
|
|||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.FaqItem__icon {
|
||||
&__icon {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import Faq from "./../Faq";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import Faq from "./Faq";
|
||||
|
||||
function FaqSection(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
import "./Features.scss";
|
||||
|
||||
function Features(props) {
|
||||
return (
|
||||
27
src/components/Features.scss
Normal file
27
src/components/Features.scss
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
.Features {
|
||||
max-width: 900px;
|
||||
margin: 80px auto 0 auto;
|
||||
|
||||
&__columns {
|
||||
// Reverse every other row
|
||||
&:nth-of-type(even) {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
padding-bottom: 1.5rem;
|
||||
@media screen and (min-width: 769px) {
|
||||
padding-bottom: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__title {
|
||||
margin-bottom: 1.2rem !important;
|
||||
}
|
||||
|
||||
&__image {
|
||||
max-width: 300px;
|
||||
margin: 30px auto;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
.Features {
|
||||
max-width: 900px;
|
||||
margin: 80px auto 0 auto;
|
||||
}
|
||||
|
||||
.Features__columns {
|
||||
// Reverse every other row
|
||||
&:nth-of-type(even) {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
padding-bottom: 1.5rem;
|
||||
@media screen and (min-width: 769px) {
|
||||
padding-bottom: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.Features__title {
|
||||
margin-bottom: 1.2rem !important;
|
||||
}
|
||||
|
||||
.Features__image {
|
||||
max-width: 300px;
|
||||
margin: 30px auto;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import Features from "./../Features";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import Features from "./Features";
|
||||
|
||||
function FeaturesSection(props) {
|
||||
return (
|
||||
|
|
@ -17,28 +16,28 @@ function FeaturesSection(props) {
|
|||
<Features
|
||||
items={[
|
||||
{
|
||||
title: "Automatisez des tâches →",
|
||||
title: "Explore",
|
||||
description:
|
||||
"Avis d’échéances, suivi des encaissements, comptabilité locative, quittancement, …",
|
||||
"Integer ornare neque mauris, ac vulputate lacus venenatis et. Pellentesque ut ultrices purus.",
|
||||
image: "https://uploads.divjoy.com/undraw-mind_map_cwng.svg"
|
||||
},
|
||||
{
|
||||
title: "Protégez vos intérêts →",
|
||||
title: "Explore",
|
||||
description:
|
||||
"Gestion des retards de paiement, révision du loyer, régularisation des charges, …",
|
||||
"Integer ornare neque mauris, ac vulputate lacus venenatis et. Pellentesque ut ultrices purus.",
|
||||
image:
|
||||
"https://uploads.divjoy.com/undraw-personal_settings_kihd.svg"
|
||||
},
|
||||
{
|
||||
title: "Soyez mieux accompagné →",
|
||||
title: "Explore",
|
||||
description:
|
||||
"Edition du bail, assistance administrative et comptable, information juridique et fiscale, …",
|
||||
"Integer ornare neque mauris, ac vulputate lacus venenatis et. Pellentesque ut ultrices purus.",
|
||||
image: "https://uploads.divjoy.com/undraw-having_fun_iais.svg"
|
||||
},
|
||||
{
|
||||
title: "Restez organisé (à venir) →",
|
||||
title: "Explore",
|
||||
description:
|
||||
"Assignation des dépenses, archivage des justificatifs, déclaration des revenus fonciers, …",
|
||||
"Integer ornare neque mauris, ac vulputate lacus venenatis et. Pellentesque ut ultrices purus.",
|
||||
image: "https://uploads.divjoy.com/undraw-balloons_vxx5.svg"
|
||||
}
|
||||
]}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import { Link } from "./../../util/router.js";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import { Link } from "./../util/router.js";
|
||||
import "./Footer.scss";
|
||||
|
||||
function Footer(props) {
|
||||
return (
|
||||
|
|
@ -13,20 +13,18 @@ function Footer(props) {
|
|||
</Link>
|
||||
</div>
|
||||
<div className="links right">
|
||||
<Link to="/about">À propos</Link>
|
||||
<Link to="/about">About</Link>
|
||||
<Link to="/faq">FAQ</Link>
|
||||
<Link to="/contact">Contact</Link>
|
||||
</div>
|
||||
<div className="social right">
|
||||
<a
|
||||
href="https://linkedin.com"
|
||||
target="_blank"
|
||||
href="https://medium.com"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="icon">
|
||||
<i className="fab fa-linkedin" />
|
||||
</span>
|
||||
Blog
|
||||
</a>
|
||||
</div>
|
||||
<div className="social right">
|
||||
<a
|
||||
href="https://twitter.com"
|
||||
target="_blank"
|
||||
|
|
@ -54,15 +52,6 @@ function Footer(props) {
|
|||
<i className="fab fa-instagram" />
|
||||
</span>
|
||||
</a>
|
||||
<a
|
||||
href="https://medium.com"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<span className="icon">
|
||||
<i className="fab fa-medium" />
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<div className="copyright left">{props.copyright}</div>
|
||||
</div>
|
||||
59
src/components/Footer.scss
Normal file
59
src/components/Footer.scss
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
.FooterComponent {
|
||||
&__container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
> div {
|
||||
display: flex;
|
||||
flex: none;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.brand {
|
||||
img {
|
||||
display: block;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.social {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.social,
|
||||
.links {
|
||||
a {
|
||||
color: inherit;
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tablet and up
|
||||
@media screen and (min-width: 769px) {
|
||||
> div {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
.left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
// Move links to end (bottom right)
|
||||
// Swaps position with social
|
||||
.links {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
.FooterComponent__container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
> div {
|
||||
display: flex;
|
||||
flex: none;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.brand {
|
||||
img {
|
||||
display: block;
|
||||
height: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.social {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.social,
|
||||
.links {
|
||||
a {
|
||||
color: inherit;
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
&:not(:first-of-type) {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Tablet and up
|
||||
@media screen and (min-width: 769px) {
|
||||
> div {
|
||||
flex: 50%;
|
||||
}
|
||||
|
||||
.left {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.right {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
// Move links to end (bottom right)
|
||||
// Swaps position with social
|
||||
.links {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import Auth from "./../Auth";
|
||||
import { useAuth } from "./../../util/auth.js";
|
||||
import "./styles.scss";
|
||||
import Auth from "./Auth";
|
||||
import { useAuth } from "./../util/auth.js";
|
||||
|
||||
function ForgotPass(props) {
|
||||
const auth = useAuth();
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import ForgotPass from "./../ForgotPass";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import ForgotPass from "./ForgotPass";
|
||||
|
||||
function ForgotPassSection(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
|
||||
function FormField(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
|
||||
function FormStatus(props) {
|
||||
return (
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import SectionButton from "./../SectionButton";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import SectionButton from "./SectionButton";
|
||||
import "./HeroSection.scss";
|
||||
|
||||
function HeroSection(props) {
|
||||
return (
|
||||
6
src/components/HeroSection.scss
Normal file
6
src/components/HeroSection.scss
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
.HeroSection {
|
||||
&__image {
|
||||
margin: 0 auto;
|
||||
max-width: 570px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
.HeroSection__image {
|
||||
margin: 0 auto;
|
||||
max-width: 570px;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React, { useState } from "react";
|
||||
import NavbarContainer from "./../NavbarContainer";
|
||||
import { Link } from "./../../util/router.js";
|
||||
import { useAuth } from "./../../util/auth.js";
|
||||
import "./styles.scss";
|
||||
import NavbarContainer from "./NavbarContainer";
|
||||
import { Link } from "./../util/router.js";
|
||||
import { useAuth } from "./../util/auth.js";
|
||||
|
||||
function Navbar(props) {
|
||||
const auth = useAuth();
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 60 KiB |
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
|
||||
function NavbarContainer(props) {
|
||||
return (
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import SectionButton from "./../SectionButton";
|
||||
import newsletter from "./../../util/newsletter.js";
|
||||
import "./styles.scss";
|
||||
import SectionButton from "./SectionButton";
|
||||
import newsletter from "./../util/newsletter.js";
|
||||
|
||||
function Newsletter(props) {
|
||||
const [email, setEmail] = useState("");
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import Newsletter from "./../Newsletter";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import Newsletter from "./Newsletter";
|
||||
|
||||
function NewsletterSection(props) {
|
||||
return (
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
import "./Pricing.scss";
|
||||
|
||||
function Pricing(props) {
|
||||
return (
|
||||
48
src/components/Pricing.scss
Normal file
48
src/components/Pricing.scss
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
.Pricing {
|
||||
&__column {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
&__card {
|
||||
display: flex;
|
||||
// Stretch to fit column width
|
||||
width: 100%;
|
||||
// Ensure .card-content stretches to fit width
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
&__card-content {
|
||||
// Flex so that button can position self at
|
||||
// bottom of card using margin-top auto.
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// Stretch to fit column width
|
||||
width: 100%;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
&__period {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
&__price {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
&__price-symbol {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
&__price-month {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
&__description {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
&__button {
|
||||
margin-top: auto;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
.Pricing__column {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.Pricing__card {
|
||||
display: flex;
|
||||
// Stretch to fit column width
|
||||
width: 100%;
|
||||
// Ensure .card-content stretches to fit width
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.Pricing__card-content {
|
||||
// Flex so that button can position self at
|
||||
// bottom of card using margin-top auto.
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// Stretch to fit column width
|
||||
width: 100%;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.Pricing__period {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.Pricing__price {
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.Pricing__price-symbol {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.Pricing__price-month {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.Pricing__description {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.Pricing__button {
|
||||
margin-top: auto;
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import Pricing from "./../Pricing";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import Pricing from "./Pricing";
|
||||
import "./PricingSection.scss";
|
||||
|
||||
function PricingSection(props) {
|
||||
return (
|
||||
5
src/components/PricingSection.scss
Normal file
5
src/components/PricingSection.scss
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
.PricingSection {
|
||||
&__container {
|
||||
max-width: 800px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
.PricingSection__container {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
import BackgroundImage from "./../BackgroundImage";
|
||||
import "./styles.scss";
|
||||
import BackgroundImage from "./BackgroundImage";
|
||||
import "./Section.scss";
|
||||
|
||||
function Section(props) {
|
||||
const {
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
|
||||
function SectionButton(props) {
|
||||
const {
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import "./styles.scss";
|
||||
import "./SectionHeader.scss";
|
||||
|
||||
function SectionHeader(props) {
|
||||
return (
|
||||
22
src/components/SectionHeader.scss
Normal file
22
src/components/SectionHeader.scss
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
.SectionHeader {
|
||||
&__header {
|
||||
margin-bottom: 3rem;
|
||||
|
||||
// Remove margin if nothing after header
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Added if props.centered is true
|
||||
&.is-centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
max-width: 700px;
|
||||
// So we can have max-width but still
|
||||
// have alignment controlled by text-align.
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
.SectionHeader__header {
|
||||
margin-bottom: 3rem;
|
||||
|
||||
// Remove margin if nothing after header
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
// Added if props.centered is true
|
||||
&.is-centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
max-width: 700px;
|
||||
// So we can have max-width but still
|
||||
// have alignment controlled by text-align.
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import Auth from "./../Auth";
|
||||
import { useAuth } from "./../../util/auth.js";
|
||||
import "./styles.scss";
|
||||
import Auth from "./Auth";
|
||||
import { useAuth } from "./../util/auth.js";
|
||||
|
||||
function SignIn(props) {
|
||||
const auth = useAuth();
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import SignIn from "./../SignIn";
|
||||
import { useRouter } from "./../../util/router.js";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import SignIn from "./SignIn";
|
||||
import { useRouter } from "./../util/router.js";
|
||||
|
||||
function SignInSection(props) {
|
||||
const router = useRouter();
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useState } from "react";
|
||||
import Auth from "./../Auth";
|
||||
import { useAuth } from "./../../util/auth.js";
|
||||
import "./styles.scss";
|
||||
import Auth from "./Auth";
|
||||
import { useAuth } from "./../util/auth.js";
|
||||
|
||||
function SignUp(props) {
|
||||
const auth = useAuth();
|
||||
|
|
@ -1,9 +1,8 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import SignUp from "./../SignUp";
|
||||
import { useRouter } from "./../../util/router.js";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import SignUp from "./SignUp";
|
||||
import { useRouter } from "./../util/router.js";
|
||||
|
||||
function SignUpSection(props) {
|
||||
const router = useRouter();
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import CenteredColumns from "./../CenteredColumns";
|
||||
import Avatar from "./../Avatar";
|
||||
import "./styles.scss";
|
||||
import CenteredColumns from "./CenteredColumns";
|
||||
import Avatar from "./Avatar";
|
||||
import "./TeamBios.scss";
|
||||
|
||||
function TeamBios(props) {
|
||||
return (
|
||||
23
src/components/TeamBios.scss
Normal file
23
src/components/TeamBios.scss
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
.TeamBios {
|
||||
&__card {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__card-content {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 1.8rem;
|
||||
}
|
||||
|
||||
&__avatar-wrapper {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
&__details {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
&__bio {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
.TeamBios__card {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.TeamBios__card-content {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 1.8rem;
|
||||
}
|
||||
|
||||
.TeamBios__avatar-wrapper {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.TeamBios__details {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.TeamBios__bio {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import TeamBios from "./../TeamBios";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import TeamBios from "./TeamBios";
|
||||
|
||||
function TeamBiosSection(props) {
|
||||
return (
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import CenteredColumns from "./../CenteredColumns";
|
||||
import Avatar from "./../Avatar";
|
||||
import "./styles.scss";
|
||||
import CenteredColumns from "./CenteredColumns";
|
||||
import Avatar from "./Avatar";
|
||||
import "./Testimonials.scss";
|
||||
|
||||
function Testimonials(props) {
|
||||
return (
|
||||
28
src/components/Testimonials.scss
Normal file
28
src/components/Testimonials.scss
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
.Testimonials {
|
||||
&__card {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__card-content {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 1.8rem;
|
||||
}
|
||||
|
||||
&__avatar-wrapper {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
&__quote {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
&__info {
|
||||
margin-top: auto;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
&__company {
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
.Testimonials__card {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.Testimonials__card-content {
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
padding: 1.8rem;
|
||||
}
|
||||
|
||||
.Testimonials__avatar-wrapper {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.Testimonials__quote {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.Testimonials__info {
|
||||
margin-top: auto;
|
||||
padding-top: 40px;
|
||||
}
|
||||
|
||||
.Testimonials__company {
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
|
@ -1,8 +1,7 @@
|
|||
import React from "react";
|
||||
import Section from "./../Section";
|
||||
import SectionHeader from "./../SectionHeader";
|
||||
import Testimonials from "./../Testimonials";
|
||||
import "./styles.scss";
|
||||
import Section from "./Section";
|
||||
import SectionHeader from "./SectionHeader";
|
||||
import Testimonials from "./Testimonials";
|
||||
|
||||
function TestimonialsSection(props) {
|
||||
return (
|
||||
|
|
@ -20,7 +19,7 @@ function TestimonialsSection(props) {
|
|||
avatar: "https://uploads.divjoy.com/pravatar-150x-5.jpeg",
|
||||
name: "Sarah Kline",
|
||||
bio:
|
||||
"“Ce que j’aime dans cet outil, c’est surtout sa simplicité d’utilisation ! Enfin quelque chose de bien pensé, rassurant et moderne [...]” ",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud.",
|
||||
company: "Company"
|
||||
},
|
||||
{
|
||||
|
|
@ -28,7 +27,7 @@ function TestimonialsSection(props) {
|
|||
name: "Shawna Murray",
|
||||
role: "Software Engineer",
|
||||
bio:
|
||||
"“J’ai 4 locations à gérer : j’étais vite débordé avant, mais maintenant tout est centralisé sur mon compte. Si je n'ai pas le temps de me connecter, je reçois quand même toujours les notifications par mail !” ",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum consequatur numquam aliquam tenetur ad amet inventore hic beatae, quas accusantium perferendis sapiente explicabo, corporis totam!",
|
||||
company: "Company"
|
||||
},
|
||||
{
|
||||
|
|
@ -36,7 +35,7 @@ function TestimonialsSection(props) {
|
|||
name: "Blake Elder",
|
||||
role: "Designer",
|
||||
bio:
|
||||
"“Avant, j’envoyais un chèque par la poste... mais c’est bien plus pratique maintenant de payer mon loyer : réglé en un clic, trace du paiement, quittance envoyée par email...” ",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dolorum consequatur numquam aliquam tenetur ad amet inventore hic beatae.",
|
||||
company: "Company"
|
||||
}
|
||||
]}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue