commit
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .env +10 -0
- .gitignore +36 -0
- Dockerfile +0 -0
- Provider/Provider.jsx +27 -0
- README.md +34 -10
- app/(beta)/api-access/page.jsx +83 -0
- app/(beta)/api-access/page.module.css +139 -0
- app/(beta)/layout.js +25 -0
- app/(working)/ChildLayout.js +192 -0
- app/(working)/layout.js +44 -0
- app/(working)/layout.module.css +317 -0
- app/(working)/loading.js +10 -0
- app/(working)/loading.module.css +20 -0
- app/(working)/page.jsx +42 -0
- app/(working)/page.module.css +24 -0
- app/(working)/search/page.jsx +227 -0
- app/(working)/search/page.module.css +152 -0
- app/(working)/settings/page.jsx +59 -0
- app/(working)/settings/page.module.css +67 -0
- app/Components/Chat/chat.jsx +368 -0
- app/Components/Chat/chat.module.css +516 -0
- app/Components/MarkdownRenderer/MarkdownRenderer.jsx +58 -0
- app/Components/Message/Message.jsx +40 -0
- app/Components/ToggleButton/ToggleButton.jsx +13 -0
- app/Components/ToggleButton/ToggleButton.module.css +72 -0
- app/Contexts/IsMobileContext/IsMobileContext.js +35 -0
- app/Contexts/MessagesContext/MessagesContext.jsx +82 -0
- app/Contexts/ThemeContext/ThemeContext.jsx +60 -0
- app/Supabase/Supabase.js +193 -0
- app/api/api-access/route.js +115 -0
- app/api/auth/[...nextauth]/route.js +77 -0
- app/api/bard/route.js +52 -0
- app/api/chat/route.js +114 -0
- app/favicon.ico +0 -0
- app/globals.css +169 -0
- jsconfig.json +7 -0
- next.config.js +8 -0
- package-lock.json +0 -0
- package.json +45 -0
- public/Fonts/ABeeZee.ttf +0 -0
- public/Fonts/Aharoni.ttf +0 -0
- public/Fonts/Montserrat.ttf +0 -0
- public/Fonts/Quicksand.ttf +0 -0
- public/Fonts/Righteous.ttf +0 -0
- public/Fonts/Roboto.ttf +0 -0
- public/RayAI.jpg +0 -0
- public/RayAI.png +0 -0
- public/RayAI.svg +11 -0
- public/bg.svg +34 -0
- public/card-bg-2.svg +26 -0
.env
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
NEXT_PUBLIC_SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImlpZWhrb2xzaXRicGlqamh0amZ1Iiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTQ5NTg0OTEsImV4cCI6MjAxMDUzNDQ5MX0.arr0B4gUCabegTVk439G7IFm1kG0AEA9xbOLmlEFDP8
|
| 2 |
+
NEXT_PUBLIC_SUPABASE_URL=https://iiehkolsitbpijjhtjfu.supabase.co
|
| 3 |
+
GOOGLE_CLIENT_ID=146606603734-cp01g76uroirlstlasvbp6ihb9at18ki.apps.googleusercontent.com
|
| 4 |
+
GOOGLE_CLIENT_SECRET=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
|
| 5 |
+
NEXTAUTH_URL=http://localhost:3001
|
| 6 |
+
NEXTAUTH_URL_INTERNAL=http://localhost:3001
|
| 7 |
+
NEXTAUTH_SECRET=B6J21rBJZIrkLK1Kgqro3eJ4g1j2ibKPxTW9m77cG6s=
|
| 8 |
+
API_KEY=AIzaSyA6B01DPsXtGIhUQjckCshbD1E99Edd2Tg
|
| 9 |
+
OPENAI_API_KEY=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
|
| 10 |
+
SMTP_PASS=soudishtiaq
|
.gitignore
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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 |
+
|
| 8 |
+
# testing
|
| 9 |
+
/coverage
|
| 10 |
+
|
| 11 |
+
# next.js
|
| 12 |
+
/.next/
|
| 13 |
+
/out/
|
| 14 |
+
|
| 15 |
+
# production
|
| 16 |
+
/build
|
| 17 |
+
|
| 18 |
+
# misc
|
| 19 |
+
.DS_Store
|
| 20 |
+
*.pem
|
| 21 |
+
|
| 22 |
+
# debug
|
| 23 |
+
npm-debug.log*
|
| 24 |
+
yarn-debug.log*
|
| 25 |
+
yarn-error.log*
|
| 26 |
+
|
| 27 |
+
# local env files
|
| 28 |
+
.env
|
| 29 |
+
.env*.local
|
| 30 |
+
|
| 31 |
+
# vercel
|
| 32 |
+
.vercel
|
| 33 |
+
|
| 34 |
+
# typescript
|
| 35 |
+
*.tsbuildinfo
|
| 36 |
+
next-env.d.ts
|
Dockerfile
ADDED
|
File without changes
|
Provider/Provider.jsx
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { SessionProvider, useSession } from "next-auth/react";
|
| 4 |
+
import { createContext, useContext, useEffect, useState } from "react";
|
| 5 |
+
|
| 6 |
+
export async function getUser () {
|
| 7 |
+
try {
|
| 8 |
+
let body = await fetch( "/api/auth/session" );
|
| 9 |
+
let user = await body.json();
|
| 10 |
+
if ( Object.keys( user ).length && Object.keys( user.user ).length ) {
|
| 11 |
+
return { session: user, signedIn: true };
|
| 12 |
+
}
|
| 13 |
+
return { session: null, signedIn: false };
|
| 14 |
+
} catch ( e ) {
|
| 15 |
+
console.log( e );
|
| 16 |
+
}
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
const Provider = ( { children, session } ) => {
|
| 20 |
+
return (
|
| 21 |
+
<SessionProvider session={ session }>
|
| 22 |
+
{ children }
|
| 23 |
+
</SessionProvider>
|
| 24 |
+
);
|
| 25 |
+
};
|
| 26 |
+
|
| 27 |
+
export default Provider;
|
README.md
CHANGED
|
@@ -1,10 +1,34 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
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).
|
| 2 |
+
|
| 3 |
+
## Getting Started
|
| 4 |
+
|
| 5 |
+
First, run the development server:
|
| 6 |
+
|
| 7 |
+
```bash
|
| 8 |
+
npm run dev
|
| 9 |
+
# or
|
| 10 |
+
yarn dev
|
| 11 |
+
# or
|
| 12 |
+
pnpm dev
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
| 16 |
+
|
| 17 |
+
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
|
| 18 |
+
|
| 19 |
+
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
| 20 |
+
|
| 21 |
+
## Learn More
|
| 22 |
+
|
| 23 |
+
To learn more about Next.js, take a look at the following resources:
|
| 24 |
+
|
| 25 |
+
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
| 26 |
+
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
| 27 |
+
|
| 28 |
+
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
| 29 |
+
|
| 30 |
+
## Deploy on Vercel
|
| 31 |
+
|
| 32 |
+
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.
|
| 33 |
+
|
| 34 |
+
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
|
app/(beta)/api-access/page.jsx
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { exists, insertData } from "@/app/Supabase/Supabase";
|
| 4 |
+
import styles from "./page.module.css";
|
| 5 |
+
import { useState } from "react";
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
const ApiPage = () => {
|
| 9 |
+
|
| 10 |
+
const [ disabled, setDisabled ] = useState( false );
|
| 11 |
+
const [ email, setEmail ] = useState( "" );
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
const handleButtonClick = async () => {
|
| 16 |
+
if ( email.trim().length && email.includes( "@" ) ) {
|
| 17 |
+
try {
|
| 18 |
+
setDisabled( true );
|
| 19 |
+
|
| 20 |
+
const userExists = await exists( {
|
| 21 |
+
table: "Early_Access",
|
| 22 |
+
where: {
|
| 23 |
+
email: email
|
| 24 |
+
}
|
| 25 |
+
} );
|
| 26 |
+
|
| 27 |
+
if ( !userExists ) {
|
| 28 |
+
|
| 29 |
+
await insertData( {
|
| 30 |
+
table: "Early_Access",
|
| 31 |
+
object: {
|
| 32 |
+
email
|
| 33 |
+
}
|
| 34 |
+
} );
|
| 35 |
+
|
| 36 |
+
const response = await fetch( "/api/api-access", {
|
| 37 |
+
method: "POST",
|
| 38 |
+
body: JSON.stringify( {
|
| 39 |
+
email
|
| 40 |
+
} )
|
| 41 |
+
} );
|
| 42 |
+
|
| 43 |
+
if ( response.ok ) {
|
| 44 |
+
console.log( await response.json() );
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
} else {
|
| 48 |
+
alert( "User has already signed up for Early Access!" );
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
} catch ( e ) {
|
| 52 |
+
console.log( e );
|
| 53 |
+
} finally {
|
| 54 |
+
setDisabled( false );
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
}
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
const handleInputClick = e => {
|
| 61 |
+
if ( e.key == "Enter" && !e.shiftKey && !disabled ) {
|
| 62 |
+
handleButtonClick();
|
| 63 |
+
}
|
| 64 |
+
};
|
| 65 |
+
|
| 66 |
+
return (
|
| 67 |
+
<section className={ styles[ "api" ] }>
|
| 68 |
+
<div className={ styles[ "heading" ] }>
|
| 69 |
+
<p className={ styles[ "note" ] }>API under Development</p>
|
| 70 |
+
<p className={ styles[ "title" ] }>COMING SOON!</p>
|
| 71 |
+
</div>
|
| 72 |
+
<div className={ styles[ "form" ] }>
|
| 73 |
+
<p className={ styles[ "desc" ] }>Unlock the future – be among the first to access our API with early access</p>
|
| 74 |
+
<div className={ styles[ "input" ] }>
|
| 75 |
+
<input onKeyDown={ handleInputClick } type="text" value={ email } onChange={ ( e ) => setEmail( e.target.value ) } placeholder='Enter your Email' />
|
| 76 |
+
<button disabled={ disabled } type='button' onClick={ handleButtonClick }>{ disabled ? "Sending" : "Send" }</button>
|
| 77 |
+
</div>
|
| 78 |
+
</div>
|
| 79 |
+
</section>
|
| 80 |
+
);
|
| 81 |
+
};
|
| 82 |
+
|
| 83 |
+
export default ApiPage;
|
app/(beta)/api-access/page.module.css
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
section.api {
|
| 2 |
+
background: url("/bg.svg") center no-repeat;
|
| 3 |
+
background-size: cover;
|
| 4 |
+
width: 100vw;
|
| 5 |
+
height: 100vh;
|
| 6 |
+
display: flex;
|
| 7 |
+
flex-direction: column;
|
| 8 |
+
justify-content: center;
|
| 9 |
+
gap: 15vh;
|
| 10 |
+
font-family: Montserrat;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
div.heading {
|
| 14 |
+
display: flex;
|
| 15 |
+
flex-direction: column;
|
| 16 |
+
gap: 3vh;
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
section.api div.heading p.note {
|
| 20 |
+
color: rgba(255, 255, 255, 0.50);
|
| 21 |
+
font-size: 1.45vw;
|
| 22 |
+
text-align: center;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
section.api div.heading p.title {
|
| 26 |
+
color: #FFF;
|
| 27 |
+
text-align: center;
|
| 28 |
+
font-size: 6.65vw;
|
| 29 |
+
font-weight: 700;
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
div.form {
|
| 33 |
+
width: 100%;
|
| 34 |
+
display: flex;
|
| 35 |
+
flex-direction: column;
|
| 36 |
+
align-items: center;
|
| 37 |
+
gap: 10vh;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
div.form p.desc {
|
| 41 |
+
text-align: center;
|
| 42 |
+
color: rgba(255, 255, 255, 0.70);
|
| 43 |
+
font-size: 1.159vw;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
div.input {
|
| 47 |
+
width: 50vw;
|
| 48 |
+
display: flex;
|
| 49 |
+
flex-direction: row;
|
| 50 |
+
justify-content: center;
|
| 51 |
+
position: relative;
|
| 52 |
+
align-items: center;
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
div.input input {
|
| 56 |
+
outline: none;
|
| 57 |
+
border: none;
|
| 58 |
+
border-radius: 6vw;
|
| 59 |
+
background: rgba(255, 255, 255, 0.1);
|
| 60 |
+
width: 100%;
|
| 61 |
+
padding: 2.25vh 3.15vw 2.25vh 1.65vw;
|
| 62 |
+
color: rgb(234, 234, 234);
|
| 63 |
+
position: relative;
|
| 64 |
+
font-size: 1.125vw;
|
| 65 |
+
letter-spacing: .075vw;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
div.input button {
|
| 69 |
+
position: absolute;
|
| 70 |
+
right: .3vw;
|
| 71 |
+
height: calc(100% - .45vw);
|
| 72 |
+
width: 6vw;
|
| 73 |
+
border: none;
|
| 74 |
+
outline: none;
|
| 75 |
+
color: rgb(244, 244, 244);
|
| 76 |
+
border-radius: 3.38vw;
|
| 77 |
+
background: #1F7268;
|
| 78 |
+
letter-spacing: .075vw;
|
| 79 |
+
text-align: center;
|
| 80 |
+
cursor: pointer;
|
| 81 |
+
transition: 60ms ease-in;
|
| 82 |
+
font-size: .98vw;
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
div.input button:hover {
|
| 86 |
+
width: 6.75vw;
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
@media (max-width: 767px) {
|
| 90 |
+
|
| 91 |
+
section.api {
|
| 92 |
+
gap: 90px;
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
div.heading {
|
| 96 |
+
gap: 17px;
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
section.api div.heading p.note {
|
| 100 |
+
font-size: 14px;
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
section.api div.heading p.title {
|
| 104 |
+
font-size: 70px;
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
div.form {
|
| 108 |
+
gap: 70px;
|
| 109 |
+
}
|
| 110 |
+
|
| 111 |
+
div.form p.desc {
|
| 112 |
+
font-size: 14.5px;
|
| 113 |
+
width: 85%;
|
| 114 |
+
}
|
| 115 |
+
|
| 116 |
+
div.input {
|
| 117 |
+
width: 85%;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
div.input input {
|
| 121 |
+
border-radius: 80px;
|
| 122 |
+
padding: 15px 42px 15px 22px;
|
| 123 |
+
font-size: 15px;
|
| 124 |
+
letter-spacing: 1px;
|
| 125 |
+
}
|
| 126 |
+
|
| 127 |
+
div.input button {
|
| 128 |
+
font-size: 13.333px;
|
| 129 |
+
right: 3px;
|
| 130 |
+
height: calc(100% - 6px);
|
| 131 |
+
width: 80px;
|
| 132 |
+
border-radius: 45px;
|
| 133 |
+
letter-spacing: 1px;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
div.input button:hover {
|
| 137 |
+
width: 85px;
|
| 138 |
+
}
|
| 139 |
+
}
|
app/(beta)/layout.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Provider from '@/Provider/Provider.jsx';
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
import "../globals.css";
|
| 5 |
+
|
| 6 |
+
export const metadata = {
|
| 7 |
+
title: 'RayAI API',
|
| 8 |
+
description: 'RayAI: Your Personal AI , Now use as API.',
|
| 9 |
+
|
| 10 |
+
};
|
| 11 |
+
|
| 12 |
+
export default function RootLayout ( { children } ) {
|
| 13 |
+
|
| 14 |
+
return (
|
| 15 |
+
<html lang="en">
|
| 16 |
+
<body>
|
| 17 |
+
<Provider >
|
| 18 |
+
|
| 19 |
+
{ children }
|
| 20 |
+
|
| 21 |
+
</Provider>
|
| 22 |
+
</body>
|
| 23 |
+
</html>
|
| 24 |
+
);
|
| 25 |
+
}
|
app/(working)/ChildLayout.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import styles from "./layout.module.css";
|
| 4 |
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
| 5 |
+
import { faGears, faMagnifyingGlass, faRightFromBracket, faServer } from '@fortawesome/free-solid-svg-icons';
|
| 6 |
+
import { faEnvelope, faMessage } from '@fortawesome/free-regular-svg-icons';
|
| 7 |
+
import { signIn, signOut, useSession } from 'next-auth/react';
|
| 8 |
+
import Image from 'next/image';
|
| 9 |
+
import Link from 'next/link';
|
| 10 |
+
import { faGoogle } from '@fortawesome/free-brands-svg-icons';
|
| 11 |
+
import { useTheme } from '../Contexts/ThemeContext/ThemeContext';
|
| 12 |
+
import Loading from "./loading";
|
| 13 |
+
import { isMobileDevice, toggleNavDevice } from "../Contexts/IsMobileContext/IsMobileContext";
|
| 14 |
+
import { useEffect, useState } from "react";
|
| 15 |
+
import { usePathname } from "next/navigation";
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
const ChildLayout = ( { children } ) => {
|
| 19 |
+
|
| 20 |
+
const { data: session, status } = useSession();
|
| 21 |
+
const { darkMode } = useTheme();
|
| 22 |
+
const { isMobile, setIsMobile } = isMobileDevice();
|
| 23 |
+
const { toggleNav, setToggleNav } = toggleNavDevice();
|
| 24 |
+
const [ isLoading, setLoading ] = useState( true );
|
| 25 |
+
const [ sessionLoading, setSessionLoading ] = useState( true );
|
| 26 |
+
const specialRoutes = [ "api-access" ];
|
| 27 |
+
const pathName = usePathname();
|
| 28 |
+
|
| 29 |
+
useEffect( () => {
|
| 30 |
+
if ( status != "loading" ) {
|
| 31 |
+
setSessionLoading( false );
|
| 32 |
+
}
|
| 33 |
+
console.log( sessionLoading );
|
| 34 |
+
}, [ session, status ] );
|
| 35 |
+
|
| 36 |
+
useEffect( () => {
|
| 37 |
+
|
| 38 |
+
const handleResize = () => setIsMobile( window.innerWidth <= 767 );
|
| 39 |
+
|
| 40 |
+
handleResize();
|
| 41 |
+
|
| 42 |
+
window.addEventListener( "resize", handleResize );
|
| 43 |
+
|
| 44 |
+
setLoading( false );
|
| 45 |
+
|
| 46 |
+
return () => {
|
| 47 |
+
window.removeEventListener( "resize", handleResize );
|
| 48 |
+
};
|
| 49 |
+
|
| 50 |
+
}, [] );
|
| 51 |
+
|
| 52 |
+
let content;
|
| 53 |
+
|
| 54 |
+
// if ( specialRoutes.includes( pathName ) ) {
|
| 55 |
+
// content =
|
| 56 |
+
// <div className={ styles[ "chat-container" ] }>
|
| 57 |
+
// { !isLoading && (
|
| 58 |
+
// <>
|
| 59 |
+
// <div className={ styles[ "previous-chats" ] } style={ isMobile ? {
|
| 60 |
+
// left: toggleNav ? "0" : -150,
|
| 61 |
+
// zIndex: 10
|
| 62 |
+
// } : null }>
|
| 63 |
+
// { isMobile && (
|
| 64 |
+
// <button className={ styles[ "close-nav" ] } onClick={ () => {
|
| 65 |
+
// setToggleNav( false );
|
| 66 |
+
// } }>
|
| 67 |
+
// ✖
|
| 68 |
+
// </button>
|
| 69 |
+
// ) }
|
| 70 |
+
// <div className={ styles[ "logo" ] }>
|
| 71 |
+
// <Image
|
| 72 |
+
// src={ "/logo.png" }
|
| 73 |
+
// alt='logo'
|
| 74 |
+
// width={ "100" }
|
| 75 |
+
// height={ "70" }
|
| 76 |
+
// />
|
| 77 |
+
|
| 78 |
+
// </div>
|
| 79 |
+
// <div className={ styles[ "links" ] }>
|
| 80 |
+
// <Link href={ "/" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faMessage } /> Chats</Link>
|
| 81 |
+
// <Link href={ "/search" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faMagnifyingGlass } /> Search</Link>
|
| 82 |
+
// <Link href={ "/settings" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faGears } /> Settings</Link>
|
| 83 |
+
// <Link href={ "/api-access" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faServer } /> Use as API</Link>
|
| 84 |
+
// </div>
|
| 85 |
+
// <div className={ styles[ 'account' ] }>
|
| 86 |
+
// { session?.user && !sessionLoading ? (
|
| 87 |
+
// <div className={ styles[ 'profile' ] }>
|
| 88 |
+
// <div className={ styles[ 'img' ] }>
|
| 89 |
+
// <Image
|
| 90 |
+
// src={ session.user.image }
|
| 91 |
+
// alt='profile'
|
| 92 |
+
// width={ 30 }
|
| 93 |
+
// height={ 30 }
|
| 94 |
+
// />
|
| 95 |
+
// </div>
|
| 96 |
+
// <div className={ styles[ 'name-email' ] }>
|
| 97 |
+
// <p className={ styles[ "name" ] }>{ session.user.name }</p>
|
| 98 |
+
// <p className={ styles[ "email" ] }>{ session.user.email.length > 22 ? session.user.email.substring( 0, 22 ) + "..." : session.user.email }</p>
|
| 99 |
+
// </div>
|
| 100 |
+
// <FontAwesomeIcon onClick={ () => signOut() } className={ styles[ "logout-icon" ] } icon={ faRightFromBracket } />
|
| 101 |
+
// </div>
|
| 102 |
+
// ) : status != "loading" ? (
|
| 103 |
+
// <button onClick={ () => signIn( "google" ) } type="button"><FontAwesomeIcon className={ styles[ 'google-icon' ] } icon={ faGoogle } /><span>Continue with Google</span></button>
|
| 104 |
+
// ) : (
|
| 105 |
+
// <Loading />
|
| 106 |
+
// ) }
|
| 107 |
+
// </div>
|
| 108 |
+
// </div>
|
| 109 |
+
// <div className={ `${ styles[ "layout" ] } ${ !darkMode ? styles[ "light" ] : "" }` }>
|
| 110 |
+
// { isMobile && (
|
| 111 |
+
// <button className={ styles[ "open-nav" ] } onClick={ () => setToggleNav( true ) }>
|
| 112 |
+
// ☰
|
| 113 |
+
// </button>
|
| 114 |
+
// ) }
|
| 115 |
+
// { children }
|
| 116 |
+
// </div>
|
| 117 |
+
// </>
|
| 118 |
+
// ) }
|
| 119 |
+
// </div >;
|
| 120 |
+
// } else {
|
| 121 |
+
// content = children;
|
| 122 |
+
// }
|
| 123 |
+
|
| 124 |
+
return (
|
| 125 |
+
<div className={ styles[ "chat-container" ] }>
|
| 126 |
+
{ !isLoading && (
|
| 127 |
+
<>
|
| 128 |
+
<div className={ styles[ "previous-chats" ] } style={ isMobile ? {
|
| 129 |
+
left: toggleNav ? "0" : -150,
|
| 130 |
+
zIndex: 10
|
| 131 |
+
} : null }>
|
| 132 |
+
{ isMobile && (
|
| 133 |
+
<button className={ styles[ "close-nav" ] } onClick={ () => {
|
| 134 |
+
setToggleNav( false );
|
| 135 |
+
} }>
|
| 136 |
+
✖
|
| 137 |
+
</button>
|
| 138 |
+
) }
|
| 139 |
+
<div className={ styles[ "logo" ] }>
|
| 140 |
+
<Image
|
| 141 |
+
src={ "/logo.png" }
|
| 142 |
+
alt='logo'
|
| 143 |
+
width={ "100" }
|
| 144 |
+
height={ "70" }
|
| 145 |
+
/>
|
| 146 |
+
|
| 147 |
+
</div>
|
| 148 |
+
<div className={ styles[ "links" ] }>
|
| 149 |
+
<Link href={ "/" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faMessage } /> Chats</Link>
|
| 150 |
+
<Link href={ "/search" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faMagnifyingGlass } /> Search</Link>
|
| 151 |
+
<Link href={ "/settings" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faGears } /> Settings</Link>
|
| 152 |
+
<Link href={ "/api-access" }><FontAwesomeIcon className={ styles[ 'link-icons' ] } icon={ faServer } /> Use as API</Link>
|
| 153 |
+
</div>
|
| 154 |
+
<div className={ styles[ 'account' ] }>
|
| 155 |
+
{ session?.user && !sessionLoading ? (
|
| 156 |
+
<div className={ styles[ 'profile' ] }>
|
| 157 |
+
<div className={ styles[ 'img' ] }>
|
| 158 |
+
<Image
|
| 159 |
+
src={ session.user.image }
|
| 160 |
+
alt='profile'
|
| 161 |
+
width={ 30 }
|
| 162 |
+
height={ 30 }
|
| 163 |
+
/>
|
| 164 |
+
</div>
|
| 165 |
+
<div className={ styles[ 'name-email' ] }>
|
| 166 |
+
<p className={ styles[ "name" ] }>{ session.user.name }</p>
|
| 167 |
+
<p className={ styles[ "email" ] }>{ session.user.email.length > 22 ? session.user.email.substring( 0, 22 ) + "..." : session.user.email }</p>
|
| 168 |
+
</div>
|
| 169 |
+
<FontAwesomeIcon onClick={ () => signOut() } className={ styles[ "logout-icon" ] } icon={ faRightFromBracket } />
|
| 170 |
+
</div>
|
| 171 |
+
) : status != "loading" && !isLoading ? (
|
| 172 |
+
<button onClick={ () => signIn( "google" ) } type="button"><FontAwesomeIcon className={ styles[ 'google-icon' ] } icon={ faGoogle } /><span>Continue with Google</span></button>
|
| 173 |
+
) : (
|
| 174 |
+
<Loading />
|
| 175 |
+
) }
|
| 176 |
+
</div>
|
| 177 |
+
</div>
|
| 178 |
+
<div className={ `${ styles[ "layout" ] } ${ !darkMode ? styles[ "light" ] : "" }` }>
|
| 179 |
+
{ isMobile && (
|
| 180 |
+
<button className={ styles[ "open-nav" ] } onClick={ () => setToggleNav( true ) }>
|
| 181 |
+
☰
|
| 182 |
+
</button>
|
| 183 |
+
) }
|
| 184 |
+
{ children }
|
| 185 |
+
</div>
|
| 186 |
+
</>
|
| 187 |
+
) }
|
| 188 |
+
</div >
|
| 189 |
+
);
|
| 190 |
+
};
|
| 191 |
+
|
| 192 |
+
export default ChildLayout;
|
app/(working)/layout.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import Provider from '@/Provider/Provider.jsx';
|
| 2 |
+
import ThemeProvider from '../Contexts/ThemeContext/ThemeContext';
|
| 3 |
+
import MessagesProvider from '../Contexts/MessagesContext/MessagesContext';
|
| 4 |
+
import ChildLayout from './ChildLayout';
|
| 5 |
+
import IsMobileProvider, { ToggleNavProvider } from '../Contexts/IsMobileContext/IsMobileContext';
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
import "../globals.css";
|
| 9 |
+
|
| 10 |
+
export const metadata = {
|
| 11 |
+
title: 'RayAI',
|
| 12 |
+
description: 'RayAI: Your Personal AI',
|
| 13 |
+
|
| 14 |
+
};
|
| 15 |
+
|
| 16 |
+
export default function RootLayout ( { children } ) {
|
| 17 |
+
|
| 18 |
+
return (
|
| 19 |
+
<html lang="en">
|
| 20 |
+
<body>
|
| 21 |
+
<Provider >
|
| 22 |
+
<ThemeProvider>
|
| 23 |
+
<main>
|
| 24 |
+
<div className='bg1'></div>
|
| 25 |
+
<div className='bg2'></div>
|
| 26 |
+
<div className='bg3'></div>
|
| 27 |
+
<div className='bg4'></div>
|
| 28 |
+
<div className='bg5'></div>
|
| 29 |
+
<MessagesProvider>
|
| 30 |
+
<IsMobileProvider>
|
| 31 |
+
<ToggleNavProvider>
|
| 32 |
+
<ChildLayout>
|
| 33 |
+
{ children }
|
| 34 |
+
</ChildLayout>
|
| 35 |
+
</ToggleNavProvider>
|
| 36 |
+
</IsMobileProvider>
|
| 37 |
+
</MessagesProvider>
|
| 38 |
+
</main>
|
| 39 |
+
</ThemeProvider>
|
| 40 |
+
</Provider>
|
| 41 |
+
</body>
|
| 42 |
+
</html>
|
| 43 |
+
);
|
| 44 |
+
}
|
app/(working)/layout.module.css
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
div.chat-container {
|
| 2 |
+
width: 100%;
|
| 3 |
+
height: 100vh;
|
| 4 |
+
display: flex;
|
| 5 |
+
flex-direction: row;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
div.previous-chats {
|
| 9 |
+
/* background: #fff; */
|
| 10 |
+
height: 100%;
|
| 11 |
+
width: 20.5vw;
|
| 12 |
+
display: flex;
|
| 13 |
+
flex-direction: column;
|
| 14 |
+
padding: .9vw 1.45vw;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
div.layout {
|
| 18 |
+
width: calc(100% - 20.5vw);
|
| 19 |
+
display: flex;
|
| 20 |
+
margin: .75vw;
|
| 21 |
+
background: #b3b3b308;
|
| 22 |
+
overflow: hidden;
|
| 23 |
+
border-radius: 3.75vw;
|
| 24 |
+
border: .075vw solid #365057;
|
| 25 |
+
flex-direction: column;
|
| 26 |
+
backdrop-filter: blur(71px);
|
| 27 |
+
align-items: center;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
div.layout.light {
|
| 31 |
+
border: none;
|
| 32 |
+
background: #ffffffe6;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
div.previous-chats div.links {
|
| 36 |
+
display: flex;
|
| 37 |
+
flex-direction: column;
|
| 38 |
+
position: relative;
|
| 39 |
+
top: 7vh;
|
| 40 |
+
/* Updated from 5.86vw to 12.12vh */
|
| 41 |
+
/* gap: 2px; */
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
.link-icons {
|
| 45 |
+
opacity: 0.4;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
div.previous-chats div.links a {
|
| 49 |
+
text-decoration: none;
|
| 50 |
+
color: #eee;
|
| 51 |
+
padding: .9vw;
|
| 52 |
+
font-family: abeezee;
|
| 53 |
+
font-size: .97vw;
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
div.previous-chats div.logo {
|
| 57 |
+
display: flex;
|
| 58 |
+
position: relative;
|
| 59 |
+
top: 2.62vh;
|
| 60 |
+
/* Updated from 1.125vw to 2.62vh */
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
div.previous-chats div.logo img {
|
| 64 |
+
width: 6.3vw;
|
| 65 |
+
height: auto;
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
div.account {
|
| 69 |
+
position: absolute;
|
| 70 |
+
bottom: 8vh;
|
| 71 |
+
left: 2vw;
|
| 72 |
+
width: 17vw;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
div.build-info {
|
| 76 |
+
padding: .8vw;
|
| 77 |
+
position: relative;
|
| 78 |
+
top: 22vh;
|
| 79 |
+
border-radius: .7vw;
|
| 80 |
+
display: flex;
|
| 81 |
+
width: 90%;
|
| 82 |
+
justify-content: center;
|
| 83 |
+
/* align-items: center; */
|
| 84 |
+
flex-direction: column;
|
| 85 |
+
gap: 2.5vh;
|
| 86 |
+
font-family: Quicksand;
|
| 87 |
+
/* border: .05vw solid #2f2f2f; */
|
| 88 |
+
/* box-shadow: inset 0 0 2px; */
|
| 89 |
+
color: white;
|
| 90 |
+
transform: scale(1);
|
| 91 |
+
animation: card infinite 3s ease-in-out;
|
| 92 |
+
/* background: linear-gradient(108deg, #1a0044 -7.56%, #660868 29.51%, #db5e83 69.57%, #ffd098 107.24%); */
|
| 93 |
+
/* background: linear-gradient(rgba(255, 255, 255, .1), rgba(255, 255, 255, .1)), url("/card-bg.svg"); */
|
| 94 |
+
/* background: url("/card-bg-3.svg") no-repeat; */
|
| 95 |
+
background: linear-gradient(108deg, #052437 -7.56%, #14507d 29.51%, #47a2a5 69.57%, #bcf7ff 107.24%);
|
| 96 |
+
backdrop-filter: blur(50px);
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
div.version {
|
| 100 |
+
display: flex;
|
| 101 |
+
flex-direction: row;
|
| 102 |
+
justify-content: space-between;
|
| 103 |
+
font-size: 1.3vw;
|
| 104 |
+
font-family: abeezee;
|
| 105 |
+
font-weight: bold;
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
div.build-info p.desc {
|
| 109 |
+
position: relative;
|
| 110 |
+
top: -1.2vh;
|
| 111 |
+
font-size: .97vw;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
div.build-info button.card-btn {
|
| 115 |
+
width: fit-content;
|
| 116 |
+
position: relative;
|
| 117 |
+
left: 50%;
|
| 118 |
+
transform: translateX(-50%);
|
| 119 |
+
padding: 1.2vh 1.5vw;
|
| 120 |
+
font-size: .9vw;
|
| 121 |
+
border-radius: .3vw;
|
| 122 |
+
border: none;
|
| 123 |
+
background: #00000049;
|
| 124 |
+
color: white;
|
| 125 |
+
cursor: pointer;
|
| 126 |
+
transition: 90ms linear;
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
div.build-info button.card-btn.light {
|
| 130 |
+
background: white;
|
| 131 |
+
color: rgb(34, 42, 46);
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
div.build-info button.card-btn:hover {
|
| 135 |
+
background: white;
|
| 136 |
+
color: rgb(34, 42, 46);
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
@keyframes card {
|
| 140 |
+
0% {
|
| 141 |
+
transform: scale(1);
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
50% {
|
| 145 |
+
transform: scale(1.03);
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
100% {
|
| 149 |
+
transform: scale(1);
|
| 150 |
+
}
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
div.profile {
|
| 154 |
+
display: flex;
|
| 155 |
+
flex-direction: row;
|
| 156 |
+
gap: .7vw;
|
| 157 |
+
align-items: center;
|
| 158 |
+
font-family: abeezee;
|
| 159 |
+
width: 100%;
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
div.img img {
|
| 163 |
+
border-radius: 50%;
|
| 164 |
+
width: 2.5vw;
|
| 165 |
+
height: 2.5vw;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
div.name-email {
|
| 169 |
+
display: flex;
|
| 170 |
+
flex-direction: column;
|
| 171 |
+
font-size: .9vw;
|
| 172 |
+
color: white;
|
| 173 |
+
gap: .6vh;
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
p.email {
|
| 177 |
+
font-size: .85vw;
|
| 178 |
+
}
|
| 179 |
+
|
| 180 |
+
div.account button {
|
| 181 |
+
background-color: #4285F4;
|
| 182 |
+
color: #fff;
|
| 183 |
+
padding: .75vw .75vw;
|
| 184 |
+
border: none;
|
| 185 |
+
border-radius: .375vw;
|
| 186 |
+
cursor: pointer;
|
| 187 |
+
display: flex;
|
| 188 |
+
flex-direction: row;
|
| 189 |
+
font-size: 1vw;
|
| 190 |
+
gap: .65vw;
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
.logout-icon {
|
| 194 |
+
color: white;
|
| 195 |
+
position: absolute;
|
| 196 |
+
right: 0;
|
| 197 |
+
font-size: .9vw;
|
| 198 |
+
cursor: pointer;
|
| 199 |
+
padding: .7vw;
|
| 200 |
+
}
|
| 201 |
+
|
| 202 |
+
@media (max-width: 767px) {
|
| 203 |
+
|
| 204 |
+
div.previous-chats {
|
| 205 |
+
/* background: #fff; */
|
| 206 |
+
height: 100%;
|
| 207 |
+
/* width: 20.5vw; */
|
| 208 |
+
width: 150px;
|
| 209 |
+
display: flex;
|
| 210 |
+
flex-direction: column;
|
| 211 |
+
/* padding: .9vw 1.45vw; */
|
| 212 |
+
padding: 5px;
|
| 213 |
+
position: absolute;
|
| 214 |
+
transition: 150ms ease-in-out;
|
| 215 |
+
background: rgb(13 36 40);
|
| 216 |
+
}
|
| 217 |
+
|
| 218 |
+
div.layout {
|
| 219 |
+
width: 100%;
|
| 220 |
+
height: 100%;
|
| 221 |
+
}
|
| 222 |
+
|
| 223 |
+
div.previous-chats div.links {
|
| 224 |
+
display: flex;
|
| 225 |
+
flex-direction: column;
|
| 226 |
+
position: relative;
|
| 227 |
+
top: 50px;
|
| 228 |
+
/* Updated from 5.86vw to 12.12vh */
|
| 229 |
+
gap: 2px;
|
| 230 |
+
}
|
| 231 |
+
|
| 232 |
+
.link-icons {
|
| 233 |
+
opacity: 0.4;
|
| 234 |
+
}
|
| 235 |
+
|
| 236 |
+
div.previous-chats div.links a {
|
| 237 |
+
text-decoration: none;
|
| 238 |
+
color: #eee;
|
| 239 |
+
padding: 6px;
|
| 240 |
+
font-family: abeezee;
|
| 241 |
+
font-size: 10px;
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
div.previous-chats div.logo {
|
| 245 |
+
display: flex;
|
| 246 |
+
position: relative;
|
| 247 |
+
top: 20px;
|
| 248 |
+
/* Updated from 1.125vw to 2.62vh */
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
div.previous-chats div.logo img {
|
| 252 |
+
width: 60px;
|
| 253 |
+
height: auto;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
div.account {
|
| 257 |
+
position: absolute;
|
| 258 |
+
bottom: 30px;
|
| 259 |
+
left: 20px;
|
| 260 |
+
width: 120px;
|
| 261 |
+
}
|
| 262 |
+
|
| 263 |
+
button.close-nav {
|
| 264 |
+
position: absolute;
|
| 265 |
+
right: 0;
|
| 266 |
+
border: none;
|
| 267 |
+
width: 25px;
|
| 268 |
+
height: 25px;
|
| 269 |
+
background: #ffffff;
|
| 270 |
+
font-size: 12px;
|
| 271 |
+
border-radius: 50%;
|
| 272 |
+
}
|
| 273 |
+
|
| 274 |
+
button.open-nav {
|
| 275 |
+
position: relative;
|
| 276 |
+
left: calc(-50% + 17px);
|
| 277 |
+
border: none;
|
| 278 |
+
width: 25px;
|
| 279 |
+
height: 25px;
|
| 280 |
+
background: #ffffff;
|
| 281 |
+
font-size: 12px;
|
| 282 |
+
border-radius: 50%;
|
| 283 |
+
}
|
| 284 |
+
|
| 285 |
+
div.profile {
|
| 286 |
+
gap: 7px;
|
| 287 |
+
width: 100%;
|
| 288 |
+
}
|
| 289 |
+
|
| 290 |
+
div.img img {
|
| 291 |
+
border-radius: 50%;
|
| 292 |
+
width: 20px;
|
| 293 |
+
height: 20px;
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
div.name-email {
|
| 297 |
+
font-size: 7px;
|
| 298 |
+
gap: 6px;
|
| 299 |
+
}
|
| 300 |
+
|
| 301 |
+
p.email {
|
| 302 |
+
font-size: 6px;
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
div.account button {
|
| 306 |
+
padding: 10px;
|
| 307 |
+
border-radius: 3px;
|
| 308 |
+
font-size: 12px;
|
| 309 |
+
gap: 8px;
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
.logout-icon {
|
| 313 |
+
font-size: 9px;
|
| 314 |
+
padding: 3px;
|
| 315 |
+
}
|
| 316 |
+
|
| 317 |
+
}
|
app/(working)/loading.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import styles from "./loading.module.css";
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
const Loading = () => {
|
| 5 |
+
return (
|
| 6 |
+
<div className={ styles[ 'loading' ] }></div>
|
| 7 |
+
);
|
| 8 |
+
};
|
| 9 |
+
|
| 10 |
+
export default Loading;
|
app/(working)/loading.module.css
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
div.loading {
|
| 2 |
+
border-radius: 50%;
|
| 3 |
+
background: transparent;
|
| 4 |
+
border: .5vw solid #6464d1;
|
| 5 |
+
width: 2.5vw;
|
| 6 |
+
height: 2.5vw;
|
| 7 |
+
animation: loader infinite ease-in-out 1s;
|
| 8 |
+
transform: rotate(0);
|
| 9 |
+
border-top-color: #2d2d85;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
@keyframes loader {
|
| 13 |
+
0% {
|
| 14 |
+
transform: rotate(0);
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
100% {
|
| 18 |
+
transform: rotate(360deg);
|
| 19 |
+
}
|
| 20 |
+
}
|
app/(working)/page.jsx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { useEffect, useState } from 'react';
|
| 4 |
+
import Chat from '../Components/Chat/chat';
|
| 5 |
+
import { useMessages } from '../Contexts/MessagesContext/MessagesContext';
|
| 6 |
+
import { signIn, useSession } from 'next-auth/react';
|
| 7 |
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
| 8 |
+
import { faGoogle } from '@fortawesome/free-brands-svg-icons';
|
| 9 |
+
|
| 10 |
+
import styles from "./page.module.css";
|
| 11 |
+
import Loading from './loading';
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
|
| 15 |
+
const page = () => {
|
| 16 |
+
const { data: session, status } = useSession();
|
| 17 |
+
const [ signedIn, setSignedIn ] = useState( false );
|
| 18 |
+
|
| 19 |
+
useEffect( () => {
|
| 20 |
+
if ( session?.user ) {
|
| 21 |
+
setSignedIn( true );
|
| 22 |
+
} else {
|
| 23 |
+
setSignedIn( false );
|
| 24 |
+
}
|
| 25 |
+
}, [ session ] );
|
| 26 |
+
|
| 27 |
+
const { messages, setMessages, Msgsloading } = useMessages();
|
| 28 |
+
|
| 29 |
+
return (
|
| 30 |
+
<>
|
| 31 |
+
{ signedIn && status != "loading" ? (
|
| 32 |
+
<Chat messages={ messages } setMessages={ setMessages } Msgsloading={ Msgsloading } />
|
| 33 |
+
) : status == "loading" ? (
|
| 34 |
+
<Loading />
|
| 35 |
+
) : (
|
| 36 |
+
<button className={ styles[ 'google-btn' ] } onClick={ () => signIn( "google" ) } type="button"><FontAwesomeIcon className={ styles[ 'google-icon' ] } icon={ faGoogle } /><span>Continue with Google</span></button >
|
| 37 |
+
) }
|
| 38 |
+
</>
|
| 39 |
+
);
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
export default page;
|
app/(working)/page.module.css
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
button.google-btn {
|
| 2 |
+
background-color: #4285F4;
|
| 3 |
+
color: #fff;
|
| 4 |
+
padding: .75vw .75vw;
|
| 5 |
+
border: none;
|
| 6 |
+
border-radius: .375vw;
|
| 7 |
+
cursor: pointer;
|
| 8 |
+
display: flex;
|
| 9 |
+
flex-direction: row;
|
| 10 |
+
font-size: 1vw;
|
| 11 |
+
gap: .65vw;
|
| 12 |
+
position: absolute;
|
| 13 |
+
top: 50%;
|
| 14 |
+
transform: translateY(-50%);
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
.logout-icon {
|
| 18 |
+
color: white;
|
| 19 |
+
position: absolute;
|
| 20 |
+
right: 0;
|
| 21 |
+
font-size: .9vw;
|
| 22 |
+
cursor: pointer;
|
| 23 |
+
padding: .7vw;
|
| 24 |
+
}
|
app/(working)/search/page.jsx
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { useEffect, useRef, useState } from 'react';
|
| 4 |
+
import styles from "./page.module.css";
|
| 5 |
+
import { useMessages } from '../../Contexts/MessagesContext/MessagesContext';
|
| 6 |
+
import { useTheme } from '../../Contexts/ThemeContext/ThemeContext';
|
| 7 |
+
import { useSession } from 'next-auth/react';
|
| 8 |
+
import { useRouter } from 'next/navigation';
|
| 9 |
+
import dynamic from 'next/dynamic';
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
const Loading = dynamic( () => import( '../loading.js' ) );
|
| 13 |
+
|
| 14 |
+
const Message = dynamic( () => import( '../../Components/Message/Message' ), {
|
| 15 |
+
loading: Loading
|
| 16 |
+
} );
|
| 17 |
+
|
| 18 |
+
const Search = () => {
|
| 19 |
+
const { messages } = useMessages();
|
| 20 |
+
const { darkMode } = useTheme();
|
| 21 |
+
const { data: session } = useSession();
|
| 22 |
+
const router = useRouter();
|
| 23 |
+
const [ prompts, setPrompts ] = useState( [] );
|
| 24 |
+
const [ cancel, setCancel ] = useState( false );
|
| 25 |
+
const msgsRef = useRef();
|
| 26 |
+
|
| 27 |
+
// Debounce the input with a 500ms delay
|
| 28 |
+
const debounce = ( func, delay ) => {
|
| 29 |
+
let timeoutId;
|
| 30 |
+
return function ( ...args ) {
|
| 31 |
+
clearTimeout( timeoutId );
|
| 32 |
+
timeoutId = setTimeout( () => {
|
| 33 |
+
func.apply( this, args );
|
| 34 |
+
}, delay );
|
| 35 |
+
};
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
const filtering = ( searchText ) => {
|
| 39 |
+
try {
|
| 40 |
+
if ( cancel ) {
|
| 41 |
+
return;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
if ( searchText.trim().length === 0 ) {
|
| 45 |
+
setPrompts( [] );
|
| 46 |
+
} else {
|
| 47 |
+
let filteredArray = messages.filter( ( message ) =>
|
| 48 |
+
message.content.toLowerCase().includes( searchText.toLowerCase() )
|
| 49 |
+
);
|
| 50 |
+
console.log( "filtered: ", filteredArray );
|
| 51 |
+
setPrompts( filteredArray );
|
| 52 |
+
}
|
| 53 |
+
} catch ( err ) {
|
| 54 |
+
console.log( err );
|
| 55 |
+
}
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
const debouncedFiltering = useRef( debounce( filtering, 500 ) );
|
| 59 |
+
|
| 60 |
+
const handleInputChange = ( e ) => {
|
| 61 |
+
setCancel( false );
|
| 62 |
+
debouncedFiltering.current( e.target.value );
|
| 63 |
+
};
|
| 64 |
+
|
| 65 |
+
useEffect( () => {
|
| 66 |
+
return () => {
|
| 67 |
+
setCancel( true );
|
| 68 |
+
};
|
| 69 |
+
}, [] );
|
| 70 |
+
|
| 71 |
+
return (
|
| 72 |
+
<div className={ styles[ "search-container" ] }>
|
| 73 |
+
<div className={ styles[ "input" ] }>
|
| 74 |
+
<input
|
| 75 |
+
type="text"
|
| 76 |
+
onChange={ handleInputChange }
|
| 77 |
+
placeholder="Search Message"
|
| 78 |
+
/>
|
| 79 |
+
</div>
|
| 80 |
+
{ !prompts.length && (
|
| 81 |
+
<p className={ styles[ 'placeholder' ] }>No Messages :(</p>
|
| 82 |
+
) }
|
| 83 |
+
<div className={ `${ styles[ "msgs" ] } ${ !darkMode ? styles[ "light" ] : "" }` } ref={ msgsRef }>
|
| 84 |
+
{ prompts.map( ( msg, key ) => (
|
| 85 |
+
<Message
|
| 86 |
+
onClick={ ( e ) => {
|
| 87 |
+
e.stopPropagation();
|
| 88 |
+
router.replace( "/#" + msg.key, { scroll: false } );
|
| 89 |
+
} }
|
| 90 |
+
key={ key }
|
| 91 |
+
msg={ msg }
|
| 92 |
+
session={ session }
|
| 93 |
+
styles={ styles }
|
| 94 |
+
/>
|
| 95 |
+
) ) }
|
| 96 |
+
</div>
|
| 97 |
+
</div>
|
| 98 |
+
);
|
| 99 |
+
};
|
| 100 |
+
|
| 101 |
+
export default Search;
|
| 102 |
+
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
// "use client";
|
| 112 |
+
|
| 113 |
+
// import { useEffect, useRef, useState } from 'react';
|
| 114 |
+
// import styles from "./page.module.css";
|
| 115 |
+
// import { useMessages } from '../Contexts/MessagesContext/MessagesContext';
|
| 116 |
+
// import Message from '../Components/Message/Message';
|
| 117 |
+
// import { useTheme } from '../Contexts/ThemeContext/ThemeContext';
|
| 118 |
+
// import { useSession } from 'next-auth/react';
|
| 119 |
+
// import { useRouter } from 'next/navigation';
|
| 120 |
+
// import { useChat } from 'ai/react';
|
| 121 |
+
|
| 122 |
+
|
| 123 |
+
// const Search = () => {
|
| 124 |
+
|
| 125 |
+
// const { messages } = useMessages();
|
| 126 |
+
// const { darkMode, _ } = useTheme();
|
| 127 |
+
// const { data: session } = useSession();
|
| 128 |
+
// const [ prompts, setPrompts ] = useState( [] );
|
| 129 |
+
// const router = useRouter();
|
| 130 |
+
// const [ Input, setInput ] = useState( "" );
|
| 131 |
+
// const [ cancel, setCancel ] = useState( false );
|
| 132 |
+
// const msgsRef = useRef();
|
| 133 |
+
|
| 134 |
+
// const debounce = ( func, delay ) => {
|
| 135 |
+
// let timeoutId;
|
| 136 |
+
// return function ( ...args ) {
|
| 137 |
+
// clearTimeout( timeoutId );
|
| 138 |
+
// timeoutId = setTimeout( () => {
|
| 139 |
+
// func.apply( this, args );
|
| 140 |
+
// }, delay );
|
| 141 |
+
// };
|
| 142 |
+
// };
|
| 143 |
+
|
| 144 |
+
// // const handleInputChange = debounce( ( e ) => {
|
| 145 |
+
|
| 146 |
+
// // console.log( messages );
|
| 147 |
+
|
| 148 |
+
// // if ( e.target.value.trim().length == 0 ) {
|
| 149 |
+
// // setPrompts( [] );
|
| 150 |
+
// // } else {
|
| 151 |
+
// // let filteredMessages = messages.filter( ( message ) => message.content.toLowerCase().includes( e.target.value.toLowerCase() ) );
|
| 152 |
+
// // setPrompts( [ ...filteredMessages ] );
|
| 153 |
+
// // }
|
| 154 |
+
|
| 155 |
+
// // }, 300 );
|
| 156 |
+
|
| 157 |
+
// const handleInputChange = ( e ) => {
|
| 158 |
+
// setCancel( false );
|
| 159 |
+
// setInput( e.target.value );
|
| 160 |
+
// };
|
| 161 |
+
|
| 162 |
+
// useEffect( () => {
|
| 163 |
+
|
| 164 |
+
// const Filtering = async () => {
|
| 165 |
+
// console.log( messages );
|
| 166 |
+
|
| 167 |
+
// try {
|
| 168 |
+
|
| 169 |
+
// if ( cancel ) {
|
| 170 |
+
// return;
|
| 171 |
+
// }
|
| 172 |
+
|
| 173 |
+
// if ( Input.trim().length == 0 ) {
|
| 174 |
+
|
| 175 |
+
// setPrompts( [] );
|
| 176 |
+
|
| 177 |
+
// } else {
|
| 178 |
+
|
| 179 |
+
// let filteredArray = await filtering();
|
| 180 |
+
// console.log( "filtered: ", filteredArray );
|
| 181 |
+
// setPrompts( filteredArray );
|
| 182 |
+
|
| 183 |
+
// }
|
| 184 |
+
|
| 185 |
+
// } catch ( err ) {
|
| 186 |
+
// console.log( err );
|
| 187 |
+
// }
|
| 188 |
+
|
| 189 |
+
// };
|
| 190 |
+
|
| 191 |
+
// Filtering();
|
| 192 |
+
|
| 193 |
+
// return () => {
|
| 194 |
+
// setCancel( true );
|
| 195 |
+
// };
|
| 196 |
+
|
| 197 |
+
// }, [ Input ] );
|
| 198 |
+
|
| 199 |
+
// const filtering = async () => {
|
| 200 |
+
|
| 201 |
+
// let filteredMessages = messages.filter( ( message ) => message.content.toLowerCase().includes( Input.toLowerCase() ) );
|
| 202 |
+
// return filteredMessages;
|
| 203 |
+
|
| 204 |
+
// };
|
| 205 |
+
|
| 206 |
+
|
| 207 |
+
// return (
|
| 208 |
+
// <div className={ styles[ "search-container" ] }>
|
| 209 |
+
// <div className={ styles[ "input" ] }>
|
| 210 |
+
// <input type={ styles[ "text" ] } onChange={ handleInputChange } placeholder='Search Message' />
|
| 211 |
+
// </div>
|
| 212 |
+
// { !prompts.length && (
|
| 213 |
+
// <p className={ styles[ 'placeholder' ] }>No Messages :(</p>
|
| 214 |
+
// ) }
|
| 215 |
+
// <div className={ `${ styles[ "msgs" ] } ${ !darkMode ? styles[ "light" ] : "" }` } ref={ msgsRef }>
|
| 216 |
+
// { prompts.map( ( msg, key ) => (
|
| 217 |
+
// <Message onClick={ ( e ) => {
|
| 218 |
+
// e.stopPropagation();
|
| 219 |
+
// router.replace( "/#" + msg.key, { scroll: false } );
|
| 220 |
+
// } } key={ key } msg={ msg } session={ session } styles={ styles } />
|
| 221 |
+
// ) ) }
|
| 222 |
+
// </div>
|
| 223 |
+
// </div>
|
| 224 |
+
// );
|
| 225 |
+
// };
|
| 226 |
+
|
| 227 |
+
// export default Search;
|
app/(working)/search/page.module.css
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
div.search-container {
|
| 2 |
+
width: calc(100% - 4.6vw);
|
| 3 |
+
height: calc(100% - 4.6vw);
|
| 4 |
+
position: relative;
|
| 5 |
+
top: 50%;
|
| 6 |
+
transform: translateY(-50%);
|
| 7 |
+
display: flex;
|
| 8 |
+
flex-direction: column;
|
| 9 |
+
align-items: center;
|
| 10 |
+
gap: 6vh;
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
p.placeholder {
|
| 14 |
+
position: absolute;
|
| 15 |
+
top: 50%;
|
| 16 |
+
left: 50%;
|
| 17 |
+
transform: translate(-50%, -50%);
|
| 18 |
+
font-size: 4vw;
|
| 19 |
+
font-family: abeezee;
|
| 20 |
+
color: #17c4ab26;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
div.search-container div.input {
|
| 24 |
+
width: 100%;
|
| 25 |
+
display: flex;
|
| 26 |
+
flex-direction: row;
|
| 27 |
+
justify-content: center;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
div.search-container div.input input {
|
| 31 |
+
width: 100%;
|
| 32 |
+
border: none;
|
| 33 |
+
padding: 1.1vw 1.3vw;
|
| 34 |
+
outline: none;
|
| 35 |
+
border-radius: .4vw;
|
| 36 |
+
font-size: 1.3vw;
|
| 37 |
+
color: #cbcbcb;
|
| 38 |
+
background: #22454D;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
div.msgs {
|
| 42 |
+
width: 100%;
|
| 43 |
+
overflow: auto;
|
| 44 |
+
display: flex;
|
| 45 |
+
flex-direction: column;
|
| 46 |
+
position: relative;
|
| 47 |
+
align-items: center;
|
| 48 |
+
gap: 3.1vh;
|
| 49 |
+
scroll-behavior: smooth;
|
| 50 |
+
transition: 150ms ease-in-out;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
div.msgs.light div.user,
|
| 54 |
+
div.msgs.light div.ai {
|
| 55 |
+
border-color: #c9e0df;
|
| 56 |
+
background: #def7f352;
|
| 57 |
+
color: #254a4d;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
div.msgs div.markdown-content > pre {
|
| 61 |
+
position: relative;
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
div.msgs.light div.markdown-content > pre > pre {
|
| 65 |
+
border: 1px solid #e8ebec;
|
| 66 |
+
transition: 150ms ease-in-out;
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
div.markdown-content,
|
| 70 |
+
div.markdown-content * {
|
| 71 |
+
white-space: pre-wrap;
|
| 72 |
+
line-height: 1.7;
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
div.user,
|
| 76 |
+
div.ai {
|
| 77 |
+
font-family: abeezee;
|
| 78 |
+
font-size: 1vw;
|
| 79 |
+
background: #5656563c;
|
| 80 |
+
border-radius: 1.4vw;
|
| 81 |
+
padding: 2vw 2vw 2vw 3vw;
|
| 82 |
+
border: #365057 1px solid;
|
| 83 |
+
display: flex;
|
| 84 |
+
color: #bebebe;
|
| 85 |
+
flex-direction: row;
|
| 86 |
+
width: calc(100% - 1.8vw);
|
| 87 |
+
position: relative;
|
| 88 |
+
left: .5vw !important;
|
| 89 |
+
cursor: pointer;
|
| 90 |
+
transition: 200ms ease-in-out;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
@keyframes msg {
|
| 94 |
+
0% {
|
| 95 |
+
height: 0;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
100% {
|
| 99 |
+
height: auto;
|
| 100 |
+
}
|
| 101 |
+
}
|
| 102 |
+
|
| 103 |
+
.text-pic {
|
| 104 |
+
width: 2.7vw;
|
| 105 |
+
height: 2.7vw;
|
| 106 |
+
position: absolute;
|
| 107 |
+
left: -1vw;
|
| 108 |
+
top: 2.8vh;
|
| 109 |
+
border-radius: .5vw;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
@media (max-width: 767px) {
|
| 113 |
+
div.search-container {
|
| 114 |
+
width: calc(100% - 13px);
|
| 115 |
+
height: calc(100% - 43px);
|
| 116 |
+
gap: 30px;
|
| 117 |
+
position: absolute;
|
| 118 |
+
top: calc(50% + 20px);
|
| 119 |
+
transform: translateY(-50%);
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
p.placeholder {
|
| 123 |
+
font-size: 10px;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
div.search-container div.input input {
|
| 127 |
+
padding: 5px 10px;
|
| 128 |
+
border-radius: 4px;
|
| 129 |
+
font-size: 10px;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
div.msgs {
|
| 133 |
+
gap: 20px;
|
| 134 |
+
}
|
| 135 |
+
|
| 136 |
+
div.user,
|
| 137 |
+
div.ai {
|
| 138 |
+
font-size: 11px;
|
| 139 |
+
border-radius: 10px;
|
| 140 |
+
padding: 10px 10px 10px 20px;
|
| 141 |
+
width: calc(100% - 20px);
|
| 142 |
+
left: 2px;
|
| 143 |
+
}
|
| 144 |
+
|
| 145 |
+
.text-pic {
|
| 146 |
+
width: 20px;
|
| 147 |
+
height: 20px;
|
| 148 |
+
left: -10px;
|
| 149 |
+
top: 10px;
|
| 150 |
+
border-radius: 5px;
|
| 151 |
+
}
|
| 152 |
+
}
|
app/(working)/settings/page.jsx
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import ToggleButton from '@/app/Components/ToggleButton/ToggleButton';
|
| 4 |
+
import { useTheme } from '@/app/Contexts/ThemeContext/ThemeContext';
|
| 5 |
+
|
| 6 |
+
import styles from "./page.module.css";
|
| 7 |
+
import { signIn, signOut } from 'next-auth/react';
|
| 8 |
+
import { getUser } from '@/Provider/Provider';
|
| 9 |
+
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
const ThemeButton = memo( () => {
|
| 13 |
+
|
| 14 |
+
const { darkMode, toggleDarkMode } = useTheme();
|
| 15 |
+
const themeToggle = useCallback( () => toggleDarkMode(), [] );
|
| 16 |
+
|
| 17 |
+
return <ToggleButton checked={ darkMode } onChange={ themeToggle } />;
|
| 18 |
+
|
| 19 |
+
} );
|
| 20 |
+
|
| 21 |
+
const page = () => {
|
| 22 |
+
const { darkMode } = useTheme();
|
| 23 |
+
const [ user, setUser ] = useState( null );
|
| 24 |
+
|
| 25 |
+
useEffect( () => {
|
| 26 |
+
async function fetchUser () {
|
| 27 |
+
const user = await getUser();
|
| 28 |
+
setUser( user );
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
fetchUser();
|
| 32 |
+
} );
|
| 33 |
+
|
| 34 |
+
const signedIn = useMemo( () => {
|
| 35 |
+
return user !== null;
|
| 36 |
+
}, [ user ] );
|
| 37 |
+
|
| 38 |
+
let button;
|
| 39 |
+
|
| 40 |
+
if ( signedIn ) {
|
| 41 |
+
button = <button className={ styles[ "logout-btn" ] } onClick={ () => signOut() }>Sign-Out</button>;
|
| 42 |
+
} else {
|
| 43 |
+
button = <button className={ styles[ "logout-btn" ] } onClick={ () => signIn( "google" ) }>Sign-In</button>;
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
return (
|
| 47 |
+
<div className={ `${ styles[ 'options' ] } ${ !darkMode ? styles[ 'light' ] : "" }` }>
|
| 48 |
+
<div className={ styles[ 'theme-changer' ] }>
|
| 49 |
+
<p className="label">Toggle Dark Mode</p>
|
| 50 |
+
<ThemeButton />
|
| 51 |
+
</div>
|
| 52 |
+
<div className={ styles[ "logout" ] }>
|
| 53 |
+
{ button }
|
| 54 |
+
</div>
|
| 55 |
+
</div>
|
| 56 |
+
);
|
| 57 |
+
};
|
| 58 |
+
|
| 59 |
+
export default page;
|
app/(working)/settings/page.module.css
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
div.options {
|
| 2 |
+
height: 100%;
|
| 3 |
+
width: 100%;
|
| 4 |
+
display: flex;
|
| 5 |
+
flex-direction: column;
|
| 6 |
+
align-items: flex-start;
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
div.theme-changer {
|
| 10 |
+
display: flex;
|
| 11 |
+
justify-content: space-between;
|
| 12 |
+
align-items: center;
|
| 13 |
+
width: 80%;
|
| 14 |
+
font-family: abeezee;
|
| 15 |
+
font-size: 1.3vw;
|
| 16 |
+
color: #a5c6c8;
|
| 17 |
+
position: relative;
|
| 18 |
+
top: 5vh;
|
| 19 |
+
left: 7.5vw;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
div.options.light div.theme-changer {
|
| 23 |
+
color: #3b5557;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
div.logout {
|
| 27 |
+
position: relative;
|
| 28 |
+
top: 13vh;
|
| 29 |
+
background: #555;
|
| 30 |
+
left: 7.5vw;
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
div.logout button {
|
| 34 |
+
background: #a30f3e;
|
| 35 |
+
padding: 1vw 2vw;
|
| 36 |
+
color: white;
|
| 37 |
+
border: none;
|
| 38 |
+
font-size: 1.1vw;
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
div.options.light div.logout button {
|
| 42 |
+
background: #d40c4c;
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
@media (max-width: 768px) {
|
| 46 |
+
div.theme-changer {
|
| 47 |
+
font-size: 13px;
|
| 48 |
+
color: #a5c6c8;
|
| 49 |
+
top: 45px;
|
| 50 |
+
left: 37px;
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
div.logout {
|
| 54 |
+
position: relative;
|
| 55 |
+
top: 90px;
|
| 56 |
+
background: #555;
|
| 57 |
+
left: 37px;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
div.logout button {
|
| 61 |
+
background: #a30f3e;
|
| 62 |
+
padding: 8px 12px;
|
| 63 |
+
color: white;
|
| 64 |
+
border: none;
|
| 65 |
+
font-size: 12px;
|
| 66 |
+
}
|
| 67 |
+
}
|
app/Components/Chat/chat.jsx
ADDED
|
@@ -0,0 +1,368 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
| 4 |
+
import { faBarsStaggered, faChevronDown, faPaperPlane, faStop, faTriangleExclamation } from '@fortawesome/free-solid-svg-icons';
|
| 5 |
+
import { useSession } from 'next-auth/react';
|
| 6 |
+
import { useChat } from "ai/react";
|
| 7 |
+
import { useTheme } from "../../Contexts/ThemeContext/ThemeContext";
|
| 8 |
+
import { memo, useCallback, useEffect, useRef, useState } from "react";
|
| 9 |
+
import { insertData } from "@/app/Supabase/Supabase";
|
| 10 |
+
import { v4 as uuid } from "uuid";
|
| 11 |
+
import Image from 'next/image';
|
| 12 |
+
import styles from "./chat.module.css";
|
| 13 |
+
import Message from "../Message/Message";
|
| 14 |
+
import { isMobileDevice } from '@/app/Contexts/IsMobileContext/IsMobileContext';
|
| 15 |
+
|
| 16 |
+
const debounce = ( func, delay ) => {
|
| 17 |
+
let timeoutId;
|
| 18 |
+
return function ( ...args ) {
|
| 19 |
+
clearTimeout( timeoutId );
|
| 20 |
+
timeoutId = setTimeout( () => {
|
| 21 |
+
func.apply( this, args );
|
| 22 |
+
}, delay );
|
| 23 |
+
};
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
const Chat = ( { messages, setMessages, Msgsloading } ) => {
|
| 27 |
+
|
| 28 |
+
const { data: session } = useSession();
|
| 29 |
+
const { darkMode } = useTheme();
|
| 30 |
+
const [ newPrompt, setNewPrompt ] = useState( [] );
|
| 31 |
+
const [ pageRendered, setPageRendered ] = useState( false );
|
| 32 |
+
const [ hash, setHash ] = useState( "" );
|
| 33 |
+
const [ buttonToBottom, setbuttonToBottom ] = useState( false );
|
| 34 |
+
const { isMobile, setIsMobile } = isMobileDevice();
|
| 35 |
+
const [ input, setInput ] = useState( "" );
|
| 36 |
+
const [ isLoading, setLoading ] = useState( false );
|
| 37 |
+
|
| 38 |
+
const inputChange = ( e ) => {
|
| 39 |
+
setInput( e.target.value );
|
| 40 |
+
};
|
| 41 |
+
|
| 42 |
+
const handleSubmit = async ( e ) => {
|
| 43 |
+
e.preventDefault();
|
| 44 |
+
setInput( "" );
|
| 45 |
+
|
| 46 |
+
try {
|
| 47 |
+
setLoading( true );
|
| 48 |
+
|
| 49 |
+
const response = await fetch( "/api/chat", {
|
| 50 |
+
method: "POST",
|
| 51 |
+
body: JSON.stringify( {
|
| 52 |
+
input,
|
| 53 |
+
// chatbot_model: 0,
|
| 54 |
+
// web_search: true,
|
| 55 |
+
new_convo: !messages.length
|
| 56 |
+
} )
|
| 57 |
+
} );
|
| 58 |
+
|
| 59 |
+
// const response = await fetch( "https://AIONS.pythonanywhere.com/api/huggingface", {
|
| 60 |
+
// method: "POST",
|
| 61 |
+
// body: JSON.stringify( {
|
| 62 |
+
// prompt: input,
|
| 63 |
+
// chatbot_model: 0,
|
| 64 |
+
// web_search: true,
|
| 65 |
+
// new_conversation: false
|
| 66 |
+
// } ),
|
| 67 |
+
// headers: {
|
| 68 |
+
// 'Content-Type': 'application/json'
|
| 69 |
+
// },
|
| 70 |
+
// mode: "cors"
|
| 71 |
+
// } );
|
| 72 |
+
|
| 73 |
+
if ( response.ok ) {
|
| 74 |
+
let body = await response.json();
|
| 75 |
+
console.log( body );
|
| 76 |
+
|
| 77 |
+
let key = uuid();
|
| 78 |
+
|
| 79 |
+
setMessages( prev => [
|
| 80 |
+
...prev,
|
| 81 |
+
{ content: body.body.response, role: "assistant", key }
|
| 82 |
+
] );
|
| 83 |
+
|
| 84 |
+
setNewPrompt( prev => [ ...prev, { value: body.body.response, key } ] );
|
| 85 |
+
// setNewPrompt( [] );
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
} catch ( e ) {
|
| 89 |
+
console.log( e );
|
| 90 |
+
setNewPrompt( [] );
|
| 91 |
+
} finally {
|
| 92 |
+
setLoading( false );
|
| 93 |
+
}
|
| 94 |
+
};
|
| 95 |
+
|
| 96 |
+
const stop = () => { };
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
// const { messages: msgs, input, handleInputChange: inputChange, handleSubmit, stop, isLoading } = useChat( {
|
| 101 |
+
// id: "_RAY_AI_CHAT_",
|
| 102 |
+
// initialMessages: messages,
|
| 103 |
+
// onFinish: ( msg ) => {
|
| 104 |
+
// setNewPrompt( prev => [ ...prev, { value: msg.content, key: msg.id } ] );
|
| 105 |
+
// }
|
| 106 |
+
// } );
|
| 107 |
+
|
| 108 |
+
useEffect( () => {
|
| 109 |
+
|
| 110 |
+
if ( typeof window !== "undefined" ) {
|
| 111 |
+
setHash( window.location.hash.slice( 1 ) );
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
const handleResize = () => setIsMobile( window.innerWidth <= 767 );
|
| 115 |
+
|
| 116 |
+
handleResize();
|
| 117 |
+
|
| 118 |
+
window.addEventListener( "resize", handleResize );
|
| 119 |
+
|
| 120 |
+
const scrollEvent = e => {
|
| 121 |
+
|
| 122 |
+
let element = e.target;
|
| 123 |
+
|
| 124 |
+
if ( element.scrollHeight - element.clientHeight - element.scrollTop >= 2000 ) setbuttonToBottom( true );
|
| 125 |
+
else setbuttonToBottom( false );
|
| 126 |
+
|
| 127 |
+
};
|
| 128 |
+
|
| 129 |
+
let msgsDiv = document.getElementsByClassName( styles[ "msgs" ] )[ 0 ];
|
| 130 |
+
msgsDiv.addEventListener( "scroll", scrollEvent );
|
| 131 |
+
|
| 132 |
+
return () => {
|
| 133 |
+
window.removeEventListener( "resize", handleResize );
|
| 134 |
+
msgsDiv.removeEventListener( "scroll", scrollEvent );
|
| 135 |
+
};
|
| 136 |
+
|
| 137 |
+
}, [] );
|
| 138 |
+
|
| 139 |
+
useEffect( () => {
|
| 140 |
+
console.log( "isLoading: ", isLoading );
|
| 141 |
+
}, [ isLoading ] );
|
| 142 |
+
|
| 143 |
+
const msgsRef = useRef();
|
| 144 |
+
|
| 145 |
+
|
| 146 |
+
const scrollToMessage = () => {
|
| 147 |
+
const messageElement = document.getElementById( hash );
|
| 148 |
+
|
| 149 |
+
if ( messageElement ) {
|
| 150 |
+
messageElement.scrollIntoView( { behavior: 'smooth' } );
|
| 151 |
+
}
|
| 152 |
+
};
|
| 153 |
+
|
| 154 |
+
useEffect( () => {
|
| 155 |
+
|
| 156 |
+
if ( hash.trim().length ) scrollToMessage();
|
| 157 |
+
|
| 158 |
+
}, [ hash, pageRendered ] );
|
| 159 |
+
|
| 160 |
+
const send = async ( e ) => {
|
| 161 |
+
|
| 162 |
+
if ( input.trim().length && !isLoading ) {
|
| 163 |
+
|
| 164 |
+
let key = uuid();
|
| 165 |
+
|
| 166 |
+
setMessages( prev => [
|
| 167 |
+
...prev,
|
| 168 |
+
{ content: input, role: "user", key }
|
| 169 |
+
] );
|
| 170 |
+
|
| 171 |
+
handleSubmit( e );
|
| 172 |
+
|
| 173 |
+
setNewPrompt( prev => [ ...prev, { value: input, key } ] );
|
| 174 |
+
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
};
|
| 178 |
+
|
| 179 |
+
const debouncedScrollToBottom = debounce( () => {
|
| 180 |
+
let isNearBottom = msgsRef.current.scrollHeight - msgsRef.current.clientHeight - msgsRef.current.scrollTop <= 250;
|
| 181 |
+
|
| 182 |
+
if ( isNearBottom ) {
|
| 183 |
+
|
| 184 |
+
msgsRef.current.scrollTo( {
|
| 185 |
+
top: msgsRef.current.scrollHeight,
|
| 186 |
+
// behavior: "smooth"
|
| 187 |
+
} );
|
| 188 |
+
|
| 189 |
+
// msgsRef.current.scrollIntoView( { behavior: 'smooth', block: 'end' } );
|
| 190 |
+
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
}, 500 );
|
| 194 |
+
|
| 195 |
+
useEffect( () => {
|
| 196 |
+
if ( messages.length ) {
|
| 197 |
+
|
| 198 |
+
debouncedScrollToBottom();
|
| 199 |
+
|
| 200 |
+
if ( !pageRendered ) {
|
| 201 |
+
msgsRef.current.scroll( 0, msgsRef.current.scrollHeight );
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
setPageRendered( true );
|
| 205 |
+
}
|
| 206 |
+
}, [ messages ] );
|
| 207 |
+
|
| 208 |
+
useEffect( () => {
|
| 209 |
+
|
| 210 |
+
console.log( "useffectt newPromp: ", newPrompt );
|
| 211 |
+
|
| 212 |
+
if ( newPrompt.length == 2 ) {
|
| 213 |
+
|
| 214 |
+
// setMessages( prev => [ ...prev,
|
| 215 |
+
// { content: newPrompt[ 0 ].value, role: "user", key: newPrompt[ 0 ].key },
|
| 216 |
+
// { content: newPrompt[ 1 ].value, role: "assistant", key: newPrompt[ 1 ].key }
|
| 217 |
+
// ] );
|
| 218 |
+
|
| 219 |
+
const sendMsg = async () => {
|
| 220 |
+
try {
|
| 221 |
+
|
| 222 |
+
let currentDate = new Date();
|
| 223 |
+
|
| 224 |
+
await insertData( {
|
| 225 |
+
table: "prompts",
|
| 226 |
+
object: {
|
| 227 |
+
author: session?.user.id,
|
| 228 |
+
prompt: newPrompt,
|
| 229 |
+
created_at: `${ currentDate.getDate() }-${ currentDate.toLocaleString( 'default', { month: 'long' } ).substring( 0, 3 ) } ${ currentDate.getFullYear() }`
|
| 230 |
+
}
|
| 231 |
+
} );
|
| 232 |
+
|
| 233 |
+
} catch ( e ) {
|
| 234 |
+
console.log( e );
|
| 235 |
+
} finally {
|
| 236 |
+
setNewPrompt( [] );
|
| 237 |
+
}
|
| 238 |
+
};
|
| 239 |
+
|
| 240 |
+
sendMsg();
|
| 241 |
+
|
| 242 |
+
}
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
}, [ newPrompt ] );
|
| 246 |
+
|
| 247 |
+
const handleTermination = () => {
|
| 248 |
+
// setProcessing( false );
|
| 249 |
+
stop();
|
| 250 |
+
setNewPrompt( [] );
|
| 251 |
+
};
|
| 252 |
+
|
| 253 |
+
const handleInputSubmit = e => {
|
| 254 |
+
if ( e.key == "Enter" && !e.shiftKey && !isLoading && !isMobile ) {
|
| 255 |
+
// e.preventDefault();
|
| 256 |
+
send( e );
|
| 257 |
+
} else if ( isMobile && e.key == "Enter" ) {
|
| 258 |
+
return;
|
| 259 |
+
}
|
| 260 |
+
};
|
| 261 |
+
|
| 262 |
+
const handleInputChange = useCallback( ( e ) => {
|
| 263 |
+
|
| 264 |
+
inputChange( e );
|
| 265 |
+
|
| 266 |
+
e.target.style.height = 'auto';
|
| 267 |
+
e.target.style.height = e.target.scrollHeight + 'px';
|
| 268 |
+
|
| 269 |
+
}, [] );
|
| 270 |
+
|
| 271 |
+
function handleExampleCopy ( e ) {
|
| 272 |
+
let text = e.target.innerText;
|
| 273 |
+
text = [ ...text ];
|
| 274 |
+
|
| 275 |
+
text.pop();
|
| 276 |
+
text.shift();
|
| 277 |
+
text = text.join( "" );
|
| 278 |
+
|
| 279 |
+
navigator.clipboard.writeText( text );
|
| 280 |
+
}
|
| 281 |
+
|
| 282 |
+
function handleBottomButtonClick () {
|
| 283 |
+
msgsRef.current.scrollTo( {
|
| 284 |
+
top: msgsRef.current.scrollHeight,
|
| 285 |
+
behavior: "smooth"
|
| 286 |
+
} );
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
return (
|
| 290 |
+
<>
|
| 291 |
+
{ ( !messages.length && !Msgsloading ) && (
|
| 292 |
+
<>
|
| 293 |
+
<Image
|
| 294 |
+
src={ darkMode ? "/logo.png" : "/logo-dark.png" }
|
| 295 |
+
alt='logo'
|
| 296 |
+
width={ 100 }
|
| 297 |
+
height={ 65 }
|
| 298 |
+
className={ `${ styles[ 'placeholder-img' ] } ${ !darkMode ? styles[ "light" ] : "" }` }
|
| 299 |
+
/>
|
| 300 |
+
<h1 className={ `${ styles[ 'title' ] } ${ !darkMode ? styles[ "light" ] : "" }` }><span className={ styles[ 'highlight' ] }>RayAI:{ " " }</span>Your Personal AI.</h1>
|
| 301 |
+
<div className={ `${ styles[ "examples" ] } ${ !darkMode ? styles[ "light" ] : "" }` }>
|
| 302 |
+
<div className={ styles[ "example" ] }>
|
| 303 |
+
<div className={ styles[ "header" ] }>
|
| 304 |
+
<FontAwesomeIcon className={ styles[ 'example-icon' ] } icon={ faBarsStaggered } />
|
| 305 |
+
<span>Example</span>
|
| 306 |
+
</div>
|
| 307 |
+
<div className={ styles[ "columns" ] }>
|
| 308 |
+
<p className={ styles[ "col" ] } onClick={ handleExampleCopy }>{ `"Tell me about the history of Eiffel Tower."` }</p>
|
| 309 |
+
<p className={ styles[ "col" ] } onClick={ handleExampleCopy }>{ `"Give me information related to EarthQuakes."` }</p>
|
| 310 |
+
<p className={ styles[ "col" ] } onClick={ handleExampleCopy }>{ `"Calculate the derivative of the function : 4x + 9"` }</p>
|
| 311 |
+
</div>
|
| 312 |
+
</div>
|
| 313 |
+
<div className={ styles[ "example" ] }>
|
| 314 |
+
<div className={ styles[ "header" ] }>
|
| 315 |
+
<FontAwesomeIcon className={ styles[ 'example-icon' ] } icon={ faTriangleExclamation } />
|
| 316 |
+
<span>Limitations</span>
|
| 317 |
+
</div>
|
| 318 |
+
<div className={ styles[ "columns" ] }>
|
| 319 |
+
<p className={ styles[ "col" ] }>{ `May Somatimes produce in-accurate Results.` }</p>
|
| 320 |
+
<p className={ styles[ "col" ] }>{ `Might Create Harmful or Biased Content.` }</p>
|
| 321 |
+
<p className={ styles[ "col" ] }>{ `Limited Knowledge.` }</p>
|
| 322 |
+
</div>
|
| 323 |
+
</div>
|
| 324 |
+
</div>
|
| 325 |
+
</>
|
| 326 |
+
) }
|
| 327 |
+
|
| 328 |
+
<div className={ `${ styles[ "msgs" ] } ${ !darkMode ? styles[ "light" ] : "" }` } ref={ msgsRef }>
|
| 329 |
+
{ messages.map( ( m, i, a ) => (
|
| 330 |
+
<>
|
| 331 |
+
<Message id={ m.key } msg={ m } session={ session } key={ i } styles={ styles } />
|
| 332 |
+
|
| 333 |
+
{ ( () => {
|
| 334 |
+
|
| 335 |
+
if ( i == a.length - 1 ) {
|
| 336 |
+
if ( m.role == "user" && isLoading ) {
|
| 337 |
+
return (
|
| 338 |
+
<Message id={ "" } msg={ { content: "...", id: "", role: "assistant" } } session={ session } key={ i + 1 } styles={ styles } />
|
| 339 |
+
);
|
| 340 |
+
}
|
| 341 |
+
}
|
| 342 |
+
|
| 343 |
+
} )() }
|
| 344 |
+
</>
|
| 345 |
+
) ) }
|
| 346 |
+
</div>
|
| 347 |
+
{/* { !isMobile && (
|
| 348 |
+
<button onClick={ handleTermination } className={ `${ styles[ "terminate" ] } ${ isLoading ? styles[ "processing" ] : "" }` }>Terminate...</button>
|
| 349 |
+
)} */}
|
| 350 |
+
{ buttonToBottom && (
|
| 351 |
+
<button onClick={ handleBottomButtonClick } type='button' className={ styles[ "to-bottom" ] }><FontAwesomeIcon icon={ faChevronDown } /></button>
|
| 352 |
+
) }
|
| 353 |
+
<div className={ `${ styles[ "input" ] } ${ !darkMode ? styles[ "light" ] : "" }` }>
|
| 354 |
+
<textarea rows={ 1 } onKeyDown={ handleInputSubmit } type="text" placeholder='Enter Prompt' onInput={ handleInputChange } value={ input } />
|
| 355 |
+
<button type='button' title={ isLoading ? "Terminate" : "Send" } onClick={ !isLoading ? send : handleTermination }>
|
| 356 |
+
{ !isLoading ? (
|
| 357 |
+
<FontAwesomeIcon icon={ faPaperPlane } />
|
| 358 |
+
) : (
|
| 359 |
+
<FontAwesomeIcon icon={ faStop } />
|
| 360 |
+
) }
|
| 361 |
+
</button>
|
| 362 |
+
</div>
|
| 363 |
+
<p className={ styles[ 'note' ] }>Free Research Preview. RayAI may produce inaccurate information about people, places, or facts.</p>
|
| 364 |
+
</>
|
| 365 |
+
);
|
| 366 |
+
};
|
| 367 |
+
|
| 368 |
+
export default memo( Chat );
|
app/Components/Chat/chat.module.css
ADDED
|
@@ -0,0 +1,516 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
h1.title {
|
| 2 |
+
color: rgba(255, 255, 255, 0.2);
|
| 3 |
+
text-align: center;
|
| 4 |
+
font-family: Righteous;
|
| 5 |
+
font-size: 2vw;
|
| 6 |
+
position: absolute;
|
| 7 |
+
top: 15.5vh;
|
| 8 |
+
left: 50%;
|
| 9 |
+
width: 90%;
|
| 10 |
+
transform: translateX(-50%);
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
h1.title.light {
|
| 14 |
+
color: #05858d5c;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
h1.title.light span.highlight {
|
| 18 |
+
color: #05858d5c;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
img.placeholder-img {
|
| 22 |
+
opacity: 0.3;
|
| 23 |
+
position: absolute;
|
| 24 |
+
top: 3.1vh;
|
| 25 |
+
/* Updated from 3.1vh to 6.4vh */
|
| 26 |
+
width: 7.43vw;
|
| 27 |
+
height: auto !important;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
div.msgs {
|
| 31 |
+
/* background: #000; */
|
| 32 |
+
width: 100%;
|
| 33 |
+
height: calc(100% - 20.5vh);
|
| 34 |
+
/* Updated from 7.5vw to 15.5vh */
|
| 35 |
+
overflow-y: auto;
|
| 36 |
+
overflow-x: hidden;
|
| 37 |
+
display: flex;
|
| 38 |
+
flex-direction: column;
|
| 39 |
+
position: relative;
|
| 40 |
+
/* align-items: center; */
|
| 41 |
+
gap: 3.1vh;
|
| 42 |
+
padding: 1.5vw 1.5vw 6vw 1.5vw;
|
| 43 |
+
/* scroll-behavior: smooth; */
|
| 44 |
+
transition: 150ms ease-in-out;
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
div.input {
|
| 48 |
+
display: flex;
|
| 49 |
+
/* position: fixed; */
|
| 50 |
+
bottom: 48px;
|
| 51 |
+
|
| 52 |
+
position: absolute;
|
| 53 |
+
/* margin-bottom: 15.7vh; now*/
|
| 54 |
+
/* Updated from 4.2vw to 8.7vh */
|
| 55 |
+
height: fit-content;
|
| 56 |
+
width: 80%;
|
| 57 |
+
align-items: center;
|
| 58 |
+
justify-content: center;
|
| 59 |
+
transition: 150ms ease-in-out;
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
div.input textarea,
|
| 63 |
+
div.input button {
|
| 64 |
+
outline: none;
|
| 65 |
+
border: none;
|
| 66 |
+
transition: 150ms ease-in-out;
|
| 67 |
+
z-index: 100;
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
div.input textarea {
|
| 71 |
+
position: relative;
|
| 72 |
+
padding: 1.9vh 5.625vw 1.9vh 1.35vw;
|
| 73 |
+
/* Updated padding values */
|
| 74 |
+
min-height: 7.12vh;
|
| 75 |
+
/* Updated from 3.45vw to 7.12vh */
|
| 76 |
+
height: 7.12vh;
|
| 77 |
+
/* Updated from 3.45vw to 7.12vh */
|
| 78 |
+
width: 100%;
|
| 79 |
+
/* bottom: -7.5vh; now */
|
| 80 |
+
/* Updated from 0.375vw to 0.77vh */
|
| 81 |
+
font-family: AbeeZee;
|
| 82 |
+
line-height: 1.6;
|
| 83 |
+
max-height: 20.12vh;
|
| 84 |
+
/* Updated from 9.75vw to 20.12vh */
|
| 85 |
+
box-sizing: border-box;
|
| 86 |
+
resize: none;
|
| 87 |
+
font-family: Abeezee;
|
| 88 |
+
border-radius: .525vw;
|
| 89 |
+
font-size: 1.1vw;
|
| 90 |
+
color: #cbcbcb;
|
| 91 |
+
background: #2a3e43;
|
| 92 |
+
transition: 200ms ease-in-out;
|
| 93 |
+
/* #364057 */
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
div.input.light textarea {
|
| 97 |
+
background: #fff;
|
| 98 |
+
box-shadow: 0 0 2px #b9b9b9;
|
| 99 |
+
color: #474747;
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
div.code-options {
|
| 103 |
+
position: absolute;
|
| 104 |
+
bottom: .3vw;
|
| 105 |
+
left: calc(100% - 2.8vw);
|
| 106 |
+
display: none;
|
| 107 |
+
transition: 150ms ease-in-out;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
div.markdown-content pre:hover div.code-options {
|
| 111 |
+
display: inline-block;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
div.code-options > * {
|
| 115 |
+
padding: .6vw;
|
| 116 |
+
cursor: pointer;
|
| 117 |
+
border-radius: .35vw;
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
div.code-options > *:hover {
|
| 121 |
+
background: #cde5eb;
|
| 122 |
+
color: #474747;
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
+
button.terminate {
|
| 126 |
+
position: absolute;
|
| 127 |
+
bottom: 5vw;
|
| 128 |
+
transition: 200ms ease-in-out;
|
| 129 |
+
border: none;
|
| 130 |
+
padding: .9vw 5vw;
|
| 131 |
+
cursor: pointer;
|
| 132 |
+
border-radius: .4vw;
|
| 133 |
+
color: white;
|
| 134 |
+
opacity: 0;
|
| 135 |
+
background: linear-gradient(108deg, #052437 -7.56%, #14507d 29.51%, #47a2a5 69.57%, #bcf7ff 107.24%);
|
| 136 |
+
}
|
| 137 |
+
|
| 138 |
+
button.terminate.processing {
|
| 139 |
+
bottom: 11vw;
|
| 140 |
+
opacity: 1;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
button.terminate:hover {
|
| 144 |
+
transform: scale(1.04);
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
div.input button {
|
| 148 |
+
height: 6.51vh;
|
| 149 |
+
/* Updated from 3.15vw to 6.51vh */
|
| 150 |
+
width: 3.15vw;
|
| 151 |
+
position: absolute;
|
| 152 |
+
right: 1.5vw;
|
| 153 |
+
background: transparent;
|
| 154 |
+
cursor: pointer;
|
| 155 |
+
font-size: 1.6vw;
|
| 156 |
+
/* Updated from 1.6vw to 3.29vh */
|
| 157 |
+
color: #dadada;
|
| 158 |
+
/* bottom: -7.5vh; */
|
| 159 |
+
/* Updated from 0.375vw to 0.77vh */
|
| 160 |
+
}
|
| 161 |
+
|
| 162 |
+
div.input.light button {
|
| 163 |
+
color: #18868d;
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
p.note {
|
| 167 |
+
position: absolute;
|
| 168 |
+
bottom: 3.72vh;
|
| 169 |
+
/* Updated from 1.8vw to 3.72vh */
|
| 170 |
+
font-size: .83vw;
|
| 171 |
+
font-family: Quicksand;
|
| 172 |
+
color: #cbcbcb;
|
| 173 |
+
width: 80%;
|
| 174 |
+
text-align: center;
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
div.examples {
|
| 178 |
+
position: absolute;
|
| 179 |
+
top: calc(50%);
|
| 180 |
+
transform: translateY(-50%);
|
| 181 |
+
display: flex;
|
| 182 |
+
flex-direction: row;
|
| 183 |
+
width: calc(100% - 35.5vw);
|
| 184 |
+
/* Updated from 35.5vw to 73.63vh */
|
| 185 |
+
gap: 3vw;
|
| 186 |
+
/* Updated from 3vw to 6.21vh */
|
| 187 |
+
transition: 150ms;
|
| 188 |
+
z-index: 100;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
div.example {
|
| 192 |
+
background: #ffffff05;
|
| 193 |
+
border: 1px solid #365057;
|
| 194 |
+
border-radius: 1.1247vw;
|
| 195 |
+
display: flex;
|
| 196 |
+
flex-direction: column;
|
| 197 |
+
gap: 2.42vh;
|
| 198 |
+
padding: 1.12vw;
|
| 199 |
+
color: #bfbfbf;
|
| 200 |
+
font-family: Quicksand;
|
| 201 |
+
width: 100%;
|
| 202 |
+
transition: 150ms;
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
div.examples.light div.example {
|
| 206 |
+
background: #fff;
|
| 207 |
+
/* border-color: #dee7e9; */
|
| 208 |
+
border: none;
|
| 209 |
+
color: #676767;
|
| 210 |
+
box-shadow: 0 0 5px #e9e9e9;
|
| 211 |
+
}
|
| 212 |
+
|
| 213 |
+
div.header {
|
| 214 |
+
color: #eee;
|
| 215 |
+
display: flex;
|
| 216 |
+
flex-direction: row;
|
| 217 |
+
gap: 1vw;
|
| 218 |
+
align-items: center;
|
| 219 |
+
font-size: 1.4vw;
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
div.header .example-icon {
|
| 223 |
+
padding: .55vw;
|
| 224 |
+
background: #18868d;
|
| 225 |
+
border-radius: .5vw;
|
| 226 |
+
}
|
| 227 |
+
|
| 228 |
+
div.examples.light div.example div.header .example-icon {
|
| 229 |
+
color: #18868d;
|
| 230 |
+
background: white;
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
div.columns {
|
| 234 |
+
display: flex;
|
| 235 |
+
flex-direction: column;
|
| 236 |
+
gap: 1.55vh;
|
| 237 |
+
/* Updated from 0.75vw to 1.55vh */
|
| 238 |
+
}
|
| 239 |
+
|
| 240 |
+
div.msgs.light div.user,
|
| 241 |
+
div.msgs.light div.ai {
|
| 242 |
+
border-color: #c9e0df;
|
| 243 |
+
background: #def7f352;
|
| 244 |
+
color: #254a4d;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
div.msgs div.markdown-content > pre {
|
| 248 |
+
position: relative;
|
| 249 |
+
}
|
| 250 |
+
|
| 251 |
+
div.msgs.light div.markdown-content > pre > pre {
|
| 252 |
+
border: 1px solid #e8ebec;
|
| 253 |
+
transition: 150ms ease-in-out;
|
| 254 |
+
}
|
| 255 |
+
|
| 256 |
+
div.examples.light div.example div.header {
|
| 257 |
+
color: #18868d;
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
div.columns p.col {
|
| 261 |
+
padding: .891vw;
|
| 262 |
+
border-radius: .586vw;
|
| 263 |
+
background: #ffffff15;
|
| 264 |
+
font-size: .935vw;
|
| 265 |
+
cursor: pointer;
|
| 266 |
+
transition: 200ms ease-in-out;
|
| 267 |
+
}
|
| 268 |
+
|
| 269 |
+
div.columns p.col:hover {
|
| 270 |
+
transform: scale(1.04);
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
div.markdown-content,
|
| 274 |
+
div.markdown-content * {
|
| 275 |
+
white-space: pre-wrap;
|
| 276 |
+
line-height: 1.7;
|
| 277 |
+
}
|
| 278 |
+
|
| 279 |
+
div.ai .text-pic,
|
| 280 |
+
div.user .text-pic {
|
| 281 |
+
width: 2.7vw;
|
| 282 |
+
height: 2.7vw;
|
| 283 |
+
position: absolute;
|
| 284 |
+
top: 2.8vh;
|
| 285 |
+
border-radius: .5vw;
|
| 286 |
+
}
|
| 287 |
+
|
| 288 |
+
div.ai .text-pic {
|
| 289 |
+
left: -1vw;
|
| 290 |
+
}
|
| 291 |
+
|
| 292 |
+
div.user .text-pic {
|
| 293 |
+
left: calc(100% - 1.8vw);
|
| 294 |
+
}
|
| 295 |
+
|
| 296 |
+
div.user,
|
| 297 |
+
div.ai {
|
| 298 |
+
font-family: abeezee;
|
| 299 |
+
font-size: 1vw;
|
| 300 |
+
background: #5656563c;
|
| 301 |
+
max-width: 55%;
|
| 302 |
+
border: #365057 1px solid;
|
| 303 |
+
display: flex;
|
| 304 |
+
color: #bebebe;
|
| 305 |
+
flex-direction: row;
|
| 306 |
+
/* width: calc(100% - 1.8vw); */
|
| 307 |
+
width: fit-content;
|
| 308 |
+
position: relative;
|
| 309 |
+
transition: 200ms ease-in-out;
|
| 310 |
+
}
|
| 311 |
+
|
| 312 |
+
div.ai {
|
| 313 |
+
left: .8vw;
|
| 314 |
+
padding: 2vw 2vw 2vw 3vw;
|
| 315 |
+
border-radius: 1.4vw 2vw .4vw 1.4vw;
|
| 316 |
+
}
|
| 317 |
+
|
| 318 |
+
div.user {
|
| 319 |
+
position: relative;
|
| 320 |
+
/* setting the left property in Message.jsx (from js) */
|
| 321 |
+
padding: 2vw 3vw 2vw 2vw;
|
| 322 |
+
opacity: 0;
|
| 323 |
+
border-radius: 2vw 1.4vw 1.4vw .4vw;
|
| 324 |
+
transition: 150ms ease-in-out;
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
button.to-bottom {
|
| 328 |
+
position: fixed;
|
| 329 |
+
bottom: 25vh;
|
| 330 |
+
right: 8vw;
|
| 331 |
+
height: 3vw;
|
| 332 |
+
font-size: 1.1vw;
|
| 333 |
+
width: 3vw;
|
| 334 |
+
border: none;
|
| 335 |
+
cursor: pointer;
|
| 336 |
+
outline: none;
|
| 337 |
+
border-radius: 50%;
|
| 338 |
+
color: #254a4d;
|
| 339 |
+
transition: 150ms ease-out;
|
| 340 |
+
}
|
| 341 |
+
|
| 342 |
+
button.to-bottom:hover {
|
| 343 |
+
transform: scale(1.1);
|
| 344 |
+
}
|
| 345 |
+
|
| 346 |
+
@keyframes msg {
|
| 347 |
+
0% {
|
| 348 |
+
height: 0;
|
| 349 |
+
}
|
| 350 |
+
|
| 351 |
+
100% {
|
| 352 |
+
height: auto;
|
| 353 |
+
}
|
| 354 |
+
}
|
| 355 |
+
|
| 356 |
+
@media (max-width: 768px) {
|
| 357 |
+
div.msgs {
|
| 358 |
+
/* background: #000; */
|
| 359 |
+
width: 100%;
|
| 360 |
+
height: calc(100vh - 220px);
|
| 361 |
+
top: 20px;
|
| 362 |
+
/* Updated from 7.5vw to 15.5vh */
|
| 363 |
+
gap: 20px;
|
| 364 |
+
padding: 7px 7px 14px 7px;
|
| 365 |
+
/* scroll-behavior: smooth; */
|
| 366 |
+
transition: 150ms ease-in-out;
|
| 367 |
+
}
|
| 368 |
+
|
| 369 |
+
div.input {
|
| 370 |
+
display: flex;
|
| 371 |
+
position: absolute;
|
| 372 |
+
margin: 0;
|
| 373 |
+
bottom: 90px;
|
| 374 |
+
/* Updated from 4.2vw to 8.7vh */
|
| 375 |
+
height: fit-content;
|
| 376 |
+
width: 83%;
|
| 377 |
+
align-items: center;
|
| 378 |
+
justify-content: center;
|
| 379 |
+
transition: 150ms ease-in-out;
|
| 380 |
+
}
|
| 381 |
+
|
| 382 |
+
div.input textarea,
|
| 383 |
+
div.input button {
|
| 384 |
+
outline: none;
|
| 385 |
+
border: none;
|
| 386 |
+
transition: 150ms ease-in-out;
|
| 387 |
+
z-index: 100;
|
| 388 |
+
}
|
| 389 |
+
|
| 390 |
+
div.input textarea {
|
| 391 |
+
position: relative;
|
| 392 |
+
padding: 6px 53px 6px 13px;
|
| 393 |
+
/* Updated padding values */
|
| 394 |
+
min-height: 29px;
|
| 395 |
+
/* Updated from 3.45vw to 7.12vh */
|
| 396 |
+
height: 29px;
|
| 397 |
+
/* Updated from 3.45vw to 7.12vh */
|
| 398 |
+
width: 100%;
|
| 399 |
+
bottom: 0;
|
| 400 |
+
/* Updated from 0.375vw to 0.77vh */
|
| 401 |
+
font-family: AbeeZee;
|
| 402 |
+
line-height: 1.6;
|
| 403 |
+
max-height: 150px;
|
| 404 |
+
/* Updated from 9.75vw to 20.12vh */
|
| 405 |
+
box-sizing: border-box;
|
| 406 |
+
resize: none;
|
| 407 |
+
font-family: Abeezee;
|
| 408 |
+
border-radius: 5px;
|
| 409 |
+
font-size: 12px;
|
| 410 |
+
color: #cbcbcb;
|
| 411 |
+
background: #2a3e43;
|
| 412 |
+
/* #364057 */
|
| 413 |
+
overflow: hidden;
|
| 414 |
+
}
|
| 415 |
+
|
| 416 |
+
div.input.light textarea {
|
| 417 |
+
background: #fff;
|
| 418 |
+
box-shadow: 0 0 2px #b9b9b9;
|
| 419 |
+
color: #474747;
|
| 420 |
+
}
|
| 421 |
+
|
| 422 |
+
div.input button {
|
| 423 |
+
height: 29px;
|
| 424 |
+
/* Updated from 3.15vw to 6.51vh */
|
| 425 |
+
width: 29px;
|
| 426 |
+
position: absolute;
|
| 427 |
+
right: 10px;
|
| 428 |
+
background: transparent;
|
| 429 |
+
cursor: pointer;
|
| 430 |
+
font-size: 12px;
|
| 431 |
+
/* Updated from 1.6vw to 3.29vh */
|
| 432 |
+
color: #dadada;
|
| 433 |
+
bottom: 0;
|
| 434 |
+
/* Updated from 0.375vw to 0.77vh */
|
| 435 |
+
}
|
| 436 |
+
|
| 437 |
+
div.ai .text-pic,
|
| 438 |
+
div.user .text-pic {
|
| 439 |
+
width: 20px;
|
| 440 |
+
height: 20px;
|
| 441 |
+
position: absolute;
|
| 442 |
+
top: 11px;
|
| 443 |
+
border-radius: 6px;
|
| 444 |
+
}
|
| 445 |
+
|
| 446 |
+
div.ai .text-pic {
|
| 447 |
+
left: -10px;
|
| 448 |
+
}
|
| 449 |
+
|
| 450 |
+
div.user .text-pic {
|
| 451 |
+
left: calc(100% - 12px);
|
| 452 |
+
}
|
| 453 |
+
|
| 454 |
+
div.user,
|
| 455 |
+
div.ai {
|
| 456 |
+
font-size: 12px;
|
| 457 |
+
border-radius: 10px;
|
| 458 |
+
border: #365057 1px solid;
|
| 459 |
+
color: #bebebe;
|
| 460 |
+
width: fit-content;
|
| 461 |
+
max-width: calc(100% - 20px);
|
| 462 |
+
position: relative;
|
| 463 |
+
transition: 200ms ease-in-out;
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
div.ai {
|
| 467 |
+
left: 8px;
|
| 468 |
+
padding: 10px 10px 10px 23px;
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
div.user {
|
| 472 |
+
position: relative;
|
| 473 |
+
/* setting the left property in Message.jsx (from js) */
|
| 474 |
+
padding: 10px 23px 10px 10px;
|
| 475 |
+
opacity: 0;
|
| 476 |
+
transition: 150ms ease-in-out;
|
| 477 |
+
}
|
| 478 |
+
|
| 479 |
+
/* .text-pic {
|
| 480 |
+
width: 20px;
|
| 481 |
+
height: 20px;
|
| 482 |
+
position: absolute;
|
| 483 |
+
left: -10px;
|
| 484 |
+
top: 11px;
|
| 485 |
+
border-radius: .5vw;
|
| 486 |
+
} */
|
| 487 |
+
|
| 488 |
+
button.terminate {
|
| 489 |
+
position: absolute;
|
| 490 |
+
bottom: -30px;
|
| 491 |
+
transition: 200ms ease-in-out;
|
| 492 |
+
border: none;
|
| 493 |
+
width: 120px;
|
| 494 |
+
height: 28px;
|
| 495 |
+
font-size: 11px;
|
| 496 |
+
border-radius: 5px;
|
| 497 |
+
color: white;
|
| 498 |
+
border: 2px solid;
|
| 499 |
+
background: none;
|
| 500 |
+
opacity: 0;
|
| 501 |
+
border-image: linear-gradient(108deg, #052437 -7.56%, #14507d 29.51%, #47a2a5 69.57%, #bcf7ff 107.24%) 1;
|
| 502 |
+
}
|
| 503 |
+
|
| 504 |
+
button.terminate.processing {
|
| 505 |
+
bottom: 80px;
|
| 506 |
+
opacity: 1;
|
| 507 |
+
}
|
| 508 |
+
|
| 509 |
+
p.note {
|
| 510 |
+
position: fixed;
|
| 511 |
+
bottom: 70px;
|
| 512 |
+
/* Updated from 1.8vw to 3.72vh */
|
| 513 |
+
font-size: 6px;
|
| 514 |
+
width: 85%;
|
| 515 |
+
}
|
| 516 |
+
}
|
app/Components/MarkdownRenderer/MarkdownRenderer.jsx
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
|
| 3 |
+
import { useTheme } from '@/app/Contexts/ThemeContext/ThemeContext';
|
| 4 |
+
import { faCopy as copyRegular } from '@fortawesome/free-regular-svg-icons';
|
| 5 |
+
import { faCopy as copySolid } from '@fortawesome/free-solid-svg-icons';
|
| 6 |
+
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
| 7 |
+
import { memo, useRef, useState } from 'react';
|
| 8 |
+
import ReactMarkdown from 'react-markdown';
|
| 9 |
+
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
|
| 10 |
+
import { atomDark, oneLight } from 'react-syntax-highlighter/dist/cjs/styles/prism';
|
| 11 |
+
|
| 12 |
+
const MarkdownRenderer = ( { text, className, optionsClassName = "" } ) => {
|
| 13 |
+
|
| 14 |
+
const { darkMode } = useTheme();
|
| 15 |
+
const [ copied, setCopied ] = useState( false );
|
| 16 |
+
|
| 17 |
+
return (
|
| 18 |
+
<div className={ className }>
|
| 19 |
+
<ReactMarkdown components={ {
|
| 20 |
+
code ( { node, inline, className, children, ...props } ) {
|
| 21 |
+
const match = /language-(\w+)/.exec( className || "" );
|
| 22 |
+
return match ? (
|
| 23 |
+
<>
|
| 24 |
+
<SyntaxHighlighter
|
| 25 |
+
children={ String( children ).replace( /\n$/, "" ) }
|
| 26 |
+
language={ match[ 1 ] }
|
| 27 |
+
style={ darkMode ? atomDark : oneLight }
|
| 28 |
+
{ ...props }
|
| 29 |
+
/>
|
| 30 |
+
<div className={ optionsClassName }>
|
| 31 |
+
<FontAwesomeIcon onClick={ ( e ) => {
|
| 32 |
+
if ( !copied ) {
|
| 33 |
+
navigator.clipboard.writeText( e.target.parentNode.previousSibling?.innerText );
|
| 34 |
+
setCopied( true );
|
| 35 |
+
let timeOut = setTimeout( () => {
|
| 36 |
+
setCopied( false );
|
| 37 |
+
clearTimeout( timeOut );
|
| 38 |
+
}, 2000 );
|
| 39 |
+
}
|
| 40 |
+
} } icon={ copied ? copySolid : copyRegular } />
|
| 41 |
+
</div>
|
| 42 |
+
</>
|
| 43 |
+
) : (
|
| 44 |
+
<>
|
| 45 |
+
<code className={ className } { ...props }>
|
| 46 |
+
{ children }
|
| 47 |
+
</code>
|
| 48 |
+
</>
|
| 49 |
+
);
|
| 50 |
+
},
|
| 51 |
+
} }>
|
| 52 |
+
{ text }
|
| 53 |
+
</ReactMarkdown>
|
| 54 |
+
</div>
|
| 55 |
+
);
|
| 56 |
+
};
|
| 57 |
+
|
| 58 |
+
export default memo( MarkdownRenderer );
|
app/Components/Message/Message.jsx
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { memo, useRef } from 'react';
|
| 2 |
+
import MarkdownRenderer from '../MarkdownRenderer/MarkdownRenderer';
|
| 3 |
+
import Image from 'next/image';
|
| 4 |
+
import { isMobileDevice } from '@/app/Contexts/IsMobileContext/IsMobileContext';
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
const Message = ( { msg, session, styles, onClick = () => { }, id } ) => {
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
const { isMobile } = isMobileDevice();
|
| 11 |
+
|
| 12 |
+
return (
|
| 13 |
+
<div className={ msg.role == "user" ? styles[ "user" ] : styles[ "ai" ] }
|
| 14 |
+
onLoad={ ( e ) => {
|
| 15 |
+
if ( msg.role == "user" ) {
|
| 16 |
+
e.currentTarget.style.left = !isMobile ? `calc(100% - ${ ( e.currentTarget.offsetWidth / window.innerWidth ) * 100 }vw - .8vw )` : `calc( 100% - ${ ( e.currentTarget.offsetWidth ) }px - 5px)`;
|
| 17 |
+
e.currentTarget.style.opacity = 1;
|
| 18 |
+
}
|
| 19 |
+
} }
|
| 20 |
+
style={ {
|
| 21 |
+
animation: "msg ease-in-out 2s 1",
|
| 22 |
+
} }
|
| 23 |
+
id={ id || msg.key }
|
| 24 |
+
onClick={ onClick }
|
| 25 |
+
>
|
| 26 |
+
<Image
|
| 27 |
+
src={ msg.role.toLowerCase() != "user" ? "/RayAI.svg" : session?.user.image }
|
| 28 |
+
alt='img'
|
| 29 |
+
width={ 50 }
|
| 30 |
+
height={ 50 }
|
| 31 |
+
className={ styles[ 'text-pic' ] }
|
| 32 |
+
/>
|
| 33 |
+
{/* <p key={ key } className={ styles[ "msg" ] }>{ marked( msg.content ) }</p> */ }
|
| 34 |
+
<MarkdownRenderer text={ msg.content } optionsClassName={ styles[ "code-options" ] } className={ styles[ "markdown-content" ] } />
|
| 35 |
+
|
| 36 |
+
</div>
|
| 37 |
+
);
|
| 38 |
+
};
|
| 39 |
+
|
| 40 |
+
export default memo( Message );
|
app/Components/ToggleButton/ToggleButton.jsx
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import React from 'react';
|
| 2 |
+
import styles from "./ToggleButton.module.css";
|
| 3 |
+
|
| 4 |
+
const ToggleButton = ( { checked = true, className = "", ...props } ) => {
|
| 5 |
+
return (
|
| 6 |
+
<label className={ `${ styles[ "switch" ] } ${ className }` }>
|
| 7 |
+
<input type="checkbox" checked={ checked } { ...props } />
|
| 8 |
+
<span className={ styles[ "slider" ] }></span>
|
| 9 |
+
</label>
|
| 10 |
+
);
|
| 11 |
+
};
|
| 12 |
+
|
| 13 |
+
export default ToggleButton;
|
app/Components/ToggleButton/ToggleButton.module.css
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
label.switch {
|
| 2 |
+
position: relative;
|
| 3 |
+
display: inline-block;
|
| 4 |
+
width: 3.5vw;
|
| 5 |
+
height: 4.5vh;
|
| 6 |
+
}
|
| 7 |
+
|
| 8 |
+
label.switch input {
|
| 9 |
+
opacity: 0;
|
| 10 |
+
width: 0;
|
| 11 |
+
height: 0;
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
span.slider {
|
| 15 |
+
position: absolute;
|
| 16 |
+
cursor: pointer;
|
| 17 |
+
top: 0;
|
| 18 |
+
left: 0;
|
| 19 |
+
right: 0;
|
| 20 |
+
bottom: 0;
|
| 21 |
+
background-color: #ccc;
|
| 22 |
+
-webkit-transition: .4s;
|
| 23 |
+
transition: .4s;
|
| 24 |
+
border-radius: 34px;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
.slider:before {
|
| 28 |
+
position: absolute;
|
| 29 |
+
content: "";
|
| 30 |
+
height: 4.2vh;
|
| 31 |
+
width: 4.2vh;
|
| 32 |
+
left: .05vw;
|
| 33 |
+
bottom: .2vh;
|
| 34 |
+
background-color: white;
|
| 35 |
+
-webkit-transition: .4s;
|
| 36 |
+
transition: .4s;
|
| 37 |
+
border-radius: 50%;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
input:checked + .slider {
|
| 41 |
+
background-color: #23bca6;
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
input:focus + .slider {
|
| 45 |
+
box-shadow: 0 0 1px #0a9290;
|
| 46 |
+
}
|
| 47 |
+
|
| 48 |
+
input:checked + .slider:before {
|
| 49 |
+
-webkit-transform: translateX(1.4vw);
|
| 50 |
+
-ms-transform: translateX(1.4vw);
|
| 51 |
+
transform: translateX(1.4vw);
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
@media (max-width: 767px) {
|
| 55 |
+
label.switch {
|
| 56 |
+
width: 35px;
|
| 57 |
+
height: 20px;
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
.slider:before {
|
| 61 |
+
height: 17px;
|
| 62 |
+
width: 17px;
|
| 63 |
+
left: 1px;
|
| 64 |
+
bottom: 1.5px;
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
input:checked + .slider:before {
|
| 68 |
+
-webkit-transform: translateX(17px);
|
| 69 |
+
-ms-transform: translateX(17px);
|
| 70 |
+
transform: translateX(17px);
|
| 71 |
+
}
|
| 72 |
+
}
|
app/Contexts/IsMobileContext/IsMobileContext.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
import { createContext, useContext, useEffect, useState } from 'react';
|
| 3 |
+
|
| 4 |
+
const IsMobileContext = createContext();
|
| 5 |
+
|
| 6 |
+
export const isMobileDevice = () => {
|
| 7 |
+
return useContext( IsMobileContext );
|
| 8 |
+
};
|
| 9 |
+
|
| 10 |
+
const IsMobileProvider = ( { children } ) => {
|
| 11 |
+
|
| 12 |
+
const [ isMobile, setIsMobile ] = useState( true );
|
| 13 |
+
|
| 14 |
+
return (
|
| 15 |
+
<IsMobileContext.Provider value={ { isMobile, setIsMobile } }>{ children }</IsMobileContext.Provider>
|
| 16 |
+
);
|
| 17 |
+
};
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
const toggleNavContext = createContext();
|
| 21 |
+
|
| 22 |
+
export const toggleNavDevice = () => {
|
| 23 |
+
return useContext( toggleNavContext );
|
| 24 |
+
};
|
| 25 |
+
|
| 26 |
+
export const ToggleNavProvider = ( { children } ) => {
|
| 27 |
+
|
| 28 |
+
const [ toggleNav, setToggleNav ] = useState( false );
|
| 29 |
+
|
| 30 |
+
return (
|
| 31 |
+
<toggleNavContext.Provider value={ { toggleNav, setToggleNav } }>{ children }</toggleNavContext.Provider>
|
| 32 |
+
);
|
| 33 |
+
};
|
| 34 |
+
|
| 35 |
+
export default IsMobileProvider;
|
app/Contexts/MessagesContext/MessagesContext.jsx
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
import { getUser } from '@/Provider/Provider';
|
| 3 |
+
import { getData } from '@/app/Supabase/Supabase';
|
| 4 |
+
import { createContext, useContext, useEffect, useState } from 'react';
|
| 5 |
+
|
| 6 |
+
const MessagesContext = createContext();
|
| 7 |
+
|
| 8 |
+
export const useMessages = () => {
|
| 9 |
+
return useContext( MessagesContext );
|
| 10 |
+
};
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
function* convertArray ( inputArray ) {
|
| 14 |
+
// const outputArray = [];
|
| 15 |
+
|
| 16 |
+
for ( const [ user, assistant ] of inputArray ) {
|
| 17 |
+
const userValue = user.value;
|
| 18 |
+
const assistantValue = assistant.value;
|
| 19 |
+
|
| 20 |
+
if ( userValue.trim().length && assistantValue.trim().length ) {
|
| 21 |
+
// outputArray.push(
|
| 22 |
+
yield { content: userValue, role: "user", key: user.key };
|
| 23 |
+
yield { content: assistantValue, role: "assistant", key: assistant.key };
|
| 24 |
+
// );
|
| 25 |
+
}
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
// return outputArray;
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
const MessagesProvider = ( { children } ) => {
|
| 33 |
+
|
| 34 |
+
const [ messages, setMessages ] = useState( [] );
|
| 35 |
+
const [ Msgsloading, setMsgsLoading ] = useState( true );
|
| 36 |
+
|
| 37 |
+
useEffect( () => {
|
| 38 |
+
|
| 39 |
+
const fetchMessages = async () => {
|
| 40 |
+
|
| 41 |
+
let { session, signedIn } = await getUser();
|
| 42 |
+
if ( signedIn ) {
|
| 43 |
+
|
| 44 |
+
try {
|
| 45 |
+
|
| 46 |
+
let { data: prompts } = await getData( {
|
| 47 |
+
table: "prompts",
|
| 48 |
+
columns: "prompt",
|
| 49 |
+
orderBy: {
|
| 50 |
+
property: "id",
|
| 51 |
+
ascending: true
|
| 52 |
+
},
|
| 53 |
+
where: {
|
| 54 |
+
author: `${ session.user.id }`
|
| 55 |
+
}
|
| 56 |
+
} );
|
| 57 |
+
|
| 58 |
+
if ( prompts.length ) {
|
| 59 |
+
console.time( "start" );
|
| 60 |
+
setMessages( [ ...convertArray( prompts.map( prompt => prompt.prompt ) ) ] );
|
| 61 |
+
console.timeEnd( "start" );
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
} catch ( e ) {
|
| 65 |
+
console.log( e );
|
| 66 |
+
} finally {
|
| 67 |
+
setMsgsLoading( false );
|
| 68 |
+
}
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
};
|
| 72 |
+
|
| 73 |
+
fetchMessages();
|
| 74 |
+
|
| 75 |
+
}, [] );
|
| 76 |
+
|
| 77 |
+
return (
|
| 78 |
+
<MessagesContext.Provider value={ { messages, setMessages, Msgsloading } }>{ children }</MessagesContext.Provider>
|
| 79 |
+
);
|
| 80 |
+
};
|
| 81 |
+
|
| 82 |
+
export default MessagesProvider;
|
app/Contexts/ThemeContext/ThemeContext.jsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client";
|
| 2 |
+
import React, { createContext, useContext, useEffect, useState } from 'react';
|
| 3 |
+
|
| 4 |
+
const ThemeContext = createContext();
|
| 5 |
+
|
| 6 |
+
export const useTheme = () => {
|
| 7 |
+
return useContext( ThemeContext );
|
| 8 |
+
};
|
| 9 |
+
|
| 10 |
+
const ThemeProvider = ( { children } ) => {
|
| 11 |
+
|
| 12 |
+
const [ darkMode, setDarkMode ] = useState();
|
| 13 |
+
|
| 14 |
+
useEffect( () => {
|
| 15 |
+
const storedDarkMode = JSON.parse( localStorage.getItem( "darkMode" ) );
|
| 16 |
+
|
| 17 |
+
if ( storedDarkMode && "darkMode" in storedDarkMode ) {
|
| 18 |
+
setDarkMode( storedDarkMode.darkMode );
|
| 19 |
+
console.log( storedDarkMode );
|
| 20 |
+
} else {
|
| 21 |
+
setDarkMode( true );
|
| 22 |
+
console.log( storedDarkMode );
|
| 23 |
+
}
|
| 24 |
+
}, [] );
|
| 25 |
+
|
| 26 |
+
|
| 27 |
+
useEffect( () => {
|
| 28 |
+
const rootStyles = getComputedStyle( document.documentElement );
|
| 29 |
+
const getProp = rootStyles.getPropertyValue.bind( rootStyles );
|
| 30 |
+
|
| 31 |
+
if ( darkMode != undefined && darkMode != null && typeof darkMode != "undefined" ) localStorage.setItem( "darkMode", JSON.stringify( { darkMode } ) );
|
| 32 |
+
|
| 33 |
+
if ( darkMode ) {
|
| 34 |
+
document.body.classList.remove( "lightMode" );
|
| 35 |
+
document.documentElement.style.setProperty( "--top-left", getProp( "--top-left-dark" ) );
|
| 36 |
+
document.documentElement.style.setProperty( "--mid-left", getProp( "--mid-left-dark" ) );
|
| 37 |
+
document.documentElement.style.setProperty( "--center", getProp( "--center-dark" ) );
|
| 38 |
+
document.documentElement.style.setProperty( "--top-right", getProp( "--top-right-dark" ) );
|
| 39 |
+
document.documentElement.style.setProperty( "--bottom-right", getProp( "--bottom-right-dark" ) );
|
| 40 |
+
} else {
|
| 41 |
+
document.body.classList.add( "lightMode" );
|
| 42 |
+
document.documentElement.style.setProperty( "--top-left", getProp( "--top-left-light" ) );
|
| 43 |
+
document.documentElement.style.setProperty( "--mid-left", getProp( "--mid-left-light" ) );
|
| 44 |
+
document.documentElement.style.setProperty( "--center", getProp( "--center-light" ) );
|
| 45 |
+
document.documentElement.style.setProperty( "--top-right", getProp( "--top-right-light" ) );
|
| 46 |
+
document.documentElement.style.setProperty( "--bottom-right", getProp( "--bottom-right-light" ) );
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
}, [ darkMode ] );
|
| 50 |
+
|
| 51 |
+
const toggleDarkMode = () => {
|
| 52 |
+
setDarkMode( prev => !prev );
|
| 53 |
+
};
|
| 54 |
+
|
| 55 |
+
return (
|
| 56 |
+
<ThemeContext.Provider value={ { darkMode, toggleDarkMode } }>{ children }</ThemeContext.Provider>
|
| 57 |
+
);
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
export default ThemeProvider;
|
app/Supabase/Supabase.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createClient } from '@supabase/supabase-js';
|
| 2 |
+
|
| 3 |
+
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
|
| 4 |
+
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY;
|
| 5 |
+
|
| 6 |
+
export const supabase = createClient(supabaseUrl, supabaseKey, {
|
| 7 |
+
auth: { persistSession: false }
|
| 8 |
+
});
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
export const getData = async ({
|
| 13 |
+
table,
|
| 14 |
+
range,
|
| 15 |
+
columns = [],
|
| 16 |
+
where = {},
|
| 17 |
+
contains = {},
|
| 18 |
+
orderBy = {
|
| 19 |
+
property: 'id',
|
| 20 |
+
ascending: false
|
| 21 |
+
}
|
| 22 |
+
}) => {
|
| 23 |
+
|
| 24 |
+
try {
|
| 25 |
+
|
| 26 |
+
if (Array.isArray(columns)) {
|
| 27 |
+
columns = columns.join(",");
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
let Data = supabase
|
| 31 |
+
.from(table)
|
| 32 |
+
.select(columns)
|
| 33 |
+
.match(where)
|
| 34 |
+
.order(orderBy.property, { ascending: orderBy.ascending });
|
| 35 |
+
|
| 36 |
+
if (range && range.length === 2) {
|
| 37 |
+
Data.range(range[0], range[1]);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
if (Object.keys(contains).length) {
|
| 41 |
+
for (let key in contains) {
|
| 42 |
+
Data.ilike(key, `%${contains[key].join("%")}%`);
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
Data = await Data;
|
| 47 |
+
|
| 48 |
+
return { data: Data.data, statusText: Data.statusText, error: Data.error };
|
| 49 |
+
|
| 50 |
+
} catch (error) {
|
| 51 |
+
|
| 52 |
+
console.log(error);
|
| 53 |
+
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
return false;
|
| 57 |
+
|
| 58 |
+
};
|
| 59 |
+
|
| 60 |
+
export const insertData = async ({
|
| 61 |
+
table,
|
| 62 |
+
object
|
| 63 |
+
}) => {
|
| 64 |
+
|
| 65 |
+
try {
|
| 66 |
+
|
| 67 |
+
const { data, error, statusText } = await supabase
|
| 68 |
+
.from(table)
|
| 69 |
+
.insert(object)
|
| 70 |
+
.select();
|
| 71 |
+
|
| 72 |
+
return { data, error, statusText };
|
| 73 |
+
|
| 74 |
+
} catch (error) {
|
| 75 |
+
|
| 76 |
+
console.log(error);
|
| 77 |
+
|
| 78 |
+
}
|
| 79 |
+
|
| 80 |
+
return false;
|
| 81 |
+
|
| 82 |
+
};
|
| 83 |
+
|
| 84 |
+
export const updateData = async ({
|
| 85 |
+
table,
|
| 86 |
+
object,
|
| 87 |
+
where
|
| 88 |
+
}) => {
|
| 89 |
+
|
| 90 |
+
try {
|
| 91 |
+
|
| 92 |
+
let Data = await supabase
|
| 93 |
+
.from(table)
|
| 94 |
+
.update(object)
|
| 95 |
+
.match(where);
|
| 96 |
+
|
| 97 |
+
|
| 98 |
+
return Data.data;
|
| 99 |
+
|
| 100 |
+
} catch (error) {
|
| 101 |
+
|
| 102 |
+
console.log(error);
|
| 103 |
+
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
return false;
|
| 107 |
+
|
| 108 |
+
};
|
| 109 |
+
|
| 110 |
+
export const exists = async ({
|
| 111 |
+
table,
|
| 112 |
+
where,
|
| 113 |
+
columns = []
|
| 114 |
+
}) => {
|
| 115 |
+
try {
|
| 116 |
+
|
| 117 |
+
if (Array.isArray(columns)) {
|
| 118 |
+
columns = columns.join(",");
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
let { data, error } = await supabase
|
| 122 |
+
.from(table)
|
| 123 |
+
.select(columns)
|
| 124 |
+
.match(where);
|
| 125 |
+
|
| 126 |
+
return !!data.length;
|
| 127 |
+
|
| 128 |
+
} catch (e) {
|
| 129 |
+
console.log(e);
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
return false;
|
| 133 |
+
};
|
| 134 |
+
|
| 135 |
+
export const deleteData = async ({
|
| 136 |
+
table,
|
| 137 |
+
where,
|
| 138 |
+
}) => {
|
| 139 |
+
try {
|
| 140 |
+
const { data, error, statusText } = await supabase
|
| 141 |
+
.from(table)
|
| 142 |
+
.delete()
|
| 143 |
+
.match(where);
|
| 144 |
+
|
| 145 |
+
return { data, error, statusText };
|
| 146 |
+
} catch (e) {
|
| 147 |
+
console.log(e);
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
return false;
|
| 151 |
+
};
|
| 152 |
+
|
| 153 |
+
export const uploadFile = async (userID, postID, id, file) => {
|
| 154 |
+
|
| 155 |
+
try {
|
| 156 |
+
|
| 157 |
+
supabase.storage
|
| 158 |
+
.from("images")
|
| 159 |
+
.upload(`users/${userID}/${postID}/${id}`, file, {
|
| 160 |
+
cacheControl: '3600',
|
| 161 |
+
upsert: false
|
| 162 |
+
}).then(console.log);
|
| 163 |
+
|
| 164 |
+
} catch (e) {
|
| 165 |
+
|
| 166 |
+
console.log(e);
|
| 167 |
+
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
};
|
| 171 |
+
|
| 172 |
+
export const getFile = (FolderPath, id) => {
|
| 173 |
+
|
| 174 |
+
let { data: { publicUrl: src } } = supabase.storage.from(`images/${FolderPath}`).getPublicUrl(id);
|
| 175 |
+
|
| 176 |
+
return src;
|
| 177 |
+
|
| 178 |
+
};
|
| 179 |
+
|
| 180 |
+
export const deleteFile = async (path) => {
|
| 181 |
+
|
| 182 |
+
let { data } = await supabase.storage.from(`images`).remove([`${path}`]);
|
| 183 |
+
|
| 184 |
+
return data;
|
| 185 |
+
|
| 186 |
+
};
|
| 187 |
+
|
| 188 |
+
export const deleteAllFiles = async (FolderPath) => {
|
| 189 |
+
let { data: list } = await supabase.storage.from(`images`).list(FolderPath);
|
| 190 |
+
const filesToDelete = list.map(file => `${FolderPath}/${file.name}`);
|
| 191 |
+
const { data, error } = await supabase.storage.from("images").remove(filesToDelete);
|
| 192 |
+
return data;
|
| 193 |
+
};
|
app/api/api-access/route.js
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { createTransport } from 'nodemailer';
|
| 2 |
+
|
| 3 |
+
export async function POST ( req ) {
|
| 4 |
+
const { email } = await req.json();
|
| 5 |
+
|
| 6 |
+
try {
|
| 7 |
+
const transporter = createTransport( {
|
| 8 |
+
service: "SMTP",
|
| 9 |
+
host: "aions.co",
|
| 10 |
+
port: 465,
|
| 11 |
+
auth: {
|
| 12 |
+
user: "chat@aions.co",
|
| 13 |
+
pass: process.env.SMTP_PASS
|
| 14 |
+
}
|
| 15 |
+
} );
|
| 16 |
+
|
| 17 |
+
const res = await transporter.sendMail( {
|
| 18 |
+
from: 'aions.co <chat@aions.co>',
|
| 19 |
+
to: email,
|
| 20 |
+
subject: 'Early Access Signup Confirmation',
|
| 21 |
+
html: `<!DOCTYPE html>
|
| 22 |
+
<html>
|
| 23 |
+
<head>
|
| 24 |
+
<style>
|
| 25 |
+
body {
|
| 26 |
+
font-family: Arial, sans-serif;
|
| 27 |
+
margin: 0;
|
| 28 |
+
padding: 0;
|
| 29 |
+
background-color: #f4f4f4;
|
| 30 |
+
}
|
| 31 |
+
.header {
|
| 32 |
+
background-color: #0073e6;
|
| 33 |
+
color: #fff;
|
| 34 |
+
text-align: center;
|
| 35 |
+
padding: 20px;
|
| 36 |
+
}
|
| 37 |
+
.container {
|
| 38 |
+
max-width: 600px;
|
| 39 |
+
margin: 0 auto;
|
| 40 |
+
background-color: #fff;
|
| 41 |
+
border-radius: 5px;
|
| 42 |
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
| 43 |
+
}
|
| 44 |
+
.services {
|
| 45 |
+
padding: 20px;
|
| 46 |
+
}
|
| 47 |
+
.services h2{
|
| 48 |
+
color: black;
|
| 49 |
+
}
|
| 50 |
+
.service {
|
| 51 |
+
margin-bottom: 20px;
|
| 52 |
+
}
|
| 53 |
+
.service h3 {
|
| 54 |
+
color: #0073e6;
|
| 55 |
+
}
|
| 56 |
+
.service p {
|
| 57 |
+
line-height: 1.6;
|
| 58 |
+
color: #333;
|
| 59 |
+
}
|
| 60 |
+
.contact {
|
| 61 |
+
text-align: center;
|
| 62 |
+
margin-top: 20px;
|
| 63 |
+
}
|
| 64 |
+
.thanks {
|
| 65 |
+
text-align: center;
|
| 66 |
+
background-color: #0073e6;
|
| 67 |
+
color: #fff;
|
| 68 |
+
padding: 10px;
|
| 69 |
+
}
|
| 70 |
+
</style>
|
| 71 |
+
</head>
|
| 72 |
+
<body>
|
| 73 |
+
<div class="header">
|
| 74 |
+
<h1>AIONS (Animated Interactive Objects and Neural Software)</h1>
|
| 75 |
+
<p>Revolutionizing animation with the power of AI</p>
|
| 76 |
+
</div>
|
| 77 |
+
<div class="container">
|
| 78 |
+
<div class="services">
|
| 79 |
+
<h2>Our Services</h2>
|
| 80 |
+
<div class="service">
|
| 81 |
+
<h3>PreBytes</h3>
|
| 82 |
+
<p>We specialize in developing games that push the boundaries of innovation and entertainment. Our team of experienced game developers and AI engineers collaborate to create immersive gaming experiences that adapt and learn from player behavior. From procedural generation and intelligent NPCs to adaptive difficulty and real-time decision-making, our AI game development services will take your gaming experience to the next level.</p>
|
| 83 |
+
</div>
|
| 84 |
+
<div class="service">
|
| 85 |
+
<h3>Chaperone</h3>
|
| 86 |
+
<p>An Android app connecting users with companions for enjoyable activities and conversations. Personalized and convenient, it's the platform for meaningful connections and memorable experiences.</p>
|
| 87 |
+
</div>
|
| 88 |
+
<div class="service">
|
| 89 |
+
<h3>Valora</h3>
|
| 90 |
+
<p>Valora is a pioneering software company specializing in HR Management services. With a focus on modernizing and streamlining human resources processes, Valora offers innovative solutions to optimize talent acquisition, employee onboarding, performance management, and more. Through its cutting-edge technology, Valora empowers businesses to enhance workforce efficiency, engagement, and overall organizational success. With a commitment to delivering user-friendly and scalable HR solutions, Valora is reshaping the future of human resource management for companies across various industries.</p>
|
| 91 |
+
</div>
|
| 92 |
+
<div class="service">
|
| 93 |
+
<h3>Neural Softwares</h3>
|
| 94 |
+
<p>Neural Softwares is a pioneering AI company at the forefront of developing a diverse range of cutting-edge AI tools. Leveraging advanced neural network architectures and machine learning techniques, Neural Softwares creates innovative solutions tailored to address various industries' unique challenges. From natural language processing and computer vision to predictive analytics and automation, their AI tools empower businesses with intelligent insights and streamlined processes, unlocking new levels of efficiency and productivity.</p>
|
| 95 |
+
</div>
|
| 96 |
+
<div class="thanks">
|
| 97 |
+
<p>Thank you for signing up for early access</p>
|
| 98 |
+
</div>
|
| 99 |
+
<div class="contact">
|
| 100 |
+
<p>Contact: <a href="mailto:info@aions.co">info@aions.co</a></p>
|
| 101 |
+
</div>
|
| 102 |
+
</div>
|
| 103 |
+
</div>
|
| 104 |
+
</body>
|
| 105 |
+
</html>
|
| 106 |
+
`
|
| 107 |
+
} );
|
| 108 |
+
|
| 109 |
+
return new Response( JSON.stringify( { response: res } ), { status: 200 } );
|
| 110 |
+
|
| 111 |
+
} catch ( e ) {
|
| 112 |
+
console.log( e );
|
| 113 |
+
return new Response( JSON.stringify( { error: e } ), { status: 500 } );
|
| 114 |
+
}
|
| 115 |
+
}
|
app/api/auth/[...nextauth]/route.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { exists, getData, insertData } from "@/app/Supabase/Supabase";
|
| 2 |
+
import NextAuth from "next-auth";
|
| 3 |
+
import GoogleProvider from "next-auth/providers/google";
|
| 4 |
+
|
| 5 |
+
const handler = NextAuth( {
|
| 6 |
+
|
| 7 |
+
providers: [
|
| 8 |
+
|
| 9 |
+
GoogleProvider( {
|
| 10 |
+
clientId: process.env.GOOGLE_CLIENT_ID,
|
| 11 |
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET
|
| 12 |
+
} )
|
| 13 |
+
|
| 14 |
+
],
|
| 15 |
+
callbacks: {
|
| 16 |
+
|
| 17 |
+
async session ( { session, user, token } ) {
|
| 18 |
+
try {
|
| 19 |
+
|
| 20 |
+
const sessionUser = await getData( {
|
| 21 |
+
table: "users",
|
| 22 |
+
where: {
|
| 23 |
+
email: session.user.email
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
} ).then( users => users.data[ 0 ] );
|
| 27 |
+
|
| 28 |
+
session.user.id = sessionUser.id;
|
| 29 |
+
|
| 30 |
+
return session;
|
| 31 |
+
|
| 32 |
+
} catch ( e ) {
|
| 33 |
+
console.log( e );
|
| 34 |
+
}
|
| 35 |
+
},
|
| 36 |
+
async signIn ( { profile } ) {
|
| 37 |
+
|
| 38 |
+
try {
|
| 39 |
+
|
| 40 |
+
const userExist = await exists( {
|
| 41 |
+
table: "users",
|
| 42 |
+
where: {
|
| 43 |
+
email: profile.email
|
| 44 |
+
},
|
| 45 |
+
columns: "email"
|
| 46 |
+
} );
|
| 47 |
+
|
| 48 |
+
if ( !userExist ) {
|
| 49 |
+
|
| 50 |
+
const currentDate = new Date();
|
| 51 |
+
|
| 52 |
+
await insertData( {
|
| 53 |
+
table: "users",
|
| 54 |
+
object: {
|
| 55 |
+
email: profile.email,
|
| 56 |
+
name: profile.name.toLowerCase(),
|
| 57 |
+
image: profile.picture,
|
| 58 |
+
created_at: `${ currentDate.getDate() }-${ currentDate.toLocaleString( 'default', { month: 'long' } ).substring( 0, 3 ) } ${ currentDate.getFullYear() }`
|
| 59 |
+
}
|
| 60 |
+
} );
|
| 61 |
+
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
return true;
|
| 65 |
+
|
| 66 |
+
} catch ( e ) {
|
| 67 |
+
|
| 68 |
+
console.log( e );
|
| 69 |
+
return false;
|
| 70 |
+
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
} );
|
| 76 |
+
|
| 77 |
+
export { handler as GET, handler as POST };
|
app/api/bard/route.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { DiscussServiceClient } from "@google-ai/generativelanguage";
|
| 2 |
+
import { GoogleAuth } from "google-auth-library";
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
const API_KEY = process.env.API_KEY;
|
| 6 |
+
const MODEL_NAME = "models/chat-bison-001";
|
| 7 |
+
|
| 8 |
+
const client = new DiscussServiceClient( {
|
| 9 |
+
authClient: new GoogleAuth().fromAPIKey( "AIzaSyA6B01DPsXtGIhUQjckCshbD1E99Edd2Tg" ),
|
| 10 |
+
} );
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
const MAX_RETRIES = 5;
|
| 14 |
+
|
| 15 |
+
export const POST = async ( req, { params } ) => {
|
| 16 |
+
try {
|
| 17 |
+
let { messages } = await req.json();
|
| 18 |
+
|
| 19 |
+
let retries = 0;
|
| 20 |
+
let answer;
|
| 21 |
+
|
| 22 |
+
while ( retries < MAX_RETRIES ) {
|
| 23 |
+
console.log( `ran ${ retries + 1 } times` );
|
| 24 |
+
const result = await client.generateMessage( {
|
| 25 |
+
model: MODEL_NAME,
|
| 26 |
+
temperature: ( retries + 1.6 ) * 0.1,
|
| 27 |
+
prompt: {
|
| 28 |
+
context: "You Are Ray-AI and this is also your name.",
|
| 29 |
+
messages,
|
| 30 |
+
},
|
| 31 |
+
} );
|
| 32 |
+
|
| 33 |
+
if ( result[ 0 ]?.candidates?.[ 0 ]?.content ) {
|
| 34 |
+
answer = result[ 0 ].candidates[ 0 ].content;
|
| 35 |
+
break;
|
| 36 |
+
} else {
|
| 37 |
+
messages.push( { content: "hmm" } );
|
| 38 |
+
retries++;
|
| 39 |
+
console.log( result[ 0 ] );
|
| 40 |
+
}
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
if ( !answer ) {
|
| 44 |
+
return new Response( JSON.stringify( { answer: "I Apologize Can you Clearify?" } ), { status: 200 } );
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
return new Response( JSON.stringify( { answer } ), { status: 200 } );
|
| 48 |
+
} catch ( e ) {
|
| 49 |
+
console.log( e );
|
| 50 |
+
return new Response( JSON.stringify( { error: e } ), { status: 500 } );
|
| 51 |
+
}
|
| 52 |
+
};
|
app/api/chat/route.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
// // import { OpenAIStream, StreamingTextResponse } from "ai";
|
| 2 |
+
// // import OpenAI from "openai";
|
| 3 |
+
|
| 4 |
+
import axios from "axios";
|
| 5 |
+
|
| 6 |
+
// // const openai = new OpenAI( {
|
| 7 |
+
// // apiKey: process.env.OPENAI_API_KEY,
|
| 8 |
+
// // } );
|
| 9 |
+
|
| 10 |
+
// // export const runtime = 'edge';
|
| 11 |
+
|
| 12 |
+
// // export async function POST ( req ) {
|
| 13 |
+
// // try {
|
| 14 |
+
// // const { messages } = await req.json();
|
| 15 |
+
// // const response = await openai.chat.completions.create( {
|
| 16 |
+
// // model: 'gpt-3.5-turbo',
|
| 17 |
+
// // stream: true,
|
| 18 |
+
// // messages,
|
| 19 |
+
// // } );
|
| 20 |
+
// // const stream = OpenAIStream( response );
|
| 21 |
+
// // return new StreamingTextResponse( stream );
|
| 22 |
+
// // } catch ( e ) {
|
| 23 |
+
// // console.log( e );
|
| 24 |
+
// // return null;
|
| 25 |
+
// // }
|
| 26 |
+
// // }
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
// import { HfInference } from '@huggingface/inference';
|
| 30 |
+
// import { HuggingFaceStream, StreamingTextResponse } from 'ai';
|
| 31 |
+
// import { experimental_buildOpenAssistantPrompt } from 'ai/prompts';
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
// const Hf = new HfInference( "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" );
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
// export const runtime = 'edge';
|
| 38 |
+
|
| 39 |
+
// export async function POST ( req ) {
|
| 40 |
+
// try {
|
| 41 |
+
|
| 42 |
+
// const { messages } = await req.json();
|
| 43 |
+
|
| 44 |
+
// const response = await Hf.textGenerationStream( {
|
| 45 |
+
// model: 'OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5',
|
| 46 |
+
// inputs: experimental_buildOpenAssistantPrompt( messages ),
|
| 47 |
+
// parameters: {
|
| 48 |
+
// max_new_tokens: 1000,
|
| 49 |
+
// // @ts-ignore (this is a valid parameter specifically in OpenAssistant models)
|
| 50 |
+
// typical_p: 0.2,
|
| 51 |
+
// repetition_penalty: 1,
|
| 52 |
+
// truncate: 1000,
|
| 53 |
+
// return_full_text: false,
|
| 54 |
+
// }
|
| 55 |
+
// } );
|
| 56 |
+
|
| 57 |
+
|
| 58 |
+
// const stream = HuggingFaceStream( response );
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
// return new StreamingTextResponse( stream );
|
| 62 |
+
|
| 63 |
+
// } catch ( e ) {
|
| 64 |
+
// console.log( e );
|
| 65 |
+
// }
|
| 66 |
+
// }
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
export async function POST ( req ) {
|
| 70 |
+
const { input, new_convo } = await req.json();
|
| 71 |
+
|
| 72 |
+
try {
|
| 73 |
+
|
| 74 |
+
// const response = await fetch( "https://AIONS.pythonanywhere.com/api/huggingface", {
|
| 75 |
+
// method: "POST",
|
| 76 |
+
// body: JSON.stringify( {
|
| 77 |
+
// prompt: input,
|
| 78 |
+
// chatbot_model: 0,
|
| 79 |
+
// web_search: true,
|
| 80 |
+
// new_conversation: new_convo
|
| 81 |
+
// } ),
|
| 82 |
+
// headers: {
|
| 83 |
+
// 'Content-Type': 'application/json',
|
| 84 |
+
// }
|
| 85 |
+
// } );
|
| 86 |
+
|
| 87 |
+
// if ( response.ok ) {
|
| 88 |
+
// const body = await response.json();
|
| 89 |
+
// console.log( body.response );
|
| 90 |
+
// return new Response( JSON.stringify( { body } ), { status: 200 } );
|
| 91 |
+
// }
|
| 92 |
+
|
| 93 |
+
// console.log( await response.json() );
|
| 94 |
+
|
| 95 |
+
let response = await axios.post( "https://AIONS.pythonanywhere.com/api/huggingface", {
|
| 96 |
+
prompt: input,
|
| 97 |
+
chatbot_model: 0,
|
| 98 |
+
web_search: true,
|
| 99 |
+
new_conversation: new_convo
|
| 100 |
+
} );
|
| 101 |
+
|
| 102 |
+
if ( response.status == 200 ) {
|
| 103 |
+
console.log( response.data.response );
|
| 104 |
+
return new Response( JSON.stringify( { body: { response: response.data.response } } ), { status: response.status } );
|
| 105 |
+
} else {
|
| 106 |
+
console.log( response.data );
|
| 107 |
+
return new Response( JSON.stringify( { error: { error: response.statusText } } ), { status: response.status } );
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
} catch ( e ) {
|
| 111 |
+
console.log( e );
|
| 112 |
+
return new Response( JSON.stringify( { error: e } ), { status: 500 } );
|
| 113 |
+
}
|
| 114 |
+
}
|
app/favicon.ico
ADDED
|
|
app/globals.css
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
@font-face {
|
| 2 |
+
font-family: Quicksand;
|
| 3 |
+
src: url("/Fonts/Quicksand.ttf");
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
@font-face {
|
| 7 |
+
font-family: Righteous;
|
| 8 |
+
src: url("/Fonts/Righteous.ttf");
|
| 9 |
+
}
|
| 10 |
+
|
| 11 |
+
@font-face {
|
| 12 |
+
font-family: Aharoni;
|
| 13 |
+
src: url("/Fonts/Aharoni.ttf");
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
@font-face {
|
| 17 |
+
font-family: ABeeZee;
|
| 18 |
+
src: url("/Fonts/ABeeZee.ttf");
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
@font-face {
|
| 22 |
+
font-family: Roboto;
|
| 23 |
+
src: url("/Fonts/Roboto.ttf");
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
@font-face {
|
| 27 |
+
font-family: Montserrat;
|
| 28 |
+
src: url("/Fonts/Montserrat.ttf");
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
* {
|
| 32 |
+
padding: 0;
|
| 33 |
+
margin: 0;
|
| 34 |
+
box-sizing: border-box;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
/* ::placeholder {
|
| 38 |
+
font-size: 0.9em;
|
| 39 |
+
} */
|
| 40 |
+
|
| 41 |
+
:root {
|
| 42 |
+
--top-left: #1c3651;
|
| 43 |
+
/* #330624: #65133a, #432d39 #1c3651: #18868d, #365057 */
|
| 44 |
+
--mid-left: #1a303a;
|
| 45 |
+
/* #33192c #1a303a */
|
| 46 |
+
--center: #1c364f;
|
| 47 |
+
/* #470932db #1c364f */
|
| 48 |
+
--top-right: #1e204d;
|
| 49 |
+
/* #41183d #1e204d */
|
| 50 |
+
--bottom-right: #273643;
|
| 51 |
+
/* #432741 #273643 */
|
| 52 |
+
|
| 53 |
+
--top-left-dark: #1c3651;
|
| 54 |
+
/* #391c51 */
|
| 55 |
+
--mid-left-dark: #1a303a;
|
| 56 |
+
/* #1D1A3A */
|
| 57 |
+
--center-dark: #1c364f;
|
| 58 |
+
/* #1C224F */
|
| 59 |
+
--top-right-dark: #1e204d;
|
| 60 |
+
/* #2B1E4D */
|
| 61 |
+
--bottom-right-dark: #273643;
|
| 62 |
+
/* #2D2743 */
|
| 63 |
+
|
| 64 |
+
--top-left-light: #0b6c6d;
|
| 65 |
+
--mid-left-light: #176da0;
|
| 66 |
+
--center-light: #aaf0ff;
|
| 67 |
+
--top-right-light: #c1c3ff;
|
| 68 |
+
--bottom-right-light: #aaf1ff;
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
body {
|
| 72 |
+
width: 100vw;
|
| 73 |
+
height: 100vh;
|
| 74 |
+
overflow: hidden;
|
| 75 |
+
--body-bg: #012127;
|
| 76 |
+
--body-bg-dark: #012127;
|
| 77 |
+
--body-bg-light: #96dade;
|
| 78 |
+
background: var(--body-bg);
|
| 79 |
+
/* background: #160722; */
|
| 80 |
+
/* #11192A */
|
| 81 |
+
/* #012127 */
|
| 82 |
+
/* #160815 */
|
| 83 |
+
}
|
| 84 |
+
|
| 85 |
+
::-webkit-scrollbar {
|
| 86 |
+
width: 8.5px;
|
| 87 |
+
height: 5px;
|
| 88 |
+
background: transparent;
|
| 89 |
+
border-radius: 5px;
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
::-webkit-scrollbar-thumb {
|
| 93 |
+
background: #7cd0cc;
|
| 94 |
+
border-radius: 5px;
|
| 95 |
+
min-height: 30px;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
body.lightMode {
|
| 99 |
+
background: var(--body-bg-light);
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
div.bg1 {
|
| 103 |
+
position: fixed;
|
| 104 |
+
background: var(--top-left);
|
| 105 |
+
width: 35.625vw;
|
| 106 |
+
height: 77.19005vh;
|
| 107 |
+
border-radius: 50%;
|
| 108 |
+
top: -34.7225vh;
|
| 109 |
+
/* Updated value */
|
| 110 |
+
left: -16.875vw;
|
| 111 |
+
z-index: -100000;
|
| 112 |
+
filter: blur(100px);
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
div.bg2 {
|
| 116 |
+
position: fixed;
|
| 117 |
+
background: var(--mid-left);
|
| 118 |
+
width: 35.625vw;
|
| 119 |
+
height: 77.01675vh;
|
| 120 |
+
/* Updated value */
|
| 121 |
+
border-radius: 50%;
|
| 122 |
+
top: 34.7225vh;
|
| 123 |
+
/* Updated value */
|
| 124 |
+
left: -16.875vw;
|
| 125 |
+
z-index: -100000;
|
| 126 |
+
filter: blur(100px);
|
| 127 |
+
}
|
| 128 |
+
|
| 129 |
+
div.bg3 {
|
| 130 |
+
position: fixed;
|
| 131 |
+
background: var(--center);
|
| 132 |
+
width: 29.1vw;
|
| 133 |
+
height: 66.4765vh;
|
| 134 |
+
/* Updated value */
|
| 135 |
+
border-radius: 50%;
|
| 136 |
+
top: -23.73115vh;
|
| 137 |
+
/* Updated value */
|
| 138 |
+
left: 24.9vw;
|
| 139 |
+
z-index: -100000;
|
| 140 |
+
filter: blur(100px);
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
div.bg4 {
|
| 144 |
+
position: fixed;
|
| 145 |
+
background: var(--top-right);
|
| 146 |
+
width: 51.6vw;
|
| 147 |
+
height: 66.4765vh;
|
| 148 |
+
/* Updated value */
|
| 149 |
+
border-radius: 50%;
|
| 150 |
+
top: -23.73115vh;
|
| 151 |
+
/* Updated value */
|
| 152 |
+
right: -11.25vw;
|
| 153 |
+
z-index: -100000;
|
| 154 |
+
filter: blur(100px);
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
div.bg5 {
|
| 158 |
+
position: fixed;
|
| 159 |
+
background: var(--bottom-right);
|
| 160 |
+
width: 51.6vw;
|
| 161 |
+
height: 66.4765vh;
|
| 162 |
+
/* Updated value */
|
| 163 |
+
border-radius: 50%;
|
| 164 |
+
bottom: -46.5066vh;
|
| 165 |
+
/* Updated value */
|
| 166 |
+
right: 6.15vw;
|
| 167 |
+
z-index: -100000;
|
| 168 |
+
filter: blur(100px);
|
| 169 |
+
}
|
jsconfig.json
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"compilerOptions": {
|
| 3 |
+
"paths": {
|
| 4 |
+
"@/*": [ "./*" ]
|
| 5 |
+
}
|
| 6 |
+
}
|
| 7 |
+
}
|
next.config.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/** @type {import('next').NextConfig} */
|
| 2 |
+
const nextConfig = {
|
| 3 |
+
images: {
|
| 4 |
+
domains: [ 'lh3.googleusercontent.com', "res.cloudinary.com", "iiehkolsitbpijjhtjfu.supabase.co" ]
|
| 5 |
+
}
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
module.exports = nextConfig;
|
package-lock.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"name": "client",
|
| 3 |
+
"version": "0.1.0",
|
| 4 |
+
"private": true,
|
| 5 |
+
"scripts": {
|
| 6 |
+
"dev": "next dev -p 3001",
|
| 7 |
+
"build": "next build",
|
| 8 |
+
"start": "next start",
|
| 9 |
+
"lint": "next lint"
|
| 10 |
+
},
|
| 11 |
+
"dependencies": {
|
| 12 |
+
"@fortawesome/fontawesome-svg-core": "^6.4.2",
|
| 13 |
+
"@fortawesome/free-brands-svg-icons": "^6.4.2",
|
| 14 |
+
"@fortawesome/free-regular-svg-icons": "^6.4.2",
|
| 15 |
+
"@fortawesome/free-solid-svg-icons": "^6.4.2",
|
| 16 |
+
"@fortawesome/react-fontawesome": "^0.2.0",
|
| 17 |
+
"@google-ai/generativelanguage": "^1.1.0",
|
| 18 |
+
"@huggingface/inference": "^2.6.3",
|
| 19 |
+
"@supabase/supabase-js": "^2.36.0",
|
| 20 |
+
"ai": "^2.2.14",
|
| 21 |
+
"axios": "^1.5.1",
|
| 22 |
+
"google-auth-library": "^9.0.0",
|
| 23 |
+
"marked": "^9.0.3",
|
| 24 |
+
"next": "13.5.2",
|
| 25 |
+
"next-auth": "^4.23.1",
|
| 26 |
+
"nodemailer": "^6.9.6",
|
| 27 |
+
"openai": "^4.11.1",
|
| 28 |
+
"react": "18.2.0",
|
| 29 |
+
"react-dom": "18.2.0",
|
| 30 |
+
"react-markdown": "^8.0.7",
|
| 31 |
+
"react-syntax-highlighter": "^15.5.0",
|
| 32 |
+
"request": "^2.88.2",
|
| 33 |
+
"uuid": "^9.0.1"
|
| 34 |
+
},
|
| 35 |
+
"devDependencies": {
|
| 36 |
+
"encoding": "^0.1.13"
|
| 37 |
+
},
|
| 38 |
+
"browser": {
|
| 39 |
+
"tls": false,
|
| 40 |
+
"net": false,
|
| 41 |
+
"fs": false,
|
| 42 |
+
"path": false,
|
| 43 |
+
"child_process": false
|
| 44 |
+
}
|
| 45 |
+
}
|
public/Fonts/ABeeZee.ttf
ADDED
|
Binary file (45.6 kB). View file
|
|
|
public/Fonts/Aharoni.ttf
ADDED
|
Binary file (40 kB). View file
|
|
|
public/Fonts/Montserrat.ttf
ADDED
|
Binary file (394 kB). View file
|
|
|
public/Fonts/Quicksand.ttf
ADDED
|
Binary file (78.6 kB). View file
|
|
|
public/Fonts/Righteous.ttf
ADDED
|
Binary file (40.9 kB). View file
|
|
|
public/Fonts/Roboto.ttf
ADDED
|
Binary file (168 kB). View file
|
|
|
public/RayAI.jpg
ADDED
|
public/RayAI.png
ADDED
|
public/RayAI.svg
ADDED
|
|
public/bg.svg
ADDED
|
|
public/card-bg-2.svg
ADDED
|
|