Gitlab@Informatics
Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
project-melon
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
65160388
project-melon
Compare revisions
fedee5f8518127e808d21afbddbc73798bc34ed6 to 1675b91762bc046f7bce9bc24cee9e62eaa9a3da
Compare revisions
Changes are shown as if the
source
revision was being merged into the
target
revision.
Learn more about comparing revisions.
Source
65160388/project-melon
Select target project
No results found
1675b91762bc046f7bce9bc24cee9e62eaa9a3da
Select Git revision
Branches
main
1 result
Swap
Target
65160388/project-melon
Select target project
65160388/project-melon
1 result
fedee5f8518127e808d21afbddbc73798bc34ed6
Select Git revision
Branches
main
1 result
Show changes
Only incoming changes from source
Include changes to target since source was created
Compare
Commits on Source
3
.2
· 37c6046c
65160388
authored
4 months ago
37c6046c
v.2.1
· 3bda7b66
65160388
authored
4 months ago
3bda7b66
Merge branch 'master' into 'main'
· 1675b917
65160388
authored
4 months ago
Master See merge request
!5
1675b917
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
.env
+1
-15
1 addition, 15 deletions
.env
server.js
+30
-35
30 additions, 35 deletions
server.js
views/dashboard.ejs
+12
-3
12 additions, 3 deletions
views/dashboard.ejs
views/partials/header.ejs
+20
-28
20 additions, 28 deletions
views/partials/header.ejs
with
63 additions
and
81 deletions
.env
View file @
1675b917
# PORT=3000
# DB_HOST=localhost
# DB_USER=root
# DB_PASS=
# DB_NAME=cloud_project_db
# SESSION_SECRET=default_secret_key
# DB_HOST=10.104.6.131
# DB_PORT=11734
# DB_USER=root
# DB_PASS=LCXndt18044
# DB_NAME=cloud_project_db
# SESSION_SECRET=default_secret_key
# PORT=3000
# DB_HOST=10.104.6.131
# DB_USER=root
# DB_PASS=DRQqan69450
# DB_NAME=cloud_project_db
# DB_PORT=3306
# SESSION_SECRET=default_secret_key
PORT=3000
# Database connection settings
DB_HOST=10.104.6.131 # IP ที่ถูกต้องของฐานข้อมูล MySQL
DB_PORT=11734 # Public port สำหรับเชื่อมต่อ MySQL
DB_USER=root # ชื่อผู้ใช้สำหรับ MySQL
...
...
This diff is collapsed.
Click to expand it.
server.js
View file @
1675b917
// server.js
require
(
'
dotenv
'
).
config
();
// โหลดค่าตัวแปรจาก .env
require
(
'
dotenv
'
).
config
();
const
express
=
require
(
'
express
'
);
const
session
=
require
(
'
express-session
'
);
const
bodyParser
=
require
(
'
body-parser
'
);
...
...
@@ -9,7 +8,6 @@ const mysql = require('mysql2');
const
app
=
express
();
// อ่านค่า PORT จาก .env ถ้าไม่มีให้ใช้ 3000
// const port = process.env.PORT || 3000;
const
port
=
process
.
env
.
PORT
;
// ตั้งค่า view engine เป็น EJS
...
...
@@ -30,7 +28,7 @@ app.use(session({
// สร้างการเชื่อมต่อกับฐานข้อมูล MySQL โดยอ่านค่าจาก .env
const
connection
=
mysql
.
createConnection
({
host
:
process
.
env
.
DB_HOST
||
'
localhost
'
,
// ถ้าไม่มีค่าใน DB_HOST จะใช้ 'localhost'
host
:
process
.
env
.
DB_HOST
||
'
localhost
'
,
user
:
process
.
env
.
DB_USER
||
'
root
'
,
password
:
process
.
env
.
DB_PASS
||
''
,
database
:
process
.
env
.
DB_NAME
||
'
cloud_project_db
'
,
...
...
@@ -45,7 +43,7 @@ connection.connect(err => {
console
.
log
(
'
Connected to MySQL
'
);
});
// Middleware ตรวจสอบการเข้าสู่ระบบ
// Middleware ตรวจสอบการเข้าสู่ระบบ
(ใช้สำหรับหน้าที่ต้องการให้ login)
function
isAuthenticated
(
req
,
res
,
next
)
{
if
(
req
.
session
.
userId
)
{
return
next
();
...
...
@@ -57,11 +55,8 @@ function isAuthenticated(req, res, next) {
// หน้าแรก
// --------------------
app
.
get
(
'
/
'
,
(
req
,
res
)
=>
{
if
(
req
.
session
.
userId
)
{
// ไม่ว่าจะล็อกอินหรือไม่ ให้ redirect ไปที่ '/dashboard' เสมอ
res
.
redirect
(
'
/dashboard
'
);
}
else
{
res
.
redirect
(
'
/login
'
);
}
});
// --------------------
...
...
@@ -132,46 +127,53 @@ app.post('/login', (req, res) => {
});
// --------------------
// Dashboard (
แสดง Project พร้อม Search
)
// Dashboard (
อนุญาตให้ Guest เข้าดูได้
)
// --------------------
app
.
get
(
'
/dashboard
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
app
.
get
(
'
/dashboard
'
,
(
req
,
res
)
=>
{
// รับค่าค้นหาจาก query string ?q=
const
searchQuery
=
req
.
query
.
q
;
let
sql
=
`
SELECT projects.*, users.username AS ownerName
FROM projects
JOIN users ON projects.user_id = users.id
ORDER BY projects.id DESC
`
;
const
params
=
[];
// ถ้ามีค่า searchQuery ให้เพิ่มเงื่อนไข WHERE เพื่อค้นหาตาม project_name หรือ description
const
params
=
[];
if
(
searchQuery
)
{
sql
+=
`
sql
=
`
SELECT projects.*, users.username AS ownerName
FROM projects
JOIN users ON projects.user_id = users.id
WHERE projects.project_name LIKE ?
OR projects.description LIKE ?
ORDER BY projects.id DESC
`
;
params
.
push
(
`%
${
searchQuery
}
%`
,
`%
${
searchQuery
}
%`
);
}
sql
+=
'
ORDER BY projects.id DESC
'
;
connection
.
query
(
sql
,
params
,
(
err
,
projects
)
=>
{
if
(
err
)
{
console
.
error
(
err
);
return
res
.
send
(
'
Error fetching projects
'
);
}
// ถ้ายังไม่ได้ login ให้แสดงชื่อ Guest
const
username
=
req
.
session
.
username
||
'
Guest
'
;
const
userId
=
req
.
session
.
userId
||
null
;
res
.
render
(
'
dashboard
'
,
{
username
:
req
.
session
.
username
,
userId
:
req
.
session
.
userId
,
username
,
userId
,
projects
,
query
:
searchQuery
||
''
query
:
searchQuery
||
''
,
currentPage
:
'
dashboard
'
});
});
});
// -----------------------------------------------------
// 1) CREATE Project
// -----------------------------------------------------
// 1) CREATE Project (ต้อง login)
app
.
get
(
'
/project/create
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
res
.
render
(
'
project-create
'
,
{
username
:
req
.
session
.
username
});
});
...
...
@@ -192,8 +194,7 @@ app.post('/project/create', isAuthenticated, (req, res) => {
});
// -----------------------------------------------------
// 2) EDIT Project
// -----------------------------------------------------
// 2) EDIT Project (ต้อง login)
app
.
get
(
'
/project/edit/:id
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
const
projectId
=
req
.
params
.
id
;
connection
.
query
(
...
...
@@ -232,8 +233,7 @@ app.post('/project/edit/:id', isAuthenticated, (req, res) => {
});
// -----------------------------------------------------
// 3) DELETE Project
// -----------------------------------------------------
// 3) DELETE Project (ต้อง login)
app
.
get
(
'
/project/delete/:id
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
const
projectId
=
req
.
params
.
id
;
connection
.
query
(
...
...
@@ -250,11 +250,9 @@ app.get('/project/delete/:id', isAuthenticated, (req, res) => {
});
// -----------------------------------------------------
// 4) VIEW Project + Comments
// -----------------------------------------------------
// 4) VIEW Project + Comments (ต้อง login)
app
.
get
(
'
/project/:id
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
const
projectId
=
req
.
params
.
id
;
// ดึงข้อมูล Project
connection
.
query
(
`SELECT projects.*, users.username AS ownerName
FROM projects
...
...
@@ -271,7 +269,6 @@ app.get('/project/:id', isAuthenticated, (req, res) => {
}
const
project
=
results
[
0
];
// ดึง Comments ของ Project นี้
connection
.
query
(
`SELECT comments.*, users.username AS commentUser
FROM comments
...
...
@@ -297,8 +294,7 @@ app.get('/project/:id', isAuthenticated, (req, res) => {
});
// -----------------------------------------------------
// 5) CREATE Comment
// -----------------------------------------------------
// 5) CREATE Comment (ต้อง login)
app
.
post
(
'
/project/:id/comment
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
const
projectId
=
req
.
params
.
id
;
const
{
comment
}
=
req
.
body
;
...
...
@@ -316,8 +312,7 @@ app.post('/project/:id/comment', isAuthenticated, (req, res) => {
});
// -----------------------------------------------------
// 6) DELETE Comment (เฉพาะเจ้าของ comment)
// -----------------------------------------------------
// 6) DELETE Comment (เฉพาะเจ้าของ comment, ต้อง login)
app
.
get
(
'
/comment/delete/:id
'
,
isAuthenticated
,
(
req
,
res
)
=>
{
const
commentId
=
req
.
params
.
id
;
const
sql
=
`
...
...
@@ -349,7 +344,7 @@ app.get('/comment/delete/:id', isAuthenticated, (req, res) => {
// --------------------
app
.
get
(
'
/logout
'
,
(
req
,
res
)
=>
{
req
.
session
.
destroy
();
res
.
redirect
(
'
/
login
'
);
res
.
redirect
(
'
/
dashboard
'
);
});
// เริ่มเซิร์ฟเวอร์
...
...
This diff is collapsed.
Click to expand it.
views/dashboard.ejs
View file @
1675b917
...
...
@@ -5,9 +5,14 @@
<!-- Header with Title -->
<div class="d-flex justify-content-between align-items-center mb-4">
<h2 class="mb-0" style="color: #EE4D2D; font-size: 30px; font-weight: 600;">TOPIC</h2>
<a href="/project/create" class="btn" style="background-color: #EE4D2D; color: #fff; font-weight: 600; border-radius: 20px; padding: 10px 20px;">
<!-- ซ่อนปุ่ม Create New Topic ถ้า userId ไม่มีค่า (ยังไม่ล็อกอิน) -->
<% if (userId) { %>
<a href="/project/create" class="btn"
style="background-color: #EE4D2D; color: #fff; font-weight: 600; border-radius: 20px; padding: 10px 20px;">
Create New Topic
</a>
<% } %>
</div>
<!-- List Group of Topics -->
...
...
@@ -36,7 +41,11 @@
<!-- Action Buttons (View/Edit/Delete) -->
<div class="mt-3">
<!-- ปุ่ม View ให้แสดงได้ทุกคน
(แต่หาก route /project/:id ใช้ isAuthenticated, Guest จะถูก redirect ไป login เอง) -->
<a href="/project/<%= project.id %>" class="btn btn-sm btn-outline-info" style="border-radius: 20px;">View</a>
<!-- แสดงปุ่ม Edit/Delete เฉพาะเจ้าของโปรเจกต์ (userId ตรงกับ project.user_id) -->
<% if (project.user_id === userId) { %>
<a href="/project/edit/<%= project.id %>" class="btn btn-sm btn-outline-warning" style="border-radius: 20px;">Edit</a>
<a href="/project/delete/<%= project.id %>"
...
...
This diff is collapsed.
Click to expand it.
views/partials/header.ejs
View file @
1675b917
...
...
@@ -4,23 +4,12 @@
<meta
charset=
"UTF-8"
>
<title>
PURIPAT
</title>
<link
rel=
"stylesheet"
href=
"https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css"
>
<!-- เพิ่ม Favicon -->
<link
rel=
"icon"
href=
"path/to/your/favicon.ico"
type=
"image/x-icon"
>
<link
rel=
"icon"
href=
"/favicon.ico"
type=
"image/x-icon"
>
<style>
/* ปรับ Navbar ให้เป็นสีส้ม Shopee */
.navbar
{
background-color
:
#EE4D2D
!important
;
/* สีส้ม Shopee */
}
/* ตัวหนังสือบน Navbar ให้เป็นสีขาว */
.navbar-brand
,
.nav-link
{
color
:
#fff
!important
;
}
.navbar-brand
:hover
,
.nav-link
:hover
{
color
:
#FFD2C3
!important
;
/* สีส้มอ่อนลงเมื่อ hover */
}
/* ปรับฟอร์มค้นหาให้สวยงาม */
.navbar
{
background-color
:
#EE4D2D
!important
;
}
.navbar-brand
,
.nav-link
{
color
:
#fff
!important
;
}
.navbar-brand
:hover
,
.nav-link
:hover
{
color
:
#FFD2C3
!important
;
}
.search-form
{
width
:
500px
;
margin-left
:
auto
;
...
...
@@ -34,7 +23,6 @@
.search-form
.input-group-append
.btn
{
background-color
:
#FF7043
;
color
:
white
;
/* border-radius: 50px; */
border
:
none
;
padding-left
:
20px
;
padding-right
:
20px
;
...
...
@@ -45,23 +33,28 @@
</style>
</head>
<body>
<
%
//
ถ้าไม่มีการส่ง
username
เข้ามา
ให้เป็น
'
Guest
'
var
localUsername =
(typeof
username
!==
'
undefined
'
&&
username
)
?
username
:
'
Guest
';
//
ถ้าไม่มี
query
ส่งเข้ามา
ให้เป็นค่าว่าง
var
localQuery =
(typeof
query
!==
'
undefined
')
?
query
:
'';
//
ถ้าไม่มี
currentPage
ส่งเข้ามา
ให้กำหนดเป็น
''
var
currentPageVal =
(typeof
currentPage
!==
'
undefined
')
?
currentPage
:
'';
%
>
<nav
class=
"navbar navbar-expand-lg navbar-dark"
>
<!-- ชื่อโปรเจกต์ -->
<a
class=
"navbar-brand"
href=
"/dashboard"
>
TONGBARN
</a>
<!-- ปุ่ม toggle สำหรับ mobile -->
<button
class=
"navbar-toggler"
type=
"button"
data-toggle=
"collapse"
data-target=
"#navbarContent"
aria-controls=
"navbarContent"
aria-expanded=
"false"
aria-label=
"Toggle navigation"
>
<span
class=
"navbar-toggler-icon"
></span>
</button>
<!-- ฟอร์ม Search จะปรากฏเฉพาะเมื่อผู้ใช้เข้าสู่ระบบ -->
<div
class=
"collapse navbar-collapse"
id=
"navbarContent"
>
<
%
if
(
typeof
usernam
e
!
==
'
undefined
')
{
%
>
<!-- แสดงฟอร์มค้นหาสำหรับผู้ใช้ที่ล็อกอินแล้ว --
>
<
!-- แสดงฟอร์มค้นหาเฉพาะเมื่อ currentPag
e ==
=
'
dashboard' --
>
<
%
if
(currentPageVal =
==
'
dashboard
')
{
%
>
<form
action=
"/dashboard"
method=
"GET"
class=
"search-form d-flex"
>
<div
class=
"input-group"
>
<input
type=
"text"
name=
"q"
class=
"form-control"
placeholder=
"Search for threads now..."
value=
"<%=
typeof query !== 'undefined' ? query : ''
%>"
>
value=
"<%=
localQuery
%>"
>
<div
class=
"input-group-append"
>
<button
class=
"btn btn-outline-secondary"
type=
"submit"
>
Search
</button>
</div>
...
...
@@ -69,12 +62,11 @@
</form>
<
%
}
%
>
<!-- เมนู Navbar -->
<ul
class=
"navbar-nav ml-auto"
>
<
%
if
(
typeof
username
!==
'
undefined
')
{
%
>
<li
class=
"nav-item"
>
<a
class=
"nav-link"
href=
"#"
>
Welcome,
<
%=
u
sername
%
></a>
<a
class=
"nav-link"
href=
"#"
>
Welcome,
<
%=
localU
sername
%
></a>
</li>
<
%
if
(
localUsername
!==
'
Guest
')
{
%
>
<li
class=
"nav-item"
>
<a
class=
"nav-link"
href=
"/logout"
>
Logout
</a>
</li>
...
...
This diff is collapsed.
Click to expand it.