Skip to content

Commit

Permalink
Ubah Design dikit gak ngaruh
Browse files Browse the repository at this point in the history
  • Loading branch information
MFathinHalim committed Jul 28, 2023
1 parent c25c96a commit 0754285
Show file tree
Hide file tree
Showing 15 changed files with 890 additions and 304 deletions.
411 changes: 411 additions & 0 deletions client/package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@emotion/react": "^11.11.1",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
Expand All @@ -15,8 +16,10 @@
"react-dom": "^18.2.0",
"react-router": "^6.14.0",
"react-router-dom": "^6.14.2",
"react-script": "^2.0.5",
"react-scripts": "5.0.1",
"socket.io-client": "^4.7.1",
"theme-ui": "^0.16.0",
"web-vitals": "^2.1.4"
},
"devDependencies": {
Expand Down
8 changes: 2 additions & 6 deletions client/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Sosmed karya anak gabut"
/>
<meta name="description" content="Sosmed karya anak gabut" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
Expand All @@ -26,7 +22,7 @@
-->
<title>React App</title>
</head>
<body>
<body class="bg-dark text-white">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
Expand Down
1 change: 1 addition & 0 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function App() {

return (
<>

<Navbar handleShow={handleShow} />
<Post show={show} handleClose={handleClose} />
<Outlet />
Expand Down
70 changes: 47 additions & 23 deletions client/src/components/Navbar.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,62 @@
import React, { useState } from "react"
import "../styles/navbar.css"
import { Navbar as BsNavbar, Nav, Form, Button } from "react-bootstrap"
import { NavLink, useNavigate } from "react-router-dom"
import React, { useState } from "react";
import "../styles/navbar.css";
import { Navbar as BsNavbar, Nav, Form, Button } from "react-bootstrap";
import { NavLink, useNavigate } from "react-router-dom";

function Navbar({ handleShow }) {
const navigate = useNavigate()
const navigate = useNavigate();

const [query, setQuery] = useState("")
const [query, setQuery] = useState("");

const handleSubmit = (e) => {
e.preventDefault()
let type = window.location.href.split("/")[3]
if (type != "memes" && type != "anime") type = "main"
navigate(`${type !== "main" ? `/${type}` : ""}/search?q=${query}`)
}
e.preventDefault();
let type = window.location.href.split("/")[3];
if (type != "memes" && type != "anime") type = "main";
navigate(`${type !== "main" ? `/${type}` : ""}/search?q=${query}`);
};

return (
<BsNavbar bg="light" sticky="top" expand="lg">
<BsNavbar.Brand as={NavLink} to="/">Menfess</BsNavbar.Brand>
<BsNavbar.Toggle aria-controls="basic-navbar-nav" />
<BsNavbar
bg="secondary"
variant="secondary"
className="text-light"
sticky="top"
expand="lg">
<BsNavbar.Brand as={NavLink} to="/" className="m-2 text-light">
Menfess
</BsNavbar.Brand>
<BsNavbar.Toggle
aria-controls="basic-navbar-nav"
className="m-2 text-light"
/>
<BsNavbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link as={NavLink} to="/">Home</Nav.Link>
<Nav.Link as={NavLink} to="/memes">Memes</Nav.Link>
<Nav.Link as={NavLink} to="/anime">Anime</Nav.Link>
<Nav.Link className="m-2 text-light" as={NavLink} to="/">
Home
</Nav.Link>
<Nav.Link className="m-2 text-light" as={NavLink} to="/memes">
Memes
</Nav.Link>
<Nav.Link className="m-2 text-light" as={NavLink} to="/anime">
Anime
</Nav.Link>
</Nav>
<Form inline="true" onSubmit={handleSubmit}>
<Form.Control required type="text" onChange={(e) => setQuery(e.target.value)} value={query} placeholder="Search" className="mr-sm-2" />
<Button variant="outline-success" type="submit">Search</Button>
<Form inline="true" onSubmit={handleSubmit} className="m-1 text-light">
<Form.Control
required
type="text"
onChange={(e) => setQuery(e.target.value)}
value={query}
placeholder="Search"
className="mr-sm-2 text-light"
/>
</Form>
<Button onClick={handleShow}>New Post</Button>
<Button className="m-2 text-light" onClick={handleShow}>
New Post
</Button>
</BsNavbar.Collapse>
</BsNavbar>
)
);
}

export default Navbar
export default Navbar;
120 changes: 78 additions & 42 deletions client/src/components/Post.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,89 @@
import React from "react"
import { Link } from "react-router-dom"
import { Button, Card, Col, Row } from "react-bootstrap"
import axios from "axios"
import React, { useCallback } from "react";
import { Link } from "react-router-dom";
import { Button, Card, Col, Row } from "react-bootstrap";
import axios from "axios";

function formatLikeCount(count) {
if (count >= 1000000) {
return (count / 1000000).toFixed(1) + "M";
} else if (count >= 1000) {
return (count / 1000).toFixed(1) + "K";
} else {
return count;
}
}

function Post({ post, type }) {
const handleShare = () => {
const copyText = `${process.env.REACT_APP_BASE_URL}${type != "main" ? `${type}/` : ""}post/${post.noteId}`
const handleShare = useCallback(() => {
const copyText = `${process.env.REACT_APP_BASE_URL}${
type !== "main" ? `${type}/` : ""
}post/${post.noteId}`;
const shareData = {
title: "Menfess!!",
text: `Sebuah Post dari ${post.noteName}`,
url: copyText,
}
};

if (navigator.canShare(shareData)) navigator.share(shareData)
else {
navigator.clipboard.writeText(copyText)
alert("Udah di copy nih, silahkan share ke temen kamu ya:3 (itupun kalo klean punya temen)")
if (navigator.canShare && navigator.canShare(shareData)) {
navigator.share(shareData);
} else {
navigator.clipboard.writeText(copyText);
alert(
"Udah di copy nih, silahkan share ke temen kamu ya:3 (itupun kalo klean punya temen)"
);
}
}
}, [post, type]);

return (
<Card>
<Card.Body>
<Card.Title>{post.noteName}</Card.Title>
<Card.Text>{post.noteContent}</Card.Text>
</Card.Body>
<Card.Img
variant="bottom"
src={`${process.env.REACT_APP_IMAGEKIT_URL_ENDPOINT}image${type != "main" ? type : ""}-${post.noteId}.jpg`}
onError={(e) => e.target.remove()}
/>
<Card.Footer>
<Row>
<Col>
<Button onClick={() => axios.post(`/api/${type}/like/${post.noteId}`)}>
{`${post.like} `}Like
</Button>
</Col>
<Col>
<Button as={Link} to={`/${type != "main" ? `${type}/` : ""}post/${post.noteId}`}>
{`${post.comment.length} `}Comment
</Button>
</Col>
<Col>
<Button onClick={handleShare}>Share</Button>
</Col>
</Row>
</Card.Footer>
</Card>
)
<div className="d-flex justify-content-center align-items-center">
<Card
className="mb-3 m-2 text-center bg-secondary text-white p-1" // Set background color to gray and text color to white
style={{ width: "500px", objectFit: "contain" }}>
<Card.Body>
<Card.Title>{post.noteName}</Card.Title>
<Card.Text>{post.noteContent}</Card.Text>
</Card.Body>
<Card.Img
variant="bottom"
src={`https://ik.imagekit.io/menfessdoma/image${
type !== "main" ? type : ""
}-${post.noteId}.jpg`}
onError={(e) => e.target.remove()}
alt={`Image for post ${post.noteName}`}
className="img-fluid"
style={{
maxHeight: "500px",
maxWidth: "500px",
objectFit: "contain",
}}
/>
<Card.Footer>
<Row className="justify-content-around align-items-center">
<Col xs="auto" sm="auto">
<Button
variant="primary"
onClick={() => axios.post(`/api/${type}/like/${post.noteId}`)}>
{`${formatLikeCount(post.like)} `}
</Button>
</Col>
<Col xs="auto" sm="auto">
<Button
variant="success"
as={Link}
to={`/${type !== "main" ? `${type}/` : ""}post/${post.noteId}`}>
Komen
</Button>
</Col>
<Col xs="auto" sm="auto">
<Button variant="info" onClick={handleShare}>
Bagi
</Button>
</Col>
</Row>
</Card.Footer>
</Card>
</div>
);
}

