Skip to content
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

Dev #249

Merged
merged 4 commits into from
Aug 4, 2022
Merged

Dev #249

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions app/Http/Controllers/PostsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

use function PHPUnit\Framework\isEmpty;

class PostsController extends Controller
{
/**
Expand All @@ -45,7 +48,7 @@ public function index()
*
* @return \Illuminate\Http\RedirectResponse
*/
private function checkRateLimiter(string $postType, $perMinute = 3): \Illuminate\Http\RedirectResponse|null
private function checkRateLimiter(string $postType, $perMinute = 5): \Illuminate\Http\RedirectResponse|null
{
$key = "posts-store-{$postType}-" . Auth::id();
if (RateLimiter::tooManyAttempts($key, $perMinute)) {
Expand Down Expand Up @@ -79,6 +82,7 @@ public function store(Request $request)
[
'description' => 'required|string|min:4|max:200',
'tags' => 'string|min:3|max:15|nullable',
'image' => 'image|mimes:jpg,png,jpeg,gif|max:1048|nullable',
'token' => 'required'
]
);
Expand All @@ -88,15 +92,18 @@ public function store(Request $request)

$posts = new Posts();

if ($request->hasFile('image')) {
$fileName = Auth::user()->username . Str::random(60) . '.' . $request->image->getClientOriginalExtension();
$request->file('image')->storeAs('images/posts', $fileName);
$posts->image = $fileName;
}
$posts->description = $request->description;
$posts->author = auth()->user()->username;
$posts->user_id = auth()->user()->id;
$posts->hashtag = $tags ? $hashtag : NULL;

$posts->save();

$this->mentionUsers($request->description, $posts);

return to_route('posts.main')->with('message', 'Posting Berhasil');
}

Expand Down
21 changes: 21 additions & 0 deletions resources/js/Components/Dashboard/CreatePost.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ const CreatePost = ({ props }) => {
const [textTagged, setTextTagged] = useState("");
const [isLimit, setIsLimit] = useState(false);
const [isErrorNotif, setIsErrorNotif] = useState(false);
const [imageFile, setImageFile] = useState();
const [imagePreview, setImagePreview] = useState("");

const regexHastag = new RegExp(/(^|\W)(#[a-z\d][\w-]*)/ig);

Expand All @@ -32,12 +34,24 @@ const CreatePost = ({ props }) => {
props.errors ? setIsErrorNotif(true) : setIsErrorNotif(false)
}, [props.errors])

const handleImagePost = (e) => {
setImageFile(e)
}

useEffect(() => {
if (!imageFile || imageFile.length < 1) return;
setImagePreview(URL.createObjectURL(imageFile))
return () => setImagePreview("")
}, [imageFile])

const submitPost = () => {
const data = {
description: description,
tags: textTagged.length > 0 ? textTagged[0].replace(/\s/g, "") : null,
image: imageFile ? imageFile : null,
token: props.auth.user.token,
};

return isValid && Inertia.post("/dashboard/manage-posts/posts", data);
}

Expand Down Expand Up @@ -83,13 +97,20 @@ const CreatePost = ({ props }) => {
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
{isErrorNotif && <NotificationAlert message={props.errors.description} />}
{props.errors && <NotificationAlert message={props.errors.image} />}
<span>
{!limiter
? "Ngetiknya udah dulu ya, simpen buat postingan berikutnya 👍"
: `Saat ini postingan kamu dibatasi ${limiter} karakter`}
</span>
</div>
</div>
<div className="w-full lg:w-1/2">
{imagePreview &&
<div className="image-full pb-4"><img src={imagePreview} /></div>
}
<input type="file" name="image" accept="image/*" onChange={(e) => handleImagePost(e.target.files[0])} />
</div>
<i>{textTagged[0]}</i>
<div className="relative w-full rounded-lg border-4 p-2 lg:w-1/2">
<div
Expand Down
8 changes: 4 additions & 4 deletions resources/js/Components/Dashboard/IntegrationCLI.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import React, {useState} from "react";
import {Inertia} from "@inertiajs/inertia";
import React, { useState } from "react";
import { Inertia } from "@inertiajs/inertia";
import NotificationAlert from "../Default/NotificationAlert";

const IntegrationCLI = ({token, props, secret, cli}) => {
const IntegrationCLI = ({ token, props, secret, cli }) => {
const [isCLIRequest, setIsCLIRequest] = useState(false);
const [isCLIGuide, setIsCLIGuide] = useState(false);

const requestActivatingCLI = request => {
setIsCLIRequest(false);
return Inertia.put("/dashboard/integration/cuy-cli", {isActive: request, token: token});
return Inertia.put("/dashboard/integration/cuy-cli", { isActive: request, token: token });
};

return (
Expand Down
25 changes: 14 additions & 11 deletions resources/js/Components/Homepage/PostList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,10 @@ export default function PostList(props) {
};

return (
<div className="bg-base card mb-10 w-full shadow-lg dark:bg-slate-700 dark:text-white md:w-2/3">
<div className="bg-base card mb-10 w-full shadow-lg dark:bg-slate-700 dark:text-white md:w-2/3 ">
{props.posts.image &&
<img src={`/storage/images/posts/${props.posts.image}`} className="image-full" />
}
<RenderIfTrue isTrue={showNotif}>
<NotificationAlert message={props.notif} />
</RenderIfTrue>
Expand Down Expand Up @@ -160,12 +163,12 @@ export default function PostList(props) {
onClick={() => likePost(props.posts.id)}
type="button"
className={`${props.user == null
? "btn-sm cursor-not-allowed rounded-md border-none bg-secondary uppercase"
: `btn-sm rounded-md border-none bg-secondary uppercase
? "btn-sm cursor-not-allowed rounded-md border-none bg-secondary uppercase"
: `btn-sm rounded-md border-none bg-secondary uppercase
${props.is_liked_post
? "bg-primary-focus hover:bg-primary"
: "bg-secondary hover:bg-primary hover:text-base-100"
}`
? "bg-primary-focus hover:bg-primary"
: "bg-secondary hover:bg-primary hover:text-base-100"
}`
}
`}
disabled={!props.user ? true : false}>
Expand All @@ -175,12 +178,12 @@ export default function PostList(props) {
onClick={() => savePost(props.posts.id)}
type="button"
className={`${props.user == null
? "btn-sm cursor-not-allowed rounded-md bg-secondary uppercase"
: `btn-sm rounded-md bg-secondary uppercase
? "btn-sm cursor-not-allowed rounded-md bg-secondary uppercase"
: `btn-sm rounded-md bg-secondary uppercase
${props.is_saved_post
? "bg-primary-focus hover:bg-primary"
: "bg-secondary hover:bg-primary hover:text-base-100"
}`
? "bg-primary-focus hover:bg-primary"
: "bg-secondary hover:bg-primary hover:text-base-100"
}`
}
`}
disabled={!props.user ? true : false}>
Expand Down
37 changes: 23 additions & 14 deletions resources/js/Components/Homepage/PostsLists.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,33 @@ const noPosts = () => {
const isPosts = (posts, from) => {
return posts.map((post, i) => {
let more = false;
let desc = post.description
if (desc.length > 30) {
desc = desc.slice(0, 80)
let desc_no_image = post.description
let desc_with_image = post.description
if (post.image && post.description.length > 20) {
desc_with_image = desc_with_image.slice(0, 20)
more = true
}
if (!post.image && post.description.length > 150) {
desc_no_image = desc_no_image.slice(0, 150)
more = true
}
return (
<div
<Link
href={`/post/${post.id}`} method="get" as="div"
key={i}
className="cursor-pointer md:border-2 md:p-2 bg-base-100 transition-all duration-300 hover:-translate-y-1 hover:bg-primary hover:text-primary-content dark:bg-slate-700 dark:text-white dark:hover:bg-gray-600 w-full md:w-1/2 lg:w-1/3 xl:w-1/4">
<Link href={`/post/${post.id}`} method="get" as="div" className="flex flex-col p-4 justify-evenly">
<div className="text-md break-words h-20">
{desc}
className="card-normal cursor-pointer md:py-2 md:px-1 bg-base-100 transition-all duration-300 dark:bg-slate-700 dark:text-white dark:hover:bg-gray-600 w-full md:w-1/2 md:h-full">
{post.image &&
<img src={`/storage/images/posts/${post.image}`} className="relative pt-2 md:pt-0 block md:max-h-72 w-auto h-auto min-w-full" />
}
<div className={`flex flex-col shadow-md p-4 justify-between h-auto hover:-translate-y-1 hover:bg-primary hover:text-primary-content`}>
<div className="text-md break-words">
{post.image ? desc_with_image : desc_no_image}
{more && <span className="italic text-sm text-primary"> ...lebih lengkap</span>}
</div>

<div className="mt-2 flex flex-row items-center">
<div className="mt-2 py-2 flex flex-row items-center">
<Link href={`/author/${post.author}`} as="button" method="get" className="avatar">
<div className="w-6 rounded-full ring ring-primary ring-offset-2 ring-offset-base-100">
<div className="w-6 rounded-full">
{from?.page == "author" ? (
<img
src={
Expand All @@ -51,16 +60,16 @@ const isPosts = (posts, from) => {
)}
</div>
</Link>
<div className="ml-4 text-sm">
<div className="ml-2 text-2xs">
<p className="leading-none dark:text-white">{post.author}</p>
<p className="break-normal text-xs">
<p className="break-normal">
posted {formatTime(post.updated_at)} |{" "}
{post.comments && post.comments.length > 0 ? post.comments.length : "no"} comment
</p>
</div>
</div>
</Link>
</div>
</div>
</Link>
);
});
};
Expand Down
12 changes: 2 additions & 10 deletions resources/js/Pages/AuthorList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,9 @@ export default function AuthorListPage(props) {
<Guest auth={props.auth.user}>
<Head title={props.title} />
<div className="min-h-screen">
<div className="pt-6 text-center">
<h1 className="text-lg font-bold dark:text-white" data-aos="zoom-in" data-aos-duration="1500">
✨ {props.title} ✨
</h1>
<p className="text-sm dark:text-white" data-aos="zoom-in" data-aos-duration="1500">
{props.description}
</p>
</div>
<div className="flex w-full p-4 lg:w-2/3 lg:p-0 lg:py-2 lg:mx-auto">
<div className="flex w-full p-4 lg:w-2/4 mx-auto">
<input
className="h-10 w-full rounded-lg border border-gray-200 bg-slate-100 placeholder:text-gray-600 focus:border-blue-400 focus:outline-none focus:ring focus:ring-blue-100 dark:border-slate-500 dark:bg-slate-900 dark:placeholder:text-slate-100 dark:focus:border-slate-500 dark:focus:ring-0"
className="h-10 w-full md:w-1/2 md:mx-auto px-4 rounded-lg border border-gray-200 bg-slate-100 placeholder:text-gray-600 focus:border-blue-400 focus:outline-none focus:ring focus:ring-blue-100 dark:border-slate-500 dark:bg-slate-900 dark:placeholder:text-slate-100 dark:focus:border-slate-500 dark:focus:ring-0"
autoComplete="off"
type="text"
name="search"
Expand Down
23 changes: 12 additions & 11 deletions resources/js/Pages/Dashboard/MyPosts.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, {useEffect, useState} from "react";
import React, { useEffect, useState } from "react";

import Authenticated from "@/Layouts/Authenticated";
import {Head, Link} from "@inertiajs/inertia-react";
import {usePage} from "@inertiajs/inertia-react";
import {formatTime} from "@/utils/jsHelper";
import {Inertia} from "@inertiajs/inertia";
import { Head, Link } from "@inertiajs/inertia-react";
import { usePage } from "@inertiajs/inertia-react";
import { formatTime } from "@/utils/jsHelper";
import { Inertia } from "@inertiajs/inertia";
import NotificationAlert from "@/Components/Default/NotificationAlert";
import {TbTrashX} from "react-icons/tb";
import { TbTrashX } from "react-icons/tb";

export default function MyPosts(props) {
const {flash} = usePage().props;
const { flash } = usePage().props;
const [showNotif, setShowNotif] = useState(false);

useEffect(() => {
Expand Down Expand Up @@ -46,19 +46,20 @@ export default function MyPosts(props) {
<Head title="Dashboard" />
<div className="lg:items-strech flex flex-col items-center justify-center gap-6 py-6 px-4 lg:flex-row lg:flex-wrap">
{showNotif && <NotificationAlert message={flash.message} />}

{props.data.length > 0 ? (
props.data.map((posts, i) => {
return (
<div
key={i}
className="card w-full cursor-pointer bg-base-100 text-base-content shadow-lg transition-all duration-300 hover:-translate-y-1 hover:delay-75 dark:bg-slate-700 dark:text-white dark:hover:bg-gray-600 md:w-1/2 lg:w-1/3 xl:w-1/3">
<div className="card-body">
{posts.image &&
<img src={`/storage/images/posts/${posts.image}`} className="image-full" />
}
<Link href={`/post/${posts.id}`} method="get" as="div" className="card-title">
<p
className={`cursor-pointer text-left text-xl transition-all duration-300 hover:-translate-y-1 ${
posts.description.length > 80 ? "overflow-x-hidden pr-2" : "break-words"
} h-20`}>
className={`cursor-pointer text-left text-xl transition-all duration-300 hover:-translate-y-1 ${posts.description.length > 80 ? "overflow-x-hidden pr-2" : "break-words"
} h-20`}>
{posts.description}
</p>
</Link>
Expand Down
9 changes: 7 additions & 2 deletions resources/js/Pages/Post.jsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React from "react";
import { Head } from "@inertiajs/inertia-react";
import { Head, Link } from "@inertiajs/inertia-react";
import PostList from "@/Components/Homepage/PostList";
import Guest from "@/Layouts/Guest";
import { FaArrowLeft } from "react-icons/fa";


export default function PostPage(props) {
return (
<Guest auth={props.auth.user}>
<Head title={props.title} />
<div className="min-h-screen">
<Link className="px-2 pt-2" href="/" as="button">
<FaArrowLeft size={20} />
</Link>
<div
className="flex flex-col items-center justify-center gap-6 px-2 pt-6 lg:flex-row lg:flex-wrap lg:items-stretch lg:px-4"
className="flex flex-col items-center justify-center gap-6 px-2 pt-2 lg:flex-row lg:flex-wrap lg:items-stretch lg:px-4"
data-aos="zoom-in"
data-aos-duration="500">
<PostList
Expand Down
2 changes: 1 addition & 1 deletion resources/js/Pages/Posts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export default function PostsPage(props) {
className="w-full p-2 mx-auto md:w-4/3 lg:w-4/6 xl:w-5/6 md:p-0"
data-aos="zoom-in"
data-aos-duration="500">
<div className="flex flex-row flex-wrap gap-1 md:gap-0 bg-base-200 md:bg-base-100">
<div className="flex flex-row flex-wrap place-items-end gap-1 bg-base-200 md:gap-0 md:bg-base-100">
<PostsList posts={posts} />
</div>
</div>
Expand Down