Skip to content

Commit

Permalink
Merge pull request #34 from aswanthabam/dev
Browse files Browse the repository at this point in the history
feat : admin panel & launch anims
  • Loading branch information
aswanthabam authored Dec 10, 2023
2 parents c88d0a2 + 501b1cd commit 58a23af
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 12 deletions.
5 changes: 5 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import { GoogleIdentity, isLoggedIn } from "./utils/utils";
import WhatsappIcon from "./components/whatsapp/Whatsapp";
import Launch from "./pages/launch/launch";
import LaunchHome from "./pages/launch/Home";
import Admin from "./pages/admin/Admin";
import NewEvent from "./pages/admin/admin_pages/new_event/NewEvent";

function getTheme() {
var theme = localStorage.getItem("theme");
Expand Down Expand Up @@ -181,6 +183,9 @@ function App() {
// </TopBarLayer>
}
></Route>
<Route path="/admin" element={<Admin />}>
<Route path="" element={<NewEvent />}></Route>
</Route>
<Route path="*" element={<Error404 />}></Route>
</Routes>
</div>
Expand Down
35 changes: 35 additions & 0 deletions src/apis/adminApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { _EventCreateData } from "../utils/types";
import {
ApiResponse,
ResponseStatus,
ResponseType,
publicRouter,
validateResponse,
} from "./api";

export const isAdmin = async (): Promise<boolean> => {
var res = publicRouter.post("/api/v2/admin/is_admin");
var val = await validateResponse(res);
if (
val.status == ResponseStatus.SUCCESS &&
val.contentType == ResponseType.DATA
) {
return (val.data.data as any)["is_admin"] as boolean;
}
return false;
};

export const createEvent = async (
event: _EventCreateData,
setToast: (
status: boolean,
message: string | null,
hideAfter: number | null
) => void
): Promise<ApiResponse> => {
var res = publicRouter.post("/api/v2/events/create", event);
var val = await validateResponse(res);
console.log(val);
setToast(true, val.data.message, 3000);
return val;
};
12 changes: 12 additions & 0 deletions src/pages/admin/Admin.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.admin {
background: wheat;
width: 100vw;
height: 100vh;
padding: 10px;
color: black;

.content {
height: 100%;
overflow: scroll;
}
}
42 changes: 42 additions & 0 deletions src/pages/admin/Admin.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { useEffect, useState } from "react";
import style from "./Admin.module.css";
import { Outlet, useNavigate } from "react-router-dom";
import { isAdmin } from "../../apis/adminApi";

interface AdminProps {}

const Admin: React.FC<AdminProps> = ({}) => {
const [admin, setAdmin] = useState<boolean>(false);
const redirect = useNavigate();
useEffect(() => {
isAdmin().then((res) => {
setAdmin(res);
if (!res) redirect("/");
});
document.head.innerHTML +=
'<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">';
document.head.innerHTML +=
'<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>';
}, []);
return admin ? (
<div className={style.admin + " container-fluid row"}>
<div className="col-3">
<h3 style={{ textAlign: "center" }}>Vijnana Admin</h3>
<ul className="list-group">
<li className="list-group-item">About Event</li>
<li className="list-group-item">Events</li>
<li className="list-group-item">Add Event</li>
<li className="list-group-item">Add Admin</li>
<li className="list-group-item">Users</li>
</ul>
</div>
<div className={style.content + " col-9"}>
<Outlet />
</div>
</div>
) : (
<div>Admin permission required ..</div>
);
};

export default Admin;
213 changes: 213 additions & 0 deletions src/pages/admin/admin_pages/new_event/NewEvent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import React, { useState } from "react";
import { _Event, _EventCreateData } from "../../../../utils/types";
import { createEvent } from "../../../../apis/adminApi";
import { useToast } from "../../../../components/toast/useToast";

const NewEvent: React.FC = () => {
const [formData, setFormData] = useState<_EventCreateData>({
name: "",
description: "",
details: "",
date: "",
type: "",
image: null,
reg_link: null,
venue: "",
gctian_only: false,
is_reg: true,
closed: false,
});
const { setToastStatus } = useToast();
const handleChange = (
e: React.ChangeEvent<
HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement
>
) => {
console.log(e.target.id, e.target.value);
setFormData({
...formData,
[e.target.id]: e.target.value,
});
};

const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
console.log("Form submitted!");
console.log(formData);
await createEvent(formData, setToastStatus);
};

return (
<div>
<h3 className="underline start" style={{ marginBottom: "30px" }}>
Create New Event
</h3>
<form onSubmit={handleSubmit} method="post">
<div className="mb-3">
<label htmlFor="title" className="form-label">
Event Name:
</label>
<input
type="text"
id="name"
className="form-control"
value={formData.name}
onChange={handleChange}
required
/>
</div>
<div className="mb-3">
<label htmlFor="description" className="form-label">
Description:
</label>
<textarea
id="description"
className="form-control"
value={formData.description}
onChange={handleChange}
required
/>
</div>
<div className="mb-3">
<label htmlFor="details" className="form-label">
details:
</label>
<textarea
id="details"
className="form-control"
value={formData.details}
onChange={handleChange}
required
/>
</div>
<div className="mb-3">
<label htmlFor="date" className="form-label">
Date:
</label>
<input
type="datetime-local"
id="date"
className="form-control"
value={formData.date}
onChange={handleChange}
required
/>
</div>
<div className="mb-3">
<label htmlFor="category" className="form-label">
Event Category:
</label>
<select
id="type"
className="form-select"
value={formData.type}
onChange={handleChange}
required
>
<option value="">Select a category</option>
<option value="cp">Competition</option>
<option value="tk">Talk</option>
<option value="sr">Seminar</option>
<option value="ws">Workshop</option>
</select>
</div>
<div className="mb-3">
<label htmlFor="image" className="form-label">
Event Image URL:
</label>
<input
type="text"
id="image"
className="form-control"
value={formData.image || ""}
onChange={handleChange}
required
/>
</div>
<div className="mb-3">
<label htmlFor="venue" className="form-label">
Event Venue:
</label>
<input
type="text"
id="venue"
className="form-control"
value={formData.venue}
onChange={handleChange}
required
/>
</div>
<div className="mb-3 d-flex " style={{ gap: "15px" }}>
<label htmlFor="gctian_only" className="form-label">
kbmgct STUDENT ONLY?
</label>
<div>
<input
type="radio"
id="gctian_only"
className="form-check-input"
value="1"
checked={formData.gctian_only == true}
onChange={handleChange}
required
/>
<label htmlFor="gctian_only" className="form-check-label">
Yes
</label>
</div>
<div>
<input
type="radio"
id="gctian_only"
className="form-check-input"
value="0"
checked={formData.gctian_only == false}
onChange={handleChange}
required
/>
<label htmlFor="studentOnly" className="form-check-label">
No
</label>
</div>
</div>
<div className="mb-3 d-flex" style={{ gap: "15px" }}>
<label htmlFor="is_reg" className="form-label">
Open to all?
</label>
<div>
<input
type="radio"
id="is_reg"
className="form-check-input"
value="0"
checked={formData.is_reg == false}
onChange={handleChange}
required
/>
<label htmlFor="is_reg" className="form-check-label">
Yes
</label>
</div>
<div>
<input
type="radio"
id="is_reg"
className="form-check-input"
value="1"
checked={formData.is_reg == true}
onChange={handleChange}
required
/>
<label htmlFor="studentOnly" className="form-check-label">
No
</label>
</div>
</div>

<button className="btn btn-primary">Create Event</button>
</form>
</div>
);
};

export default NewEvent;
30 changes: 21 additions & 9 deletions src/pages/launch/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import style from "./LaunchHome.module.css";
// import SecondaryButton from '../../components/buttons/secondary_button/SecondaryButton';
import alien from "../../assets/dehill-spacelove-1-dribble.gif";
import Counter from "../../components/counter/Counter";
import EventList from "../../components/eventlist/EventList";
import Footer from "../../components/footer/Footer";
// import Counter from "../../components/counter/Counter";
// import EventList from "../../components/eventlist/EventList";
// import Footer from "../../components/footer/Footer";
import TopBar from "../../components/topbar/topbar";
import { useState } from "react";
// for build commit
interface LaunchHomeProps {}

const LaunchHome: React.FC<LaunchHomeProps> = ({}) => {
var [dots, setDots] = useState("...");

setInterval(async () => {
if (dots.length > 2) await setDots("");
else await setDots(dots + ".");
// setDots(dots);
}, 1000);
return (
<div className={style.home}>
<TopBar
Expand Down Expand Up @@ -61,23 +69,27 @@ const LaunchHome: React.FC<LaunchHomeProps> = ({}) => {
NA <span className="sparkblink-1">2.0</span>
</h1>
{/* <img style={{ height: 300 }} src="/logo.png" /> */}
<span className={style.mottoText}>KBM Government College</span>
<span className={style.mottoText}>
KBM Government College Thalassery
</span>
<span className="line"></span>
<span className={style.daysLeft}>
The countdown to awesomeness begins...
<span>Coming Soon </span>
{/* <span className={style.dots}>{dots}</span> */}
</span>
<Counter

{/* <Counter
className={style.counter}
date={new Date("2023-12-15 00:00:00")}
/>
/> */}
</div>
</div>
<div className={style.page2}>
{/* <div className={style.page2}>
<h2 className="underline">Events</h2>
<br />
<EventList limit={4} />
</div>
<Footer />
<Footer /> */}
</div>
);
};
Expand Down
Loading

0 comments on commit 58a23af

Please sign in to comment.