New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add proverb form component #24
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,27 @@ | ||
.button-custom { | ||
background-color: #111; | ||
border-radius: 3px; | ||
box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.15); | ||
color: #fff; | ||
font-weight: 700; | ||
text-transform: uppercase; | ||
letter-spacing: 1px; | ||
border: none; | ||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); | ||
padding: 10px 25px; | ||
font-size: 1rem; | ||
line-height: 24px; | ||
display: inline-block; | ||
position: relative; | ||
outline: none; | ||
white-space: nowrap; | ||
} | ||
.button-custom:hover { | ||
opacity: 0.9; | ||
background-color: #111 !important; | ||
color: #fff; | ||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); | ||
} | ||
|
||
.button-custom, | ||
.button-custom:visited .button-custom:active, | ||
.button-custom:focus { | ||
background-color: #111; | ||
border-radius: 3px; | ||
box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.15); | ||
color: #fff; | ||
font-weight: 700; | ||
text-transform: uppercase; | ||
letter-spacing: 1px; | ||
border: none; | ||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); | ||
padding: 10px 25px; | ||
font-size: 1rem; | ||
line-height: 24px; | ||
display: inline-block; | ||
position: relative; | ||
outline: none; | ||
white-space: nowrap; | ||
} | ||
.button-custom:hover, | ||
.button-custom:visited:hover { | ||
opacity: 0.9; | ||
background-color: #111 !important; | ||
color: #fff; | ||
text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import React from "react"; | ||
import { Modal as ModalBootstrap } from "react-bootstrap"; | ||
|
||
const Modal = ({ children, isOpen, modalClose, dialogClassName, centered }) => { | ||
return ( | ||
<ModalBootstrap | ||
dialogClassName={dialogClassName} | ||
centered={centered} | ||
show={isOpen} | ||
onHide={modalClose} | ||
> | ||
<ModalBootstrap.Header className="border-bottom-0" closeButton /> | ||
{children} | ||
</ModalBootstrap> | ||
); | ||
}; | ||
|
||
export default Modal; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
export const isArabic = (text) => { | ||
const pattern = /[\u0600-\u06FF]/; | ||
const result = pattern.test(text); | ||
return result; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
.add-proverb-modal .modal-content { | ||
padding: 3rem; | ||
} | ||
|
||
.add-proverb-modal .modal-content #proverb-explanation { | ||
height: 10rem; | ||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,19 +1,60 @@ | ||||||
import React from "react"; | ||||||
import React, { useState } from "react"; | ||||||
import ProverbList from "./../proverb/ProverbList"; | ||||||
|
||||||
import AddProverb from "./../proverb/AddProverb"; | ||||||
import Section from "./../../components/Section"; | ||||||
import Breadcrumb from './../../components/Breadcrumb' | ||||||
import Breadcrumb from "./../../components/Breadcrumb"; | ||||||
import Modal from "./../../components/Modal"; | ||||||
import Button from "./../../components/Button"; | ||||||
|
||||||
import "./HomePage.css"; | ||||||
|
||||||
const HomePage = () => { | ||||||
//Modal States | ||||||
const [modal, setModal] = useState({ | ||||||
isOpen: false, | ||||||
type: "", | ||||||
}); | ||||||
|
||||||
//Modal Handlers | ||||||
|
||||||
const handleShowModal = (type) => async (e) => { | ||||||
e.preventDefault(); | ||||||
if (type === "add") { | ||||||
setModal({ | ||||||
isOpen: true, | ||||||
type: "Add", | ||||||
}); | ||||||
} | ||||||
}; | ||||||
return ( | ||||||
<div> | ||||||
<Section | ||||||
<Modal | ||||||
isOpen={modal.isOpen} | ||||||
modalClose={() => setModal({ isOpen: false, type: undefined })} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
you could create a function called handleCloseModal and use it as I wrote above. this could be an implementation:
It's good to have named functions, they are easier to read and to debug than anonymous functions. I would advise You can find a lot of interesting information about arrow functions here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions |
||||||
centered={true} | ||||||
dialogClassName="add-proverb-modal" | ||||||
> | ||||||
{modal.type === "Add" && ( | ||||||
<AddProverb actionType="Add" setModal={setModal} /> | ||||||
)} | ||||||
</Modal> | ||||||
|
||||||
<Section | ||||||
id="page-title" | ||||||
title="PROVERBS" | ||||||
containerClass="d-flex justify-content-between mx-5 align-items-center" | ||||||
> | ||||||
<Breadcrumb /> | ||||||
<Breadcrumb /> | ||||||
</Section> | ||||||
<Button | ||||||
variant="info" | ||||||
text="Add Proverb" | ||||||
onClick={handleShowModal("add")} | ||||||
color="white" | ||||||
type="submit" | ||||||
className="button-custom float-right m-5" | ||||||
id="homepage-add-proverb-button" | ||||||
/> | ||||||
<ProverbList /> | ||||||
</div> | ||||||
); | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import React from "react"; | ||
import Proverb from "./Proverb"; | ||
|
||
const AddProverb = () => { | ||
return <Proverb actionType="Add" />; | ||
}; | ||
|
||
export default AddProverb; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
#add-proverb-button { | ||
background-color: #111; | ||
} | ||
|
||
#add-proverb-button:disabled, | ||
#add-proverb-button:disabled:hover, | ||
#add-proverb-button[disabled] { | ||
background-color: #111; | ||
border-radius: 3px; | ||
box-shadow: inset 0 -3px 0 rgba(0, 0, 0, 0.15); | ||
color: #fff; | ||
opacity: 0.5; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import React, { useState, useEffect } from "react"; | ||
import { Form } from "react-bootstrap"; | ||
import Input from "./../../components/Input"; | ||
import Button from "./../../components/Button"; | ||
import { isArabic } from "./../../helpers/functions"; | ||
|
||
import { PROVERB_INITIAL_DATA } from "./../../helpers/formData"; | ||
import "./Proverb.css"; | ||
|
||
const Proverb = ({ actionType }) => { | ||
const [formData, setFormData] = useState(PROVERB_INITIAL_DATA); | ||
const [disabled, setDisabled] = useState(true); | ||
|
||
const { proverb, translation, explanation } = formData; | ||
|
||
useEffect(() => { | ||
const isFilled = [proverb, translation, explanation].every((data) => | ||
Boolean(data) | ||
); | ||
const result = isArabic(proverb); | ||
const shouldBeDisabled = !isFilled || !result; | ||
setDisabled(shouldBeDisabled); | ||
}, [formData]); | ||
|
||
const handleInputChange = (e) => { | ||
setFormData({ ...formData, [e.target.name]: e.target.value }); | ||
}; | ||
|
||
const onSubmit = async (e) => { | ||
e.preventDefault(); | ||
}; | ||
|
||
return ( | ||
<Form> | ||
<Input | ||
label="Proverb" | ||
id="proverb-proverb" | ||
type="text" | ||
value={proverb} | ||
name="proverb" | ||
onChange={handleInputChange} | ||
placeholder="أضف مثلًا أو تعبيرًا باللغة العربية" | ||
autoComplete="off" | ||
labelClassName="input-form-label my-3" | ||
className="rounded" | ||
/> | ||
<Input | ||
label="Translation" | ||
id="proverb-translation" | ||
type="text" | ||
value={translation} | ||
name="translation" | ||
onChange={handleInputChange} | ||
placeholder="English translation" | ||
autoComplete="off" | ||
labelClassName="input-form-label my-3" | ||
className="rounded" | ||
/> | ||
|
||
<Input | ||
label="Explanation" | ||
id="proverb-explanation" | ||
type="text" | ||
value={explanation} | ||
name="explanation" | ||
onChange={handleInputChange} | ||
placeholder="English explanation" | ||
autoComplete="off" | ||
labelClassName="input-form-label my-3" | ||
className="rounded" | ||
as="textarea" | ||
/> | ||
|
||
<Button | ||
variant="info" | ||
text="Add" | ||
onClick={onSubmit} | ||
color="white" | ||
type="submit" | ||
className="button-custom float-right" | ||
id="add-proverb-button" | ||
disabled={disabled} | ||
/> | ||
</Form> | ||
); | ||
}; | ||
|
||
export default Proverb; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this can be simplified as we are not using the result value.