Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"typescript.tsdk": "node_modules/typescript/lib",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
}
"typescript.tsdk": "node_modules/typescript/lib",
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"WillLuke.nextjs.hasPrompted": true
}
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,12 @@ https://vitest.dev/guide/mocking.html

## Recharts
https://recharts.org/en-US/

## Filestore
https://firebase.google.com/docs/storage/web/start

## P5.js
https://github.com/P5-wrapper/react


## Acknowledgment
Expand Down
Binary file added app/(dashboard)/feelings/feelings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions app/(dashboard)/feelings/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use client'
import FeelingsWheel from '@/components/FeelingsWheel'
// import SunburstAnyChart from '@/components/Sunburst'
import Image from 'next/image'
export default function Feelings() {
return (
<>
{/* <Image
alt="feelings wheel"
src="/feelings.png"
width={600}
height={600}
></Image> */}
<FeelingsWheel></FeelingsWheel>
</>
)
}
28 changes: 16 additions & 12 deletions app/(dashboard)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
import { UserButton } from "@clerk/nextjs"
import Link from "next/link"
import { UserButton } from '@clerk/nextjs'
import Link from 'next/link'


const DashboardLayout = ({children}) => {
const DashboardLayout = ({ children }) => {
const links = [
{label: 'home', href: '/' },
{label: 'journal', href: '/journal'},
{label: 'history', href: '/history'},
{ label: 'home', href: '/' },
{ label: 'journal', href: '/journal' },
{ label: 'history', href: '/history' },
{ label: 'visualizer', href: '/visualizer' },
{ label: 'feelings', href: '/feelings' },
{ label: 'markdown', href: '/markdown' },
]
return (
<div className="h-screen w-screen relative">
<aside className="absolute w-[200px] top-0 left-0 h-full border-r border-black/10">
<Link href="/journal"> Entheogen</Link>
<aside className="absolute w-[200px] top-0 left-0 h-full border-r border-black/10">
<Link href="/journal"> Entheogen</Link>
<ul>
{ links.map(link => (
{links.map((link) => (
<li key={link.label}>
<Link key={link.label} href={link.href}>{link.label}</Link>
<Link key={link.label} href={link.href}>
{link.label}
</Link>
</li>
))}
</ul>
Expand All @@ -32,4 +36,4 @@ const DashboardLayout = ({children}) => {
)
}

export default DashboardLayout
export default DashboardLayout
64 changes: 64 additions & 0 deletions app/(dashboard)/markdown/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
//https://contentlayer.dev/
// "use client"
// import { MDXEditor, MDXEditorMethods } from "@mdxeditor/editor"
// import { useRef } from "react"

// create a ref to the editor component
// const MarkdownPage = () => {
// const ref = useRef<MDXEditorMethods>(null)
// return (
// <>
// <button onClick={() => ref.current?.insertMarkdown('new markdown to insert')}>Insert new markdown</button>
// <button onClick={() => console.log(ref.current?.getMarkdown())}>Get markdown</button>
// <MDXEditor ref={ref} markdown="hello world" onChange={console.log} />
// </>
// )
// }

// export default MarkdownPage;

// import { MDXEditor, headingsPlugin, listsPlugin, quotePlugin, thematicBreakPlugin } from '@mdxeditor/editor'

// function App() {
// return <MDXEditor markdown="# Hello world" plugins={[headingsPlugin(), listsPlugin(), quotePlugin(), thematicBreakPlugin()]} />
// }

import Image from 'next/image'
import dynamic from 'next/dynamic'
import { Suspense } from 'react'

const EditorComp = dynamic(() => import('@/components/MDXEditor'), {
ssr: false,
})

const markdown = `
Hello **world**!
`

export default function Home() {
return (
<>
<p>
This is a bare-bones unstyled MDX editor without any plugins and no
toolbar. Check the EditorComponent.tsx file for the code.
</p>
<p>
To enable more features, add the respective plugins to your instance -
see{' '}
<a
className="text-blue-600"
href="https://mdxeditor.dev/editor/docs/getting-started"
>
the docs
</a>{' '}
for more details.
</p>
<br />
<div style={{ border: '1px solid black' }}>
<Suspense fallback={null}>
<EditorComp markdown={markdown} />
</Suspense>
</div>
</>
)
}
35 changes: 35 additions & 0 deletions app/(dashboard)/visualizer/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@

import Uploader from "@/components/FileUploader"
import {Visualizer} from "@/components/Visualizer"
const getEEGData = async () => {
// const user = await getUserFromClerkID
// const entry = await prisma.journalEntry.findMany({
// where:{
// userId: user.id,
// },
// orderBy:{
// createdAt: 'desc'
// }
// })
// eegData =
// return eegData
}

const VisualizerPage = async () => {
// const data = await getEEGData()
// console.log('data ', data)
return (
<div className="px-6 py-8 bg-zinc-100/50 h-full">
<h2 className="text-4xl mb-12">Journal</h2>
<div className="my-8">
Visualization
{/* <Uploader /> */}
</div>
<div className="grid grid-cols-3 gap-4">
<Visualizer />
</div>
</div>
)
}

export default VisualizerPage
57 changes: 57 additions & 0 deletions app/api/storage/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { NextApiRequest, NextApiResponse } from 'next'
import { initializeApp } from 'firebase/app'
import { getDownloadURL, getStorage, ref } from 'firebase/storage'
import { firebaseConfig } from '@/firebase'
// https://dev.to/reeshee/how-to-use-firebase-storage-to-upload-and-retrieve-files-in-nextjs-pages-router-2p16
async function filePOST(request: NextApiRequest, res: NextApiResponse) {
// Initialize the Firebase app with the provided configuration
const app = initializeApp(firebaseConfig)
// Get a reference to the Firebase Storage and parse the request data as a FormData object
const storage = getStorage(app)
// More code to handle uploads incoming...
}



async function fileGET(request: NextApiRequest, res: NextApiResponse) {
// Extract the 'file' parameter from the request URL.
const file = request.query.file
// Check if the 'image' parameter exists in the URL.
if (file && typeof file === 'string') {
try {
// Initialize the Firebase app with the provided configuration.
const app = initializeApp(firebaseConfig)
// Get a reference to the Firebase storage.
const storage = getStorage(app)
// Create a reference to the specified file in storage.
const fileRef = ref(storage, file)
// Get the download URL of the file.
const filePublicURL = await getDownloadURL(fileRef)
// Return a JSON response with the file's public URL and a 200 status code.
return res.status(200).json({ filePublicURL })
} catch (e: any) {
// If an error occurs, log the error message and return a JSON response with a 500 status code.
const tmp = e.message || e.toString()
console.log(tmp)
return res.status(500).send(tmp)
}
}
// If the 'file' parameter is not found in the URL, return a JSON response with a 400 status code.
return res.status(400).json({ error: 'Invalid Request' })
}

export const GET = async (request: NextApiRequest, response: NextApiResponse) => {
return await fileGET(request, response)
}

export const POST = async (request: NextApiRequest, response: NextApiResponse) => {
await filePOST(request, response)
}

// Disable parsing the body by Next.js default behavior
export const config = {
api: {
bodyParser: false,
},
}

61 changes: 13 additions & 48 deletions components/FeelingsWheel.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,17 @@
import React, { useState } from 'react';
import '@/styles/FeelingsWheel.css';

const feelingsData = [
{ name: 'Joy', color: 'yellow', angle: 0 },
{ name: 'Trust', color: 'green', angle: 45 },
{ name: 'Fear', color: 'blue', angle: 90 },
{ name: 'Surprise', color: 'lightblue', angle: 135 },
{ name: 'Sadness', color: 'purple', angle: 180 },
{ name: 'Disgust', color: 'green', angle: 225 },
{ name: 'Anger', color: 'red', angle: 270 },
{ name: 'Anticipation', color: 'orange', angle: 315 },
];

const Feeling = ({ feeling, onClick }) => (
<div
className="feeling-segment"
style={{
backgroundColor: feeling.color,
transform: `rotate(${feeling.angle}deg) skewY(-60deg)`,
}}
onClick={() => onClick(feeling.name)}
>
<div className="feeling-label" style={{ transform: `skewY(60deg) rotate(${feeling.angle * -1}deg)` }}>
{feeling.name}
</div>
</div>
);
'use client'
import AnyChart from 'anychart-react'
import { data } from '@/data/feelings/data'

const FeelingsWheel = () => {
const [selectedFeeling, setSelectedFeeling] = useState(null);

const handleClick = (feeling) => {
setSelectedFeeling(feeling);
alert(`You clicked on ${feeling}`);
};

return (
<div className="wheel-container">
{feelingsData.map((feeling) => (
<Feeling key={feeling.name} feeling={feeling} onClick={handleClick} />
))}
{selectedFeeling && (
<div className="selected-feeling">
<h3>{`You selected: ${selectedFeeling}`}</h3>
</div>
)}
</div>
);
};
<AnyChart
type="sunburst"
data={data}
title="Feelings Wheel"
height={800}
width={800}
/>
)
}

export default FeelingsWheel;
export default FeelingsWheel
44 changes: 44 additions & 0 deletions components/FileUploader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Use next app router, server components, and server actions to upload files to firebase storage
//
// you probably dont want to do this since just storing images in the next public folder is usually best
// but if for some reason you need to upload files to firebase storage from nextjs, here you go
// also worth noting that the firebase-admin storage sdk has almost no documentation
// and from what I can tell does almost nothing, but it's just a wrapper around the google cloud storage sdk
// so you can use that instead if you want better documentation and functionality
'use client'
import {Upload} from '@/utils/firebase'

const Uploader = () => {
// const handleOnClick = async () => {

// console.log("data is : ", data)
// // router.push(`/journal/${data.id}`)
// }
const handleFormData = async (formData: FormData) => {
const file = formData.get("file") as File;
console.log("file is: ", file)
const res = await Upload(file)
console.log("res is, ", res)
}
return (
<div>
<h1>Upload an image</h1>
<form action={handleFormData}>
<label>
{/* <input
type="file"
name="file"
accept="image/png, image/jpeg, image/gif"
/> */}
<input
type="file"
name="file"
/>
</label>
<button type="submit">Submit</button>
</form>
</div>
);
}

export default Uploader;
18 changes: 18 additions & 0 deletions components/ForwardRefEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client'
import dynamic from 'next/dynamic'
import { forwardRef } from 'react'
import {type MDXEditorMethods,MDXEditorProps } from '@mdxeditor/editor'
// ForwardRefEditor.tsx

// This is the only place InitializedMDXEditor is imported directly.
const Editor = dynamic(() => import('./InitializedMDXEditor'), {
// Make sure we turn SSR off
ssr: false
})

// This is what is imported by other components. Pre-initialized with plugins, and ready
// to accept other props, including a ref.
export const ForwardRefEditor = forwardRef<MDXEditorMethods, MDXEditorProps>((props, ref) => <Editor {...props} editorRef={ref} />)

// TS complains without the following line
ForwardRefEditor.displayName = 'ForwardRefEditor'
Loading