Skip to content

Commit d5dc2d4

Browse files
authored
Merge pull request #97 from OudomMunint/dev
Dev => Maun
2 parents ca1268e + 6433694 commit d5dc2d4

File tree

7 files changed

+135
-82
lines changed

7 files changed

+135
-82
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
run: npx eslint --no-error-on-unmatched-pattern.
2828

2929
- name: Run all tests
30-
run: npm run test
30+
run: npm test
3131

3232
- name: Generate build
3333
env:
@@ -45,4 +45,4 @@ jobs:
4545
uses: ncipollo/release-action@v1.14.0
4646
with:
4747
artifacts: "react-github-actions-build"
48-
tag: v1.5.5.1
48+
tag: v1.5.5.2

src/App.test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ test('Find contact form', async () => {
3030
expect(formFieldMessage).toBeInTheDocument();
3131
});
3232

33+
// Test Alert message
34+
test('Find alert message', () => {
35+
render(<ContactForm />);
36+
const alertMessage = screen.getByText(/This website serves as a showcase of my development work/i);
37+
expect(alertMessage).toBeInTheDocument();
38+
});
39+
3340
// Test form submit button
3441
test('Find form submit button', () => {
3542
render(<ContactForm />);

src/components/AlertComponent.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import React, { useState, useEffect, useCallback } from "react";
2+
3+
const hideAlert = () => {
4+
const alertElement = document.querySelector(".alert-container");
5+
if (alertElement) {
6+
alertElement.classList.add("hidden");
7+
}
8+
};
9+
10+
const AlertComponent = ({ message, animateAlert }) => {
11+
return (
12+
<div className={`alert-container ${animateAlert ? "" : "hidden"}`} id="alert">
13+
<p style={{ margin: "0" }}>
14+
{message}
15+
</p>
16+
<button
17+
onClick={hideAlert}
18+
style={{
19+
backgroundColor: "transparent",
20+
border: "none",
21+
color: "#721c24",
22+
cursor: "pointer",
23+
float: "right",
24+
}}
25+
>
26+
&#x2715;
27+
</button>
28+
</div>
29+
);
30+
};
31+
32+
export default AlertComponent;

src/components/Contact.js

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,42 @@
11
import React, { useState, useEffect, useCallback } from "react";
2+
import AlertComponent from "./AlertComponent";
23

34
function ContactForm() {
45
const isDevelopment = process.env.NODE_ENV === "development";
56
const [name, setName] = useState("");
67
const [email, setEmail] = useState("");
78
const [message, setMessage] = useState("");
8-
const handleSubmit = useCallback(async (event) => {
9-
event.preventDefault();
10-
let data = { name, email, message };
11-
try {
12-
// clear form
13-
setName('');
14-
setEmail('');
15-
setMessage('');
16-
if (isDevelopment) {
17-
data = {
18-
name: "testUser1",
19-
email: "test@test.com",
20-
message: "Hello, this is a test message."
21-
};
9+
const [animateAlert, setAnimateAlert] = useState(false);
10+
11+
useEffect(() => {
12+
const timer = setTimeout(() => {
13+
setAnimateAlert(true);
14+
}, 500);
15+
return () => clearTimeout(timer);
16+
}, []);
17+
18+
const handleSubmit = useCallback(
19+
async (event) => {
20+
event.preventDefault();
21+
let data = { name, email, message };
22+
try {
23+
setName("");
24+
setEmail("");
25+
setMessage("");
26+
if (isDevelopment) {
27+
data = {
28+
name: "testUser1",
29+
email: "test@test.com",
30+
message: "Hello, this is a test message.",
31+
};
32+
}
33+
console.log("Form submission successful:", data);
34+
} catch (error) {
35+
console.error("Form submission error:", error);
2236
}
23-
console.log('Form submission successful:', data);
24-
} catch (error) {
25-
console.error('Form submission error:', error);
26-
console.log('Error caught');
27-
}
28-
}, [name, email, message, isDevelopment]);
37+
},
38+
[name, email, message, isDevelopment]
39+
);
2940

3041
useEffect(() => {
3142
if (isDevelopment) {
@@ -43,13 +54,26 @@ function ContactForm() {
4354

4455
return (
4556
<>
46-
<form name="contact" netlify="true" netlify-honeypot="bot-field" data-netlify-recaptcha="true" hidden>
57+
<form name="contact" netlify="true" netlify-honeypot="bot-field" data-netlify-recaptcha="true" hidden>
4758
<input type="text" name="name" />
4859
<input type="email" name="email" />
4960
<textarea name="message"></textarea>
5061
</form>
5162

5263
<div className="formFlex">
64+
65+
{/* Alert Message */}
66+
<AlertComponent message={
67+
<>
68+
This website serves as a showcase of my development work. The source code is hosted on GitHub and deployed via my personal Netlify account.
69+
Therefore, all emails sent through this form will be directed to me. For inquiries related to
70+
<strong className="purple"> Studio Zed</strong>, please contact
71+
<a href="https://www.newcastle.edu.au/profile/simone-ocallaghan"> Dr. Simone O'Callaghan</a>.
72+
</>
73+
}
74+
animateAlert={animateAlert} />
75+
76+
{/* Form */}
5377
<div className="form">
5478
<div className="top-bar">
5579
<span></span>
@@ -59,35 +83,21 @@ function ContactForm() {
5983
<div className="title">Get in touch!</div>
6084
<form name="contact" method="POST" data-netlify-recaptcha="true">
6185
<input type="hidden" name="form-name" value="contact" />
62-
63-
{/* Name */}
6486
<div className="input-container ic1">
65-
<label className="form-label" htmlFor="name"></label>
66-
<input className="form-control input" type="text" id="name" name="name" value={name} onChange={(e) => setName(e.target.value)}
67-
placeholder="Name"
68-
required />
87+
<input className="form-control input" type="text" id="name" name="name" value={name}
88+
onChange={(e) => setName(e.target.value)} placeholder="Name" required/>
6989
</div>
70-
71-
{/* Email */}
7290
<div className="input-container ic2">
73-
<label className="form-label" htmlFor="email"></label>
74-
<input className="form-control input" type="email" id="email" name="email" value={email} onChange={(e) => setEmail(e.target.value)}
75-
placeholder="Email"
76-
required
77-
pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
78-
title="Please enter a valid email address"
79-
/>
91+
<input className="form-control input" type="email" id="email" name="email" value={email}
92+
onChange={(e) => setEmail(e.target.value)} placeholder="Email"
93+
required pattern="[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
94+
title="Please enter a valid email address"/>
8095
</div>
81-
82-
{/* Message */}
8396
<div className="input-container ic2">
84-
<label className="form-label" htmlFor="message"></label>
85-
<textarea className="form-control input from-textarea" id="message" name="message" value={message} onChange={(e) => setMessage(e.target.value)}
86-
placeholder="Message"
87-
required />
97+
<textarea className="form-control input from-textarea" id="message" name="message"
98+
value={message} onChange={(e) => setMessage(e.target.value)} placeholder="Message" required/>
8899
</div>
89100
<div data-netlify-recaptcha="true" className="reCaptcha"></div>
90-
{/* Submit */}
91101
<button title="submit" className="btn btn-danger submit" type="submit" style={{ position: "relative", marginTop: "68px" }}>
92102
Submit
93103
</button>

src/components/Projects/ProjectCards.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from "react";
22
import Card from "react-bootstrap/Card";
3-
//import Button from "react-bootstrap/Button";
4-
//import { CgWebsite } from "react-icons/cg";
3+
import Button from "react-bootstrap/Button";
4+
import { CgArrowRight } from "react-icons/cg";
55
//import { BsGithub } from "react-icons/bs";
66

77
function ProjectCards(props) {
@@ -20,21 +20,19 @@ function ProjectCards(props) {
2020
{"\n"}
2121
{"\n"}
2222

23-
{/* If the component contains Demo link and if it's not a Blog then, it will render the below component */}
24-
2523
{!props.isBlog && props.demoLink && (
26-
{/* <Button
24+
<Button
2725
variant="primary"
2826
href={props.demoLink}
2927
target="_blank"
3028
style={{ marginLeft: "10px" }}
3129
>
32-
<CgWebsite /> &nbsp;
33-
{"Demo"}
34-
</Button> */}
30+
<CgArrowRight /> &nbsp;
31+
{"Visit"}
32+
</Button>
3533
)}
3634
</Card.Body>
3735
</Card>
3836
);
3937
}
40-
export default ProjectCards;
38+
export default ProjectCards;

src/components/Projects/Projects.js

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ function Projects() {
3636
isBlog={false}
3737
title="Public Art Workers website and branding"
3838
description="A website, Logo and branding for a newly formed company called Public art workers."
39-
//ghLink="https://github.com/soumyajit4419/Chatify"
40-
//demoLink="https://chatify-49.web.app/"
39+
//ghLink="https://github.com/"
40+
demoLink="https://www.publicartworkers.com/"
4141
/>
4242
</Col>
4343

@@ -46,9 +46,7 @@ function Projects() {
4646
imgPath={JH}
4747
isBlog={false}
4848
title="John Hunter Health anniversary book"
49-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
50-
//ghLink="https://github.com/soumyajit4419/Bits-0f-C0de"
51-
//demoLink="https://blogs.soumya-jit.tech/"
49+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
5250
/>
5351
</Col>
5452

@@ -57,9 +55,7 @@ function Projects() {
5755
imgPath={LocalConnect}
5856
isBlog={false}
5957
title="Local Connections restuarant"
60-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
61-
//ghLink="https://github.com/soumyajit4419/Editor.io"
62-
//demoLink="https://editor.soumya-jit.tech/"
58+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
6359
/>
6460
</Col>
6561

@@ -68,9 +64,7 @@ function Projects() {
6864
imgPath={newcastleArt}
6965
isBlog={false}
7066
title="Newcastle art gallery"
71-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
72-
//ghLink="https://github.com/soumyajit4419/Plant_AI"
73-
//demoLink="https://plant49-ai.herokuapp.com/"
67+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
7468
/>
7569
</Col>
7670

@@ -79,9 +73,7 @@ function Projects() {
7973
imgPath={wanersbay}
8074
isBlog={false}
8175
title="Warners Bay kids book"
82-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
83-
//ghLink="https://github.com/soumyajit4419/AI_For_Social_Good"
84-
// demoLink="https://www.youtube.com/watch?v=dQw4w9WgXcQ&ab_channel=RickAstley" <--------Please include a demo link here
76+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
8577
/>
8678
</Col>
8779

@@ -90,9 +82,7 @@ function Projects() {
9082
imgPath={water}
9183
isBlog={false}
9284
title="Water conservation kids book"
93-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
94-
//ghLink="https://github.com/soumyajit4419/Face_And_Emotion_Detection"
95-
// demoLink="https://blogs.soumya-jit.tech/" <--------Please include a demo link here
85+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
9686
/>
9787
</Col>
9888

@@ -101,9 +91,7 @@ function Projects() {
10191
imgPath={tina}
10292
isBlog={false}
10393
title="This Is Not Art Program"
104-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
105-
//ghLink="https://github.com/soumyajit4419/Face_And_Emotion_Detection"
106-
// demoLink="https://blogs.soumya-jit.tech/" <--------Please include a demo link here
94+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
10795
/>
10896
</Col>
10997

@@ -112,9 +100,7 @@ function Projects() {
112100
imgPath={noWorries}
113101
isBlog={false}
114102
title="No worries rebranding and website"
115-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
116-
//ghLink="https://github.com/soumyajit4419/Face_And_Emotion_Detection"
117-
// demoLink="https://blogs.soumya-jit.tech/" <--------Please include a demo link here
103+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
118104
/>
119105
</Col>
120106

@@ -123,9 +109,7 @@ function Projects() {
123109
imgPath={air}
124110
isBlog={false}
125111
title="Art in Recovery rebrading and commemorative book"
126-
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
127-
//ghLink="https://github.com/soumyajit4419/Face_And_Emotion_Detection"
128-
// demoLink="https://blogs.soumya-jit.tech/" <--------Please include a demo link here
112+
//description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
129113
/>
130114
</Col>
131115

@@ -135,8 +119,6 @@ function Projects() {
135119
isBlog={false}
136120
title="Head 2 Art website and branding project"
137121
description="This project is about [Insert name] it is for [ inset ] by [inset] this project involved [ insert]"
138-
//ghLink="https://github.com/soumyajit4419/Face_And_Emotion_Detection"
139-
// demoLink="https://blogs.soumya-jit.tech/" <--------Please include a demo link here
140122
/>
141123
</Col> */}
142124
</Row>

src/style.css

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,30 @@ a {
785785
left: 0%;
786786
position: relative;
787787
margin-bottom: 210px;
788+
flex-direction: column;
789+
}
790+
791+
.alert-container {
792+
display: flex;
793+
background-color: rgb(247, 200, 205);
794+
color: rgb(114, 28, 36);
795+
padding: 10px;
796+
border: 1px solid rgb(245, 198, 203);
797+
border-radius: 5px;
798+
margin-bottom: 10px;
799+
flex-direction: row;
800+
align-items: center;
801+
width: 100%;
802+
max-width: 800px;
803+
opacity: 1;
804+
transform: translateY(0);
805+
transition: opacity 0.3s ease, transform 0.3s ease;
806+
}
807+
808+
.alert-container.hidden {
809+
opacity: 0;
810+
transform: translateY(-10px);
811+
pointer-events: none; /* Prevent interaction */
788812
}
789813

790814
.form {

0 commit comments

Comments
 (0)