Skip to content

Commit 61c8c1c

Browse files
author
N-Kiran123
committed
Fixed 4 blocking issuses, pages now load flawlessly
0 parents  commit 61c8c1c

289 files changed

Lines changed: 29397 additions & 0 deletions

File tree

Some content is hidden

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

.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+
}

.github/workflows/blank1.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# This is a basic workflow to help you get started with Actions
2+
3+
name: CI
4+
5+
# Controls when the workflow will run
6+
on:
7+
# Triggers the workflow on push or pull request events but only for the "main" branch
8+
push:
9+
branches: [ "main" ]
10+
pull_request:
11+
branches: [ "main" ]
12+
13+
# Allows you to run this workflow manually from the Actions tab
14+
workflow_dispatch:
15+
16+
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
17+
jobs:
18+
# This workflow contains a single job called "build"
19+
build:
20+
# The type of runner that the job will run on
21+
runs-on: ubuntu-latest
22+
23+
# Steps represent a sequence of tasks that will be executed as part of the job
24+
steps:
25+
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
26+
- uses: actions/checkout@v4
27+
28+
# Runs a single command using the runners shell
29+
- name: Run a one-line script
30+
run: echo Hello, world!
31+
32+
# Runs a set of commands using the runners shell
33+
- name: Run a multi-line script
34+
run: |
35+
echo Add other actions to build,
36+
echo test, and deploy your project.

.gitignore

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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+
.yarn/install-state.gz
8+
9+
# testing
10+
/coverage
11+
12+
# next.js
13+
/.next/
14+
/out/
15+
16+
# production
17+
/build
18+
19+
# misc
20+
.DS_Store
21+
*.pem
22+
23+
# debug
24+
npm-debug.log*
25+
yarn-debug.log*
26+
yarn-error.log*
27+
28+
# local env files
29+
.env*.local
30+
.env
31+
32+
# vercel
33+
.vercel
34+
35+
# typescript
36+
*.tsbuildinfo
37+
next-env.d.ts
38+
39+
# Database backups
40+
/backups/
41+
*.sql
42+
*.dump
43+
*.backup
44+
45+
# Logs
46+
*.log
47+
logs/
48+
49+
# IDE
50+
.vscode/
51+
.idea/
52+
*.swp
53+
*.swo
54+
55+
# OS
56+
Thumbs.db
57+
.DS_Store

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Aleksandar Kuzmanović
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Providers.tsx

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"use client";
2+
import { Toaster } from "react-hot-toast";
3+
4+
import React from "react";
5+
6+
const Providers = ({ children }: { children: React.ReactNode }) => {
7+
return (
8+
<>
9+
<Toaster
10+
toastOptions={{
11+
className: "",
12+
style: {
13+
fontSize: "17px",
14+
},
15+
}}
16+
/>
17+
{children}
18+
</>
19+
);
20+
};
21+
22+
export default Providers;

README.md

Lines changed: 236 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
"use client";
2+
import { DashboardSidebar } from "@/components";
3+
import { useRouter } from "next/navigation";
4+
import React, { useEffect, useState, use } from "react";
5+
import toast from "react-hot-toast";
6+
import { formatCategoryName } from "../../../../../utils/categoryFormating";
7+
import { convertCategoryNameToURLFriendly } from "../../../../../utils/categoryFormating";
8+
import apiClient from "@/lib/api";
9+
10+
interface DashboardSingleCategoryProps {
11+
params: Promise<{ id: string }>;
12+
}
13+
14+
const DashboardSingleCategory = ({
15+
params,
16+
}: DashboardSingleCategoryProps) => {
17+
const resolvedParams = use(params);
18+
const id = resolvedParams.id;
19+
20+
const [categoryInput, setCategoryInput] = useState<{ name: string }>({
21+
name: "",
22+
});
23+
const router = useRouter();
24+
25+
const deleteCategory = async () => {
26+
const requestOptions = {
27+
method: "DELETE",
28+
};
29+
// sending API request for deleting a category
30+
apiClient.delete(`/api/categories/${id}`, requestOptions)
31+
.then((response) => {
32+
if (response.status === 204) {
33+
toast.success("Category deleted successfully");
34+
router.push("/admin/categories");
35+
} else {
36+
throw Error("There was an error deleting a category");
37+
}
38+
})
39+
.catch((error) => {
40+
toast.error("There was an error deleting category");
41+
});
42+
};
43+
44+
const updateCategory = async () => {
45+
if (categoryInput.name.length > 0) {
46+
const requestOptions = {
47+
method: "PUT",
48+
headers: { "Content-Type": "application/json" },
49+
body: JSON.stringify({
50+
name: convertCategoryNameToURLFriendly(categoryInput.name),
51+
}),
52+
};
53+
// sending API request for updating a category
54+
apiClient.put(`/api/categories/${id}`, requestOptions)
55+
.then((response) => {
56+
if (response.status === 200) {
57+
return response.json();
58+
} else {
59+
throw Error("Error updating a category");
60+
}
61+
})
62+
.then((data) => toast.success("Category successfully updated"))
63+
.catch((error) => {
64+
toast.error("There was an error while updating a category");
65+
});
66+
} else {
67+
toast.error("For updating a category you must enter all values");
68+
return;
69+
}
70+
};
71+
72+
useEffect(() => {
73+
// sending API request for getting single categroy
74+
apiClient.get(`/api/categories/${id}`)
75+
.then((res) => {
76+
return res.json();
77+
})
78+
.then((data) => {
79+
setCategoryInput({
80+
name: data?.name,
81+
});
82+
});
83+
}, [id]);
84+
85+
return (
86+
<div className="bg-white flex justify-start max-w-screen-2xl mx-auto xl:h-full max-xl:flex-col max-xl:gap-y-5">
87+
<DashboardSidebar />
88+
<div className="flex flex-col gap-y-7 xl:pl-5 max-xl:px-5 w-full">
89+
<h1 className="text-3xl font-semibold">Category details</h1>
90+
<div>
91+
<label className="form-control w-full max-w-xs">
92+
<div className="label">
93+
<span className="label-text">Category name:</span>
94+
</div>
95+
<input
96+
type="text"
97+
className="input input-bordered w-full max-w-xs"
98+
value={formatCategoryName(categoryInput.name)}
99+
onChange={(e) =>
100+
setCategoryInput({ ...categoryInput, name: e.target.value })
101+
}
102+
/>
103+
</label>
104+
</div>
105+
106+
<div className="flex gap-x-2 max-sm:flex-col">
107+
<button
108+
type="button"
109+
className="uppercase bg-blue-500 px-10 py-5 text-lg border border-black border-gray-300 font-bold text-white shadow-sm hover:bg-blue-600 hover:text-white focus:outline-none focus:ring-2"
110+
onClick={updateCategory}
111+
>
112+
Update category
113+
</button>
114+
<button
115+
type="button"
116+
className="uppercase bg-red-600 px-10 py-5 text-lg border border-black border-gray-300 font-bold text-white shadow-sm hover:bg-red-700 hover:text-white focus:outline-none focus:ring-2"
117+
onClick={deleteCategory}
118+
>
119+
Delete category
120+
</button>
121+
</div>
122+
<p className="text-xl text-error max-sm:text-lg">
123+
Note: if you delete this category, you will delete all products
124+
associated with the category.
125+
</p>
126+
</div>
127+
</div>
128+
);
129+
};
130+
131+
export default DashboardSingleCategory;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
"use client";
2+
import { DashboardSidebar } from "@/components";
3+
import React, { useState } from "react";
4+
import toast from "react-hot-toast";
5+
import { convertCategoryNameToURLFriendly } from "../../../../../utils/categoryFormating";
6+
import apiClient from "@/lib/api";
7+
8+
const DashboardNewCategoryPage = () => {
9+
const [categoryInput, setCategoryInput] = useState({
10+
name: "",
11+
});
12+
13+
const addNewCategory = () => {
14+
if (categoryInput.name.length > 0) {
15+
const requestOptions = {
16+
method: "post",
17+
headers: { "Content-Type": "application/json" },
18+
body: JSON.stringify({
19+
name: convertCategoryNameToURLFriendly(categoryInput.name),
20+
}),
21+
};
22+
// sending API request for creating new cateogry
23+
apiClient.post(`/api/categories`, requestOptions)
24+
.then((response) => {
25+
if (response.status === 201) {
26+
return response.json();
27+
} else {
28+
throw Error("There was an error while creating category");
29+
}
30+
})
31+
.then((data) => {
32+
toast.success("Category added successfully");
33+
setCategoryInput({
34+
name: "",
35+
});
36+
})
37+
.catch((error) => {
38+
toast.error("There was an error while creating category");
39+
});
40+
} else {
41+
toast.error("You need to enter values to add a category");
42+
}
43+
};
44+
return (
45+
<div className="bg-white flex justify-start max-w-screen-2xl mx-auto xl:h-full max-xl:flex-col max-xl:gap-y-5">
46+
<DashboardSidebar />
47+
<div className="flex flex-col gap-y-7 xl:pl-5 max-xl:px-5 w-full">
48+
<h1 className="text-3xl font-semibold">Add new category</h1>
49+
<div>
50+
<label className="form-control w-full max-w-xs">
51+
<div className="label">
52+
<span className="label-text">Category name:</span>
53+
</div>
54+
<input
55+
type="text"
56+
className="input input-bordered w-full max-w-xs"
57+
value={categoryInput.name}
58+
onChange={(e) =>
59+
setCategoryInput({ ...categoryInput, name: e.target.value })
60+
}
61+
/>
62+
</label>
63+
</div>
64+
65+
<div className="flex gap-x-2">
66+
<button
67+
type="button"
68+
className="uppercase bg-blue-500 px-10 py-5 text-lg border border-black border-gray-300 font-bold text-white shadow-sm hover:bg-blue-600 hover:text-white focus:outline-none focus:ring-2"
69+
onClick={addNewCategory}
70+
>
71+
Create category
72+
</button>
73+
</div>
74+
</div>
75+
</div>
76+
);
77+
};
78+
79+
export default DashboardNewCategoryPage;

0 commit comments

Comments
 (0)