export default Post
export default Post;
85 changes: 51 additions & 34 deletions client/src/components/modals/Post.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
import React, { useState } from "react"
import { Form, Modal, Button } from "react-bootstrap"
import axios from "axios"
import { useNavigate } from "react-router"
import React, { useState } from "react";
import { Form, Modal, Button } from "react-bootstrap";
import axios from "axios";
import { useNavigate } from "react-router";

function Post({ show, handleClose }) {
const navigate = useNavigate()
const navigate = useNavigate();

const initData = { noteName: "", noteContent: "" }
const [formData, setFormData] = useState(initData)
const [previewUrl, setPreviewUrl] = useState(null)
const { noteName, noteContent } = formData
const initData = { noteName: "", noteContent: "" };
const [formData, setFormData] = useState(initData);
const [previewUrl, setPreviewUrl] = useState(null);
const { noteName, noteContent } = formData;

const handleTextInputChange = e => {
const { name, value } = e.target
setFormData({ ...formData, [name]: value })
}
const handleTextInputChange = (e) => {
const { name, value } = e.target;
setFormData({ ...formData, [name]: value });
};

const handleFileInputChange = e => {
const image = e.target.files[0]
setFormData({ ...formData, image })
setPreviewUrl(URL.createObjectURL(image))
}
const handleFileInputChange = (e) => {
const image = e.target.files[0];
setFormData({ ...formData, image });
setPreviewUrl(URL.createObjectURL(image));
};

const handleSubmit = async () => {
let type = window.location.href.split("/")[3]
if (type != "memes" && type != "anime") type = "main"
navigate(`/${type !== "main" ? type : ""}`)
await axios.postForm(`/api/${type}/post`, formData)
setFormData(initData)
handleClose()
}
let type = window.location.href.split("/")[3];
if (type != "memes" && type != "anime") type = "main";
navigate(`/${type !== "main" ? type : ""}`);
await axios.postForm(`/api/${type}/post`, formData);
setFormData(initData);
handleClose();
};

