diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4da3c4 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/app/components/header.tsx b/app/components/header.tsx new file mode 100644 index 0000000..df17875 --- /dev/null +++ b/app/components/header.tsx @@ -0,0 +1,52 @@ +"use client"; + +import Image from "next/image"; +import Icon from "../../public/logo/logo-transparent-svg.svg"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import {AppwriteConfig} from "../constants/appwrite_config"; + +export default function Header() { + const appwriteConfig = new AppwriteConfig(); + const router = useRouter(); + return ( +
+
+ + Product Logo + + + +
+
+ ); +} diff --git a/app/constants/appwrite_config.tsx b/app/constants/appwrite_config.tsx new file mode 100644 index 0000000..5247c0e --- /dev/null +++ b/app/constants/appwrite_config.tsx @@ -0,0 +1,233 @@ +"use client"; + +import { Client, Account, Models, ID, Databases, Storage } from "appwrite"; +import { User } from "./interface"; +import sdk, { Permission, Role } from "node-appwrite"; + +interface Sponsors { + id: number; + name: string; + url: string; +} +class ServerConfig { + client: sdk.Client = new sdk.Client(); + regDb: string = `${process.env.NEXT_PUBLIC_REGDB}`; + sponDb: string = `${process.env.NEXT_PUBLIC_SPODB}`; + databases: sdk.Databases = new sdk.Databases(this.client); + + constructor() { + this.client + .setEndpoint(`${process.env.NEXT_PUBLIC_ENDPOINT}`) + .setProject(`${process.env.NEXT_PUBLIC_PROJECTID}`) + .setKey(`${process.env.NEXT_PUBLIC_DBKEY}`); + } + + createRegColl(id: string, name: string) { + this.databases + .createCollection(this.regDb, id, name, [ + Permission.read(Role.any()), // Anyone can view this document + Permission.update(Role.any()), // Writers can update this document + Permission.create(Role.any()), // Admins can update this document + Permission.delete(Role.any()), // Admins can delete this document + ]) + .then((res) => { + this.databases.createStringAttribute(this.regDb, id, "name", 50, false); + this.databases.createStringAttribute(this.regDb, id, "email", 50, false); + this.databases.createStringAttribute(this.regDb, id, "confirm", 50, false, ""); + + }); + } + + createSponColl(id: string, name: string, sponsor: Sponsors[], user:string) { + this.databases + .createCollection(this.sponDb, id, name, [ + Permission.read(Role.any()), // Anyone can view this document + Permission.update(Role.user(user)), // Writers can update this document + Permission.create(Role.user(user)), // Admins can update this document + Permission.delete(Role.user(user)), // Admins can delete this document + ]) + .then((res) => { + this.databases + .createStringAttribute(this.sponDb, id, "name", 50, false) + .then((res) => { + this.databases + .createStringAttribute(this.sponDb, id, "url", 50, false) + .then((res) => { + for (var i = 0; i < sponsor.length; i++) { + this.databases.createDocument(this.sponDb, id, ID.unique(), { + name: sponsor[i].name, + url: sponsor[i].url, + }); + } + }); + }); + }); + } +} + +class AppwriteConfig { + databaseId: string = `${process.env.NEXT_PUBLIC_DATABASEID}`; + activeCollId: string = `${process.env.NEXT_PUBLIC_EVENT_COLLID}`; + bannerBucketId: string = `${process.env.NEXT_PUBLIC_EVENTBUCKET}`; + regDbId: string = `${process.env.NEXT_PUBLIC_REGDB}`; + + client: Client = new Client(); + account: Account = new Account(this.client); + databases: Databases = new Databases(this.client); + regDb: Databases = new Databases(this.client); + storage: Storage = new Storage(this.client); + user: User = {} as User; + + constructor() { + this.client + .setEndpoint(`${process.env.NEXT_PUBLIC_ENDPOINT}`) + .setProject(`${process.env.NEXT_PUBLIC_PROJECTID}`); + } + + googlelog(): void { + try { + const promise = this.account.createOAuth2Session( + "google", + `${process.env.NEXT_PUBLIC_APPURL}/login/sucess`, + `${process.env.NEXT_PUBLIC_APPURL}/login/failure`, + [] + ); + this.getCurUser(); + } catch (error) { + console.log(error); + } + } + + githublog(): void { + try { + this.account.createOAuth2Session( + "github", + `${process.env.NEXT_PUBLIC_APPURL}/login/sucess`, + `${process.env.NEXT_PUBLIC_APPURL}/login/failure`, + [] + ); + this.getCurUser(); + } catch (error) { + console.log(error); + } + } + + getCurUser(): void { + try { + this.account + .get() + .then((res) => { + this.user = res; + localStorage.setItem("userInfo", JSON.stringify(this.user)); + }) + .catch((err) => { + console.log(err); + }); + } catch (error) { + console.log(error); + } + } + + emailSignUp(name: string, email: string, password: string): void { + try { + this.account.create(ID.unique(), email, password, name); + } catch (error) { + console.log(error); + } + } + + emailLogin(email: string, password: string): Promise { + return this.account.createEmailSession(email, password); + } + + signOut(id: string): boolean { + try { + this.account.deleteSession(id); + return true; + } catch (error) { + console.log(error); + return false; + } + } + + magicUrlLogin(email: string): void { + this.account.createMagicURLSession( + ID.unique(), + email, + `${process.env.NEXT_PUBLIC_APPURL}/login/sucess` + ); + this.getCurUser(); + } + + createEvent( + eventname: string, + description: string, + banner: File, + hostname: string, + eventdate: string, + email: string, + country: string, + address: string, + city: string, + state: string, + postal: string, + audience: string, + type: string, + attendees: number, + price: number, + tech: string, + agenda: string, + sponsor: Sponsors[], + approval: string, + twitter: string, + website: string, + linkedin: string, + instagram: string + ): Promise { + try { + this.storage + .createFile(this.bannerBucketId, ID.unique(), banner) + .then((res) => { + this.databases + .createDocument(this.databaseId, this.activeCollId, ID.unique(), { + eventname: eventname, + description: description, + url: `${process.env.NEXT_PUBLIC_ENDPOINT}/storage/buckets/${this.bannerBucketId}/files/${res.$id}/view?project=${process.env.NEXT_PUBLIC_PROJECTID}&mode=admin`, + hostname: hostname, + eventdate: eventdate, + email: email, + country: country, + address: address, + city: city, + state: state, + postal: postal, + audience: audience, + type: type, + attendees: attendees, + price: price, + tech: tech, + agenda: agenda, + approval: approval, + created: JSON.parse(localStorage.getItem("userInfo") || "{}").$id, + twitter: twitter, + website: website, + linkedin: linkedin, + instagram: instagram, + registrations: [], + }) + .then((res) => { + const serverConfig = new ServerConfig(); + serverConfig.createRegColl(res.$id, eventname); + serverConfig.createSponColl(res.$id, eventname, sponsor, JSON.parse(localStorage.getItem("userInfo") || "{}").$id); + return Promise.resolve("sucess"); + }); + }); + } catch (error) { + console.log("error block 1"); + throw error; + } + return Promise.resolve("sucess"); + } +} + +export {AppwriteConfig, ServerConfig}; diff --git a/app/constants/interface.tsx b/app/constants/interface.tsx new file mode 100644 index 0000000..27c053e --- /dev/null +++ b/app/constants/interface.tsx @@ -0,0 +1,26 @@ +export interface User { + $id: string; + $createdAt: string; + $updatedAt: string; + name: string; + password?: string | undefined; + hash?: string | undefined; + hashOptions?: object | undefined; + registration: string; + status: boolean; + passwordUpdate: string; + email: string; + phone: string; + emailVerification: boolean; + phoneVerification: boolean; + prefs: Prefs; +} + +export interface HashOptions { + type: string; + memoryCost: number; + timeCost: number; + threads: number; +} + +export interface Prefs {} diff --git a/app/create/create.tsx b/app/create/create.tsx new file mode 100644 index 0000000..f95ae06 --- /dev/null +++ b/app/create/create.tsx @@ -0,0 +1,716 @@ +"use client"; + +import { ChangeEvent, FormEvent, useState } from "react"; +import {AppwriteConfig} from "../constants/appwrite_config"; +import { useRouter } from "next/navigation"; +import { PhotoIcon } from "@heroicons/react/24/solid"; +import Header from "../components/header"; + +interface Sponsors { + id: number; + name: string; + url: string; +} + +const CreateEventPage = () => { + const [eventname, setEventName] = useState(" "); + const [description, setDescription] = useState(" "); + const [banner, setBanner] = useState(null); + const [hostname, setHostName] = useState(" "); + const [eventdate, setEventDate] = useState(" "); + const [email, setEmail] = useState(" "); + const [country, setCountry] = useState(" "); + const [address, setAddress] = useState(" "); + const [city, setCity] = useState(" "); + const [state, setState] = useState(""); + const [postal, setPostal] = useState(" "); + const [audience, setAudience] = useState(" "); + const [type, setType] = useState("In Person"); + const [attendees, setAttendees] = useState(0); + const [price, setPrice] = useState(0); + const [tech, setTech] = useState("Yes"); + const [agenda, setAgenda] = useState(" "); + const [approval, setApproval] = useState(" "); + const [twitter, setTwitter] = useState(" "); + const [website, setWebsite] = useState(" "); + const [linkedin, setLinkedin] = useState(" "); + const [instagram, setInstagram] = useState(" "); + + const router = useRouter(); + const appwriteConfig = new AppwriteConfig(); + + const [sponsors, setSponsors] = useState([ + { id: 1, name: "", url: "" }, + ]); + + const handleSponsorChange = ( + id: number, + fieldName: string, + value: string + ) => { + const updatedFields = sponsors.map((field) => + field.id === id ? { ...field, [fieldName]: value } : field + ); + setSponsors(updatedFields); + }; + + const handleAddSponsor = () => { + const newField: Sponsors = { + id: sponsors.length + 1, + name: "", + url: "", + }; + setSponsors([...sponsors, newField]); + }; + + const handleRemoveSponsor = (id: number) => { + const updatedFields = sponsors.filter((field) => field.id !== id); + setSponsors(updatedFields); + }; + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + + appwriteConfig + .createEvent( + eventname, + description, + banner || new File([], ""), + hostname, + eventdate, + email, + country, + address, + city, + state, + postal, + audience, + type, + attendees, + price, + tech, + agenda, + sponsors, + approval, + twitter, + website, + linkedin, + instagram + ) + .then((res) => { + if (res == "sucess") { + router.push("/events"); + } else { + } + }); + }; + + const handleBannerChange = (e: ChangeEvent) => { + const file = e.target.files?.[0] || null; + setBanner(file); + }; + + return ( +
+
+
+

+ Create Event +

+
+
+
+
+
+ +
+ setEventName(e.target.value)} + autoComplete="given-name" + className="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" + /> +
+
+ +
+ +
+