Skip to content

Commit af62577

Browse files
authored
Merge pull request #13 from ikapiar/Avei20/LoginPage
feat: LoginPage and Dockerfile for production. dynamic docker-compose for dev and prod
2 parents 28ec5b4 + 3ef3208 commit af62577

28 files changed

+1331
-166
lines changed

docker-compose.yml

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,52 @@
11
services:
2-
frontend:
3-
build:
4-
context: ./frontend
5-
dockerfile: Dockerfile
6-
container_name: ikapiar-frontend
7-
ports:
8-
- "3000:80" # Map local port 3000 to NGINX's port 80
9-
networks:
10-
- ikapiar-network
2+
frontend:
3+
profiles: ["frontend"]
4+
build:
5+
context: ./frontend
6+
dockerfile: ${DOCKERFILE:-Dockerfile}
7+
environment:
8+
- NEXT_PUBLIC_API_BASE_URL=https://ikapiar.my.id # Adjust this URL according to your API service
9+
container_name: ikapiar-frontend
10+
ports:
11+
- "3000:3000" # Map local port 3000 to NGINX's port 80
12+
networks:
13+
- ikapiar-network
14+
develop:
15+
watch:
16+
- path: ./frontend
17+
target: /app
18+
action: sync+restart
1119

12-
backend:
13-
build:
14-
context: ./backend
15-
dockerfile: Dockerfile
16-
container_name: ikapiar-backend
17-
ports:
18-
- "4000:4000"
19-
networks:
20-
- ikapiar-network
20+
backend:
21+
profiles: ["backend"]
22+
build:
23+
context: ./backend
24+
dockerfile: Dockerfile
25+
container_name: ikapiar-backend
26+
ports:
27+
- "4000:4000"
28+
networks:
29+
- ikapiar-network
2130

22-
database:
23-
image: postgres:15-alpine
24-
container_name: postgres-container
25-
hostname: postgres
26-
restart: always
27-
environment:
28-
POSTGRES_USER: postgres
29-
POSTGRES_PASSWORD: postgres
30-
POSTGRES_DB: postgres
31-
ports:
32-
- "5432:5432"
33-
volumes:
34-
- ikapiar-db:/var/lib/postgresql/data
35-
networks:
36-
- ikapiar-network
31+
database:
32+
profiles:
33+
- database
34+
- backend
35+
image: postgres:15-alpine
36+
container_name: postgres-container
37+
hostname: postgres
38+
restart: always
39+
environment:
40+
POSTGRES_USER: postgres
41+
POSTGRES_PASSWORD: postgres
42+
POSTGRES_DB: postgres
43+
ports:
44+
- "5432:5432"
45+
volumes:
46+
- ikapiar-db:/var/lib/postgresql/data
47+
networks:
48+
- ikapiar-network
3749
volumes:
38-
ikapiar-db:
50+
ikapiar-db:
3951
networks:
40-
ikapiar-network:
52+
ikapiar-network:

frontend/Dockerfile

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
# build environment
2-
FROM node:alpine AS build
1+
FROM oven/bun:latest
2+
3+
# create & set working directory
34
WORKDIR /app
5+
6+
# copy source files
47
COPY . .
5-
RUN yarn
6-
RUN yarn build
7-
8-
# production environment
9-
FROM nginx:stable-alpine
10-
COPY --from=build /app/out /usr/share/nginx/html
11-
COPY --from=build /app/nginx/nginx.conf /etc/nginx/conf.d/default.conf
12-
EXPOSE 80
13-
CMD ["nginx", "-g", "daemon off;"]
8+
9+
# install dependencies
10+
RUN bun install
11+
12+
# start app
13+
RUN bun run build
14+
EXPOSE 3000
15+
CMD bun run start

frontend/Dockerfile.local

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM oven/bun:latest
2+
WORKDIR /app
3+
4+
COPY . .
5+
RUN bun install
6+
CMD ["bun", "run", "dev"]

frontend/bun.lockb

10.1 KB
Binary file not shown.

frontend/next.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import type { NextConfig } from "next";
22

33
const nextConfig: NextConfig = {
4-
/* config options here */
5-
output: 'export'
4+
/* config options here */
5+
// output: "export",
6+
// experimental: {
7+
// serverActions: true,
8+
// },
69
};
710

811
export default nextConfig;

frontend/package.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,22 @@
99
"lint": "next lint"
1010
},
1111
"dependencies": {
12+
"@hookform/resolvers": "^3.10.0",
13+
"@radix-ui/react-avatar": "^1.1.2",
14+
"@radix-ui/react-label": "^2.1.1",
15+
"@radix-ui/react-separator": "^1.1.1",
16+
"@radix-ui/react-slot": "^1.1.1",
1217
"class-variance-authority": "^0.7.1",
1318
"clsx": "^2.1.1",
1419
"lucide-react": "^0.469.0",
1520
"next": "15.1.2",
1621
"react": "^19.0.0",
1722
"react-dom": "^19.0.0",
23+
"react-hook-form": "^7.54.2",
1824
"tailwind-merge": "^2.5.5",
19-
"tailwindcss-animate": "^1.0.7"
25+
"tailwindcss-animate": "^1.0.7",
26+
"zod": "^3.24.1",
27+
"zustand": "^5.0.3"
2028
},
2129
"devDependencies": {
2230
"typescript": "^5",

frontend/public/logo.jpeg

23.8 KB
Loading

frontend/src/app/layout.tsx

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,56 @@
11
import type { Metadata } from "next";
2-
import { Geist, Geist_Mono } from "next/font/google";
2+
import { Geist, Azeret_Mono as Geist_Mono } from "next/font/google";
33
import "./globals.css";
44

55
const geistSans = Geist({
6-
variable: "--font-geist-sans",
7-
subsets: ["latin"],
6+
variable: "--font-geist-sans",
7+
subsets: ["latin"],
88
});
99

1010
const geistMono = Geist_Mono({
11-
variable: "--font-geist-mono",
12-
subsets: ["latin"],
11+
variable: "--font-geist-mono",
12+
subsets: ["latin"],
1313
});
1414

1515
export const metadata: Metadata = {
16-
title: "Create Next App",
17-
description: "Generated by create next app",
16+
title: "IKAPIAR Platform",
17+
description: "Your gateway to innovative solutions",
1818
};
1919

2020
export default function RootLayout({
21-
children,
21+
children,
2222
}: Readonly<{
23-
children: React.ReactNode;
23+
children: React.ReactNode;
2424
}>) {
25-
return (
26-
<html lang="en">
27-
<body
28-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29-
>
30-
{children}
31-
</body>
32-
</html>
33-
);
25+
return (
26+
<html lang="en">
27+
<body
28+
className={`${geistSans.variable} ${geistMono.variable} antialiased min-h-screen flex flex-col`}
29+
>
30+
<main className="flex-1">{children}</main>
31+
<footer className="py-6 px-4 bg-gray-100 border-t border-gray-200">
32+
<div className="container mx-auto flex flex-col sm:flex-row justify-between items-center">
33+
<div className="text-sm text-gray-600 mb-4 sm:mb-0">
34+
© {new Date().getFullYear()} IKAPIAR Platform. All
35+
rights reserved.
36+
</div>
37+
<nav className="flex space-x-4">
38+
<a
39+
href="/legal/privacy-policy"
40+
className="text-sm text-gray-600 hover:text-gray-900 hover:underline"
41+
>
42+
Privacy Policy
43+
</a>
44+
<a
45+
href="/legal/terms-of-service"
46+
className="text-sm text-gray-600 hover:text-gray-900 hover:underline"
47+
>
48+
Terms of Service
49+
</a>
50+
</nav>
51+
</div>
52+
</footer>
53+
</body>
54+
</html>
55+
);
3456
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
export default function PrivacyPolicy() {
2+
return (
3+
<div className="max-w-4xl mx-auto px-6 py-8">
4+
<h1 className="text-3xl font-bold mb-6" id="privacy-policy">
5+
Privacy Policy
6+
</h1>
7+
8+
<section className="mb-8">
9+
<h2 className="text-2xl font-semibold mb-4" id="introduction">
10+
Introduction
11+
</h2>
12+
<p className="mb-4">
13+
Welcome to IKAPIAR, the school alumni data dashboard. We are
14+
committed to safeguarding the privacy of our users, who are
15+
all alumni of the institution. This Privacy Policy outlines
16+
how we collect, use, and protect your information.
17+
</p>
18+
</section>
19+
20+
<section className="mb-8">
21+
<h2
22+
className="text-2xl font-semibold mb-4"
23+
id="data-collection"
24+
>
25+
Data Collection
26+
</h2>
27+
<p className="mb-4">
28+
We collect the following types of information:
29+
</p>
30+
<ol className="list-decimal pl-6 space-y-2">
31+
<li>
32+
<strong>Personal Information</strong>: Including but not
33+
limited to your name, email address, and graduation
34+
details.
35+
</li>
36+
<li>
37+
<strong>Google/LinkedIn Sync</strong>: With your
38+
consent, we may sync information from your Google or
39+
LinkedIn accounts, such as profile details, work
40+
history, and contact information.
41+
</li>
42+
<li>
43+
<strong>Forms and Surveys</strong>: Any Google Forms or
44+
other surveys filled out for the alumni organization may
45+
be integrated into the platform.
46+
</li>
47+
<li>
48+
<strong>Usage Data</strong>: Statistics and analytics
49+
related to your interaction with the platform.
50+
</li>
51+
</ol>
52+
</section>
53+
54+
{/* Additional sections following the same pattern */}
55+
{/* ... */}
56+
57+
<section className="mb-8">
58+
<h2 className="text-2xl font-semibold mb-4" id="contact-us">
59+
Contact Us
60+
</h2>
61+
<p>
62+
For questions or concerns about this Privacy Policy, please
63+
contact us at{" "}
64+
<a
65+
href="mailto:[email protected]"
66+
className="text-blue-600 hover:underline"
67+
>
68+
69+
</a>
70+
.
71+
</p>
72+
</section>
73+
</div>
74+
);
75+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
export default function TermsOfService() {
2+
return (
3+
<div className="max-w-4xl mx-auto px-6 py-8">
4+
<h1 className="text-3xl font-bold mb-6" id="terms-of-service">Terms of Service</h1>
5+
6+
<section className="mb-8">
7+
<h2 className="text-2xl font-semibold mb-4" id="acceptance-of-terms">Acceptance of Terms</h2>
8+
<p className="mb-4">
9+
By accessing or using IKAPIAR, you agree to be bound by these Terms
10+
of Service. If you do not agree, you may not use the platform.
11+
</p>
12+
</section>
13+
14+
<section className="mb-8">
15+
<h2 className="text-2xl font-semibold mb-4" id="eligibility">Eligibility</h2>
16+
<p className="mb-4">
17+
Only approved alumni of the institution may use IKAPIAR. Each user
18+
must undergo a verification process.
19+
</p>
20+
</section>
21+
22+
<section className="mb-8">
23+
<h2 className="text-2xl font-semibold mb-4" id="user-responsibilities">User Responsibilities</h2>
24+
<ol className="list-decimal pl-6 space-y-2">
25+
<li>
26+
<strong>Account Security</strong>: You are responsible for
27+
maintaining the confidentiality of your account credentials.
28+
</li>
29+
<li>
30+
<strong>Accurate Information</strong>: Ensure that the data you
31+
provide is accurate and up to date.
32+
</li>
33+
<li>
34+
<strong>Prohibited Activities</strong>: You agree not to:
35+
<ul className="list-disc pl-6 mt-2">
36+
<li>Share your account with others.</li>
37+
<li>Use the platform for unauthorized or malicious purposes.</li>
38+
</ul>
39+
</li>
40+
</ol>
41+
</section>
42+
43+
{/* Additional sections following the same pattern */}
44+
{/* ... */}
45+
46+
<section className="mb-8">
47+
<h2 className="text-2xl font-semibold mb-4" id="contact-us">Contact Us</h2>
48+
<p>
49+
For questions or concerns about these Terms of Service, please contact us at{" "}
50+
<a href="mailto:[email protected]" className="text-blue-600 hover:underline">
51+
52+
</a>.
53+
</p>
54+
</section>
55+
</div>
56+
);
57+
}

0 commit comments

Comments
 (0)