return (
<Modal show={show} onHide={handleClose}>
Expand All @@ -40,31 +40,48 @@ function Post({ show, handleClose }) {
<Form>
<Form.Group controlId="name">
<Form.Label>Name</Form.Label>
<Form.Control required type="text" value={noteName} onChange={handleTextInputChange} name="noteName" placeholder="Masukkan nama" />
<Form.Control
required
type="text"
value={noteName}
onChange={handleTextInputChange}
name="noteName"
placeholder="Masukkan nama"
/>
</Form.Group>
<Form.Group controlId="content">
<Form.Label>Content</Form.Label>
<Form.Control required as="textarea" value={noteContent} onChange={handleTextInputChange} rows="3" name="noteContent" placeholder="Ketik aja" />
<Form.Control
required
as="textarea"
value={noteContent}
onChange={handleTextInputChange}
rows="3"
name="noteContent"
placeholder="Ketik aja"
/>
</Form.Group>
<Form.Group controlId="image">
<Form.Control required name="image" type="file" onChange={handleFileInputChange} />
<Form.Control
required
name="image"
type="file"
onChange={handleFileInputChange}
/>
</Form.Group>
</Form>
<div>
<h3>Preview Gambar</h3>
<img src={previewUrl} alt="Preview"/>
<img src={previewUrl} alt="Preview" />
</div>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
<Button variant="primary" onClick={handleSubmit}>
Send
</Button>
</Modal.Footer>
</Modal>
)
);
}

export default Post
export default Post;
5 changes: 0 additions & 5 deletions client/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,3 @@ root.render(
<Router />
</React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();
Loading

0 comments on commit 0754285

Please sign in to comment.