Skip to content

Commit 65fc337

Browse files
authored
Merge pull request #1 from comet19950902/dev
working well
2 parents e2df7df + c162238 commit 65fc337

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+8464
-2
lines changed

.env

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#MONGODB_URL=mongodb+srv://goodluckydev:fTz8yAS3T89IuF8A@cluster0.sli4ekj.mongodb.net/purelyblog
2+
NEXTAUTH_SECRET=http://127.0.0.1
3+
MONGODB_URL=mongodb://127.0.0.1:27017/purelyblog
4+
CLOUDINARY_CLOUD_NAME=dobysttjt
5+
CLOUDINARY_API_KEY=599714117419491
6+
CLOUDINARY_API_SECRET=blEW5B3nSOgspPpdGaa3j7dnr4c
7+
GOOGLE_CLIENT_ID
8+
GOOGLE_CLIENT_SECRET
9+
GITHUB_CLIENT_ID
10+
GITHUB_CLIENT_SECRET

.eslintrc.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"extends": "next/core-web-vitals"
3+
}

.gitignore

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
*.pem
21+
22+
# debug
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
27+
# local env files
28+
.env*.local
29+
30+
# vercel
31+
.vercel
32+
33+
# typescript
34+
*.tsbuildinfo
35+
next-env.d.ts

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
1-
# purelyblog-nextjs
2-
nextjs, mongoose, cloudinary, flowbite-react
1+
Please set following variables to the .env file
2+
3+
#MONGODB_URL=mongodb+srv://goodluckydev:fTz8yAS3T89IuF8A@cluster0.sli4ekj.mongodb.net/purelyblog
4+
NEXTAUTH_SECRET=http://127.0.0.1
5+
MONGODB_URL=mongodb://127.0.0.1:27017/purelyblog
6+
CLOUDINARY_CLOUD_NAME=dobysttjt
7+
CLOUDINARY_API_KEY=599714117419491
8+
CLOUDINARY_API_SECRET=blEW5B3nSOgspPpdGaa3j7dnr4c
9+
GOOGLE_CLIENT_ID
10+
GOOGLE_CLIENT_SECRET
11+
GITHUB_CLIENT_ID
12+
GITHUB_CLIENT_SECRET

app/(root)/communities/page.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const page = () => {
2+
return <div>Communities</div>;
3+
};
4+
5+
export default page;

app/(root)/layout.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import "../globals.css";
2+
import type { Metadata } from "next";
3+
import { Inter } from "next/font/google";
4+
import LeftSideBar from "@/components/shared/LeftSideBar";
5+
import RightSideBar from "@/components/shared/RightSideBar";
6+
import AuthProvider from "@/context/AuthProvider";
7+
import { Toaster } from "react-hot-toast";
8+
9+
const inter = Inter({ subsets: ["latin"] });
10+
11+
export const metadata: Metadata = {
12+
title: "PurelyBlog",
13+
description: "Blog application using NextJS",
14+
};
15+
16+
export default function RootLayout({
17+
children,
18+
}: {
19+
children: React.ReactNode;
20+
}) {
21+
return (
22+
<html lang="en">
23+
<AuthProvider>
24+
<body className={inter.className}>
25+
<main className="flex flex-row min-h-screen">
26+
<LeftSideBar />
27+
<section className="flex w-full">
28+
<Toaster position="top-center" reverseOrder={false} />
29+
<div className="m-16 w-full">{children}</div>
30+
</section>
31+
<RightSideBar />
32+
</main>
33+
</body>
34+
</AuthProvider>
35+
</html>
36+
);
37+
}

app/(root)/new-post/page.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import PostForm from "@/components/posts/PostForm";
2+
3+
const Page = async () => {
4+
return <PostForm />;
5+
};
6+
7+
export default Page;

app/(root)/notifications/page.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const page = () => {
2+
return <div>Notifications page</div>;
3+
};
4+
5+
export default page;

app/(root)/page.tsx

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import PostCard from "@/components/posts/PostCard";
2+
import { getPosts } from "@/lib/actions/posts.actions";
3+
import toast from "react-hot-toast";
4+
5+
export default async function Home() {
6+
const { posts, error } = await getPosts();
7+
8+
if (error) {
9+
return <div>Oops! Something went wrong...</div>;
10+
}
11+
12+
if (posts?.length === 0) {
13+
return <div>No posts found</div>;
14+
}
15+
16+
return (
17+
<div>
18+
<div className="p-4">
19+
<h1 className="text-2xl font-bold mb-10">Latest posts</h1>
20+
<div className="flex flex-col gap-8">
21+
{posts?.map((post) => (
22+
<PostCard
23+
key={post._id}
24+
id={post._id.toString()}
25+
text={post.text}
26+
title={post.title}
27+
image={post.image}
28+
createdAt={post.createdAt}
29+
authorUsername={post.author.username}
30+
authorName={post.author.name}
31+
authorImage={post.author.image}
32+
/>
33+
))}
34+
</div>
35+
</div>
36+
</div>
37+
);
38+
}

app/(root)/posts/[id]/edit/page.tsx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import PostForm from "@/components/posts/PostForm";
2+
import { getPost } from "@/lib/actions/posts.actions";
3+
import toast from "react-hot-toast";
4+
5+
const Page = async ({ params }: { params: { id: string } }) => {
6+
const { post, error } = await getPost(params.id);
7+
8+
if (error) {
9+
toast.error(error);
10+
return;
11+
}
12+
13+
return (
14+
<PostForm
15+
title={post.title}
16+
text={post.text}
17+
image={post.image}
18+
id={post.id.toString()}
19+
/>
20+
);
21+
};
22+
23+
export default Page;

app/(root)/posts/[id]/page.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import PostCard from "@/components/posts/PostCard";
2+
import { getPost } from "@/lib/actions/posts.actions";
3+
import toast from "react-hot-toast";
4+
5+
const Page = async ({ params }: { params: { id: string } }) => {
6+
const result = await getPost(params.id);
7+
8+
if (result?.error) {
9+
toast.error(result.error);
10+
return;
11+
}
12+
const { post } = result;
13+
14+
return (
15+
<PostCard
16+
key={post._id}
17+
id={post._id.toString()}
18+
text={post.text}
19+
title={post.title}
20+
image={post.image}
21+
createdAt={post.createdAt}
22+
authorUsername={post.author.username}
23+
authorName={post.author.name}
24+
authorImage={post.author.image}
25+
/>
26+
);
27+
};
28+
29+
export default Page;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import UserEditForm from "@/components/user/UserEditForm";
2+
import { getUser } from "@/lib/actions/user.actions";
3+
import { useSession } from "next-auth/react";
4+
import toast from "react-hot-toast";
5+
6+
const Page = async ({ params }: { params: { username: string } }) => {
7+
const result = await getUser({ username: params.username });
8+
9+
if (result?.error) {
10+
toast.error(result.error);
11+
return;
12+
}
13+
const { user } = result;
14+
return (
15+
<>
16+
<h1 className="text-2xl font-bold">Edit user {user.username}</h1>
17+
<UserEditForm
18+
name={user.name}
19+
username={user.username}
20+
email={user.email}
21+
image={user.image}
22+
bio={user.bio}
23+
/>
24+
</>
25+
);
26+
};
27+
28+
export default Page;

app/(root)/users/[username]/page.tsx

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import Button from "@/components/ui/Button";
2+
import UserPosts from "@/components/user/UserPosts";
3+
import { getUser } from "@/lib/actions/user.actions";
4+
import { getServerSession } from "next-auth";
5+
import Image from "next/image";
6+
import { toast } from "react-hot-toast";
7+
import { BiEditAlt, BiArchive } from "react-icons/bi";
8+
9+
const page = async ({ params }: { params: { username: string } }) => {
10+
const { user, error } = await getUser({ username: params.username });
11+
const session = await getServerSession();
12+
13+
const isSelf = user?.email === session?.user?.email;
14+
15+
if (error) {
16+
toast.error(error);
17+
return;
18+
}
19+
20+
return (
21+
<div>
22+
<div className="flex flex-row gap-28 px-10 mb-10">
23+
<div>
24+
<Image
25+
src={user.image}
26+
width={175}
27+
height={175}
28+
alt={user.username}
29+
className="rounded-full"
30+
/>
31+
</div>
32+
<div className="flex flex-col gap-6">
33+
<div className="flex flex-row gap-4 items-center">
34+
<span className="text-xl font-bold">{user.username}</span>
35+
{isSelf ? (
36+
<>
37+
<Button
38+
text="Edit profile"
39+
bgColor="bg-gray-100"
40+
textColor="text-black"
41+
icon={<BiEditAlt />}
42+
src={`/users/${params.username}/edit`}
43+
/>
44+
<Button
45+
text="Show archive"
46+
bgColor="bg-gray-100"
47+
textColor="text-black"
48+
icon={<BiArchive />}
49+
/>
50+
</>
51+
) : (
52+
<Button
53+
text="Follow"
54+
bgColor="bg-cyan-700"
55+
textColor="text-white"
56+
/>
57+
)}
58+
</div>
59+
<div className="flex flex-row gap-8 items-center">
60+
<div>
61+
<span className="font-bold">0</span> posts
62+
</div>
63+
<div>
64+
<span className="font-bold">0</span> followers
65+
</div>
66+
<div>
67+
<span className="font-bold">0</span> following
68+
</div>
69+
</div>
70+
<div className="text-sm">{user.bio}</div>
71+
</div>
72+
</div>
73+
<hr />
74+
<UserPosts userId={user._id} />
75+
</div>
76+
);
77+
};
78+
79+
export default page;

app/(root)/users/page.tsx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import SearchBar from "@/components/shared/SearchBar";
2+
import UserCard from "@/components/user/UserCard";
3+
import { getUsers } from "@/lib/actions/user.actions";
4+
import { getServerSession } from "next-auth";
5+
6+
const Page = async ({
7+
params,
8+
searchParams,
9+
}: {
10+
params: { slug: string };
11+
searchParams?: { [key: string]: string | string[] | undefined };
12+
}) => {
13+
const session = await getServerSession();
14+
const currentUser = session?.user?.email || "";
15+
const result = await getUsers({
16+
currentUser,
17+
searchString: searchParams?.q as string,
18+
});
19+
20+
if (result?.error) {
21+
console.log(result.error);
22+
return;
23+
}
24+
25+
return (
26+
<div>
27+
<SearchBar searchType="users" />
28+
<ul className="my-4 divide-y divide-gray-200 dark:divide-gray-700">
29+
{result?.results && result?.results > 0 ? (
30+
result?.users?.map((user) => (
31+
<li key={user._id} className="py-2 sm:py-4">
32+
<UserCard
33+
name={user.name}
34+
username={user.username}
35+
email={user.email}
36+
image={user.image}
37+
/>
38+
</li>
39+
))
40+
) : (
41+
<p className="text-2xl font-bold">No users found.</p>
42+
)}
43+
</ul>
44+
</div>
45+
);
46+
};
47+
48+
export default Page;

0 commit comments

Comments
 (0)