Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
NadyaHristuk committed Apr 12, 2024
1 parent 0a2bad6 commit 3ccdc36
Show file tree
Hide file tree
Showing 46 changed files with 3,055 additions and 314 deletions.
8 changes: 8 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
MONGO =mongodb+srv://projectoffice:[email protected]/druk_army

PORT=3001
AUTH_SECRET=g5JA~$sH@<GMa$6YzIa+k8185a
BASE_URL=http://localhost:3001
CLOUDINARY_NAME =dxgv5a6mt
CLOUDINARY_KEY=432362782992859
CLOUDINARY_SECRET =gftS1IhhAGqIchmeF_R36n76VYg
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"CodeGPT.apiKey": "CodeGPT Plus Beta"
}
1,612 changes: 1,329 additions & 283 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,29 @@
"lint": "next lint"
},
"dependencies": {
"@next/eslint-plugin-next": "14.0.1",
"bcrypt": "5.1.1",
"i18next": "^23.8.2",
"i18next-resources-to-backend": "^1.2.0",
"modern-normalize": "^2.0.0",
"mongoose": "8.0.0",
"nanoid": "^5.0.5",
"next": "14.1.0",
"next-auth": "^5.0.0-beta.3",
"next-i18n-router": "^5.2.1",
"next-themes": "^0.2.1",
"react": "^18",
"react-copy-to-clipboard": "^5.1.0",
"react-dom": "^18",
"react-i18next": "^14.0.5",
"react-icons": "4.11.0",
"react-quill": "^2.0.0",
"react-responsive": "^9.0.2",
"react-svg": "^16.1.32",
"react-tooltip": "^5.26.3",
"swiper": "^11.0.5"
"recharts": "2.9.0",
"swiper": "^11.0.5",
"use-debounce": "9.0.4"
},
"devDependencies": {
"eslint": "^8",
Expand Down
Binary file added public/astronaut.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/noavatar.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/noproduct.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/app/[...nextauth].js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import NextAuth from "next-auth";
import { authConfig } from "./authConfig";

export default NextAuth({
...authConfig,
// other configurations...
});
19 changes: 19 additions & 0 deletions src/app/[locale]/dashboard/layout.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import Navbar from "../../../components/dashboard/navbar/navbar"
import Sidebar from "../../../components/dashboard/sidebar/sidebar"
import styles from "../../../components/dashboard/dashboard.module.css"

const Layout = ({children}) => {
return (
<div className={styles.container}>
<div className={styles.menu}>
<Sidebar/>
</div>
<div className={styles.content}>
<Navbar/>
{children}
</div>
</div>
)
}

export default Layout
50 changes: 50 additions & 0 deletions src/app/[locale]/dashboard/news/[id]/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { updateNewsArticle } from "@/app/lib/actions";
import { fetchNewsArticle } from "@/app/lib/data";
import styles from "@/components/dashboard/news/singleNews/singleNews.module.css";
import Image from "next/image";

const SingleNewsPage = async ({ params }) => {
const { id } = params;
const article = await fetchNewsArticle(id); // This function needs to be implemented

return (
<div className={styles.container}>
<div className={styles.infoContainer}>
<div className={styles.imgContainer}>
<Image src={article.imageUrl || "/noavatar.png"} alt="" layout="fill" />
</div>
<h2>{article.title}</h2>
<p>{article.description}</p>
<p>Author: {article.author}</p>
<p>Date: {article.date}</p>
<p>Time to read: {article.timeToRead} minutes</p>
<p>Views: {article.views}</p>
</div>
<div className={styles.formContainer}>
<form action={updateNewsArticle} method="POST" className={styles.form}>
<input type="hidden" name="_id" value={article._id} />
<label>Title</label>
<input type="text" name="title" defaultValue={article.title} />
<label>Description</label>
<textarea
name="description"
id="description"
rows="10"
defaultValue={article.description}
></textarea>
<label>Author</label>
<input type="text" name="author" defaultValue={article.author} />
<label>Date</label>
<input type="text" name="date" defaultValue={article.date} />
<label>Time to read (minutes)</label>
<input type="number" name="timeToRead" defaultValue={article.timeToRead} />
<label>Views</label>
<input type="number" name="views" defaultValue={article.views} />
<button type="submit">Update</button>
</form>
</div>
</div>
);
};

export default SingleNewsPage;
39 changes: 39 additions & 0 deletions src/app/[locale]/dashboard/news/add/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"use client"
import dynamic from 'next/dynamic';
import React, { useState } from 'react';
import 'react-quill/dist/quill.snow.css';
import styles from "@/components/dashboard/news/addNews/addNews.module.css";

// Import ReactQuill using dynamic import with SSR disabled
const ReactQuill = dynamic(() => import('react-quill'), {
ssr: false,
loading: () => <p>Loading editor...</p>,
});

const AddNewsPage = () => {
const [description, setDescription] = useState("");

const handleSubmit = async (event) => {
event.preventDefault();
const formData = new FormData(event.target);
formData.append('description', description);
// Assuming addNews is an API that handles the POST request
await addNews(formData);
};

return (
<div className={styles.container}>
<form onSubmit={handleSubmit} className={styles.form}>
<input type="text" placeholder="Title" name="title" required />
<input type="text" placeholder="Author" name="author" required />
<input type="date" placeholder="Date" name="date" required />
<input type="number" placeholder="Time to read (minutes)" name="timeToRead" required />
<input type="number" placeholder="Views" name="views" required />
<ReactQuill theme="snow" value={description} className={styles.quill} onChange={setDescription} />
<button type="submit">Submit</button>
</form>
</div>
);
};

export default AddNewsPage;
73 changes: 73 additions & 0 deletions src/app/[locale]/dashboard/news/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import Image from "next/image";
import Link from "next/link";
import styles from "@/components/dashboard/news/news.module.css";
import Search from "@/components/dashboard/search/search";
import Pagination from "@/components/dashboard/pagination/pagination";
import { fetchNewsArticles } from "@/app/lib/data";
import { deleteNews } from "@/app/lib/actions";
import { NewsList } from "@/components/newsPage";

const newsPage = async ({ searchParams }) => {
const q = searchParams?.q || "";
const page = searchParams?.page || 1;
const { count, news } = await fetchNewsArticles(q, page);

return (
<div className={styles.container}>
<div className={styles.top}>
<Search placeholder="Search for a new..." />
<Link href="/dashboard/news/add">
<button className={styles.addButton}>Add New</button>
</Link>
</div>
<table className={styles.table}>
<thead>
<tr>
<td>Title</td>
<td>Description</td>
<td>Created At</td>
<td>Action</td>
</tr>
</thead>
<tbody>
{news.map((news) => (
<tr key={news.id}>
<td>
<div className={styles.new}>
<Image
src={NewsList.img || "/nonew.jpg"}
alt=""
width={40}
height={40}
className={styles.newImage}
/>
{news.title}
</div>
</td>
<td>{news.desc}</td>
<td>{news.createdAt?.toString().slice(4, 16)}</td>
<td>
<div className={styles.buttons}>
<Link href={`/dashboard/news/${news.id}`}>
<button className={`${styles.button} ${styles.view}`}>
View
</button>
</Link>
<form action={deleteNews}>
<input type="hidden" name="id" value={news.id} />
<button className={`${styles.button} ${styles.delete}`}>
Delete
</button>
</form>
</div>
</td>
</tr>
))}
</tbody>
</table>
<Pagination count={count} />
</div>
);
};

export default newsPage;
19 changes: 19 additions & 0 deletions src/app/[locale]/dashboard/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { cards } from "../../lib/data";

import styles from "../../../components/dashboard/dashboard.module.css";

const Dashboard = () => {
return (
<div className={styles.wrapper}>
<div className={styles.main}>
<h1 className={styles.title}>Ласкаво просимо!</h1>
<p className={styles.description}>
Ви знаходитесь в адміністративній панелі, де ви можете виконувати різні дії, такі
як налаштування, керування контентом, здійснення операцій і багато іншого.
</p>
</div>
</div>
);
};

export default Dashboard;
49 changes: 49 additions & 0 deletions src/app/[locale]/dashboard/users/[id]/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { updateUser } from "@/app/lib/actions";
import { fetchUser } from "@/app/lib/data";
import styles from "@/components/dashboard/users/singleUser/singleUser.module.css";
import Image from "next/image";

const SingleUserPage = async ({ params }) => {

const { id } = params;
const user = await fetchUser(id);

return (
<div className={styles.container}>
<div className={styles.infoContainer}>
<div className={styles.imgContainer}>
<Image src={user.img || "/noavatar.png"} alt="" fill />
</div>
{user.username}
</div>
<div className={styles.formContainer}>
<form action={updateUser} className={styles.form}>
<input type="hidden" name="id" value={user.id}/>
<label>Username</label>
<input type="text" name="username" placeholder={user.username} />
<label>Email</label>
<input type="email" name="email" placeholder={user.email} />
<label>Password</label>
<input type="password" name="password" />
<label>Phone</label>
<input type="text" name="phone" placeholder={user.phone} />
<label>Address</label>
<textarea type="text" name="address" placeholder={user.address} />
<label>Is Admin?</label>
<select name="isAdmin" id="isAdmin">
<option value={true} selected={user.isAdmin}>Yes</option>
<option value={false} selected={!user.isAdmin}>No</option>
</select>
<label>Is Active?</label>
<select name="isActive" id="isActive">
<option value={true} selected={user.isActive}>Yes</option>
<option value={false} selected={!user.isActive}>No</option>
</select>
<button>Update</button>
</form>
</div>
</div>
);
};

export default SingleUserPage;
43 changes: 43 additions & 0 deletions src/app/[locale]/dashboard/users/add/page.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { addUser } from "@/app/lib/actions";
import styles from "@/components/dashboard/users/addUser/addUser.module.css";

const AddUserPage = () => {
return (
<div className={styles.container}>
<form action={addUser} className={styles.form}>
<input type="text" placeholder="username" name="username" required />
<input type="email" placeholder="email" name="email" required />
<input
type="password"
placeholder="password"
name="password"
required
/>
<input type="phone" placeholder="phone" name="phone" />
<select name="isAdmin" id="isAdmin">
<option value={false}>
Is Admin?
</option>
<option value={true}>Yes</option>
<option value={false}>No</option>
</select>
<select name="isActive" id="isActive">
<option value={true}>
Is Active?
</option>
<option value={true}>Yes</option>
<option value={false}>No</option>
</select>
<textarea
name="address"
id="address"
rows="16"
placeholder="Address"
></textarea>
<button type="submit">Submit</button>
</form>
</div>
);
};

export default AddUserPage;
Loading

0 comments on commit 3ccdc36

Please sign in to comment.