├── supabase ├── seed.sql ├── .gitignore └── getUsers.ts ├── functions ├── .gitignore └── process_brainwaves │ └── requirements.txt ├── components ├── ui │ ├── Navbar │ │ ├── index.ts │ │ ├── Navbar.module.css │ │ └── SignOutButton.tsx │ ├── Footer │ │ ├── index.ts │ │ └── Footer.tsx │ ├── LoadingDots │ │ ├── index.ts │ │ ├── LoadingDots.tsx │ │ └── LoadingDots.module.css │ ├── CrispChat.tsx │ ├── skeleton.tsx │ ├── label.tsx │ ├── feedback.tsx │ ├── progress.tsx │ ├── toaster.tsx │ ├── textarea.tsx │ ├── input.tsx │ ├── hover-card.tsx │ ├── checkbox.tsx │ ├── scroll-area.tsx │ ├── button.tsx │ └── PlanRibbon.tsx ├── icons │ ├── Logo.tsx │ ├── Discord.tsx │ └── GitHub.tsx ├── AppleHealthConnect.tsx ├── MetriportConnect.tsx ├── NeurosityDisconnect.tsx ├── OuraDisconnect.tsx └── magicui │ └── shimmer-button.tsx ├── public ├── demo.png ├── logo.png ├── og.png ├── oura.png ├── favicon.ico ├── neurosity.png ├── video-under.png ├── favicon-16x16.png ├── favicon-32x32.png ├── vercel-deploy.png ├── apple-touch-icon.png ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── google.svg ├── stripe.svg ├── vercel.svg ├── telegram.svg └── github.svg ├── postcss.config.js ├── ios ├── MediarAI │ ├── Assets.xcassets │ │ ├── Contents.json │ │ ├── AppIcon.appiconset │ │ │ ├── 1024.png │ │ │ └── Contents.json │ │ └── AccentColor.colorset │ │ │ └── Contents.json │ ├── Preview Content │ │ └── Preview Assets.xcassets │ │ │ └── Contents.json │ ├── Models │ │ ├── Model.swift │ │ └── HealthModel.swift │ ├── Components │ │ ├── Colors.swift │ │ ├── OTPTextField.swift │ │ ├── OTPFieldView.swift │ │ ├── PhoneNumber.swift │ │ ├── Button.swift │ │ ├── LabelTextField.swift │ │ ├── WhatsappConnect.swift │ │ └── Metriport.swift │ ├── MediarAI.entitlements │ ├── Constants.swift │ ├── AppView.swift │ ├── Info.plist │ ├── ContentView.swift │ ├── Views │ │ ├── TabsView.swift │ │ └── AlertView.swift │ ├── MediarAIApp.swift │ └── ViewModels │ │ └── SyncViewModel.swift ├── .swiftformat └── MediarAI.xcodeproj │ ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ │ └── louisbeaumont.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ ├── xcuserdata │ ├── louisbeaumont.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── louis.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist │ └── xcshareddata │ └── xcschemes │ └── MediarAI.xcscheme ├── utils ├── extended-types.ts ├── highlight.config.ts ├── stripe.ts ├── stripe-client.ts ├── helpers.ts └── neurosity-client.ts ├── next-env.d.ts ├── next.config.js ├── app ├── api │ ├── evervault-any │ │ └── route.ts │ ├── whatsapp-verification │ │ └── route.ts │ ├── evervault │ │ └── route.ts │ ├── completion │ │ └── route.ts │ ├── whatsapp-verification-otp │ │ └── route.ts │ ├── create-portal-link │ │ └── route.ts │ ├── metriport-token │ │ └── route.ts │ ├── single-metriport │ │ └── route.ts │ ├── chat │ │ └── route.ts │ ├── metriport │ │ └── route.ts │ ├── multi-metriport │ │ └── route.ts │ ├── multi-prompts │ │ └── route.ts │ ├── multi-static-prompts │ │ └── route.ts │ ├── single-static-prompts │ │ └── route.ts │ ├── webhooks │ │ └── route.ts │ ├── create-checkout-session │ │ └── route.ts │ └── multi-insights │ │ └── route.ts ├── posthog-server.ts ├── terms │ └── page.tsx ├── privacy │ └── page.tsx ├── metrics │ └── route.ts ├── custom-highlight-start.tsx ├── posthog-provider.tsx ├── auth │ ├── sign-out │ │ └── route.ts │ ├── sign-in │ │ └── route.ts │ ├── sign-up │ │ └── route.ts │ ├── callback │ │ └── route.ts │ └── neurosity │ │ ├── url │ │ └── route.ts │ │ └── route.ts ├── pricing │ └── page.tsx ├── _examples │ ├── route-handler │ │ └── route.ts │ ├── server-component │ │ └── page.tsx │ ├── client-component │ │ └── page.tsx │ ├── server-action │ │ └── page.tsx │ └── protected-route │ │ └── page.tsx ├── signin │ ├── messages.tsx │ ├── AuthUI.tsx │ └── page.tsx ├── dashboard │ ├── SaveTimezone.tsx │ ├── PosthogMail.tsx │ ├── layout.tsx │ ├── Chat.tsx │ ├── useNeurosity.ts │ ├── LLMInsights.tsx │ ├── page.tsx │ └── Command.tsx ├── onboarding │ ├── neurosity │ │ └── page.tsx │ ├── intro │ │ ├── GoToButton.tsx │ │ ├── page.tsx │ │ └── LLMStoryDistraction.tsx │ ├── goals │ │ └── page.tsx │ ├── oura │ │ └── page.tsx │ ├── whatsapp │ │ └── page.tsx │ ├── telegram │ │ └── page.tsx │ ├── layout.tsx │ ├── health │ │ └── page.tsx │ ├── communication │ │ └── page.tsx │ └── MobileWarning.tsx ├── dev │ └── page.tsx ├── signup │ └── page.tsx ├── account │ ├── ManageSubscriptionButton.tsx │ ├── Sub.tsx │ ├── LanguageSelector.tsx │ └── DailyUsage.tsx ├── telegram-server.tsx ├── supabase-provider.tsx ├── whatsapp │ └── page.tsx └── page.tsx ├── styles ├── chrome-bug.css └── main.css ├── components.json ├── vercel.json ├── instrumentation.ts ├── .gitignore ├── .env.local.example ├── tsconfig.json ├── LICENSE ├── tailwind.config.js ├── middleware.ts ├── lib └── google-cloud.ts ├── README.md └── fixtures └── stripe-fixtures.json /supabase/seed.sql: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /functions/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | -------------------------------------------------------------------------------- /supabase/.gitignore: -------------------------------------------------------------------------------- 1 | # Supabase 2 | .branches 3 | .temp 4 | -------------------------------------------------------------------------------- /components/ui/Navbar/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Navbar' 2 | -------------------------------------------------------------------------------- /components/ui/Footer/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './Footer'; 2 | -------------------------------------------------------------------------------- /components/ui/LoadingDots/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './LoadingDots'; 2 | -------------------------------------------------------------------------------- /public/demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/demo.png -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/logo.png -------------------------------------------------------------------------------- /public/og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/og.png -------------------------------------------------------------------------------- /public/oura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/oura.png -------------------------------------------------------------------------------- /functions/process_brainwaves/requirements.txt: -------------------------------------------------------------------------------- 1 | supabase 2 | functions-framework==3.* 3 | scikit-learn 4 | pandas -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/neurosity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/neurosity.png -------------------------------------------------------------------------------- /public/video-under.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/video-under.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = { 3 | plugins: { 4 | tailwindcss: {}, 5 | autoprefixer: {} 6 | } 7 | }; -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/vercel-deploy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/vercel-deploy.png -------------------------------------------------------------------------------- /public/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/apple-touch-icon.png -------------------------------------------------------------------------------- /ios/MediarAI/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /public/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/android-chrome-192x192.png -------------------------------------------------------------------------------- /public/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/public/android-chrome-512x512.png -------------------------------------------------------------------------------- /ios/MediarAI/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/.swiftformat: -------------------------------------------------------------------------------- 1 | --binarygrouping none --decimalgrouping none --hexgrouping none --octalgrouping none --semicolons never --stripunusedargs closure-only --wrapcollections before-first 2 | -------------------------------------------------------------------------------- /ios/MediarAI/Assets.xcassets/AppIcon.appiconset/1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/ios/MediarAI/Assets.xcassets/AppIcon.appiconset/1024.png -------------------------------------------------------------------------------- /utils/extended-types.ts: -------------------------------------------------------------------------------- 1 | import { Database } from "@/types_db"; 2 | 3 | export type State = Database["public"]["Tables"]["states"]["Row"] 4 | export type Tag = Database["public"]["Tables"]["tags"]["Row"] 5 | -------------------------------------------------------------------------------- /ios/MediarAI.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /ios/MediarAI/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /utils/highlight.config.ts: -------------------------------------------------------------------------------- 1 | // src/app/utils/highlight.config.ts: 2 | import { Highlight } from '@highlight-run/next/server' 3 | 4 | export const withHighlight = Highlight({ 5 | projectID: process.env.NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID!, 6 | }) 7 | 8 | -------------------------------------------------------------------------------- /ios/MediarAI.xcodeproj/xcuserdata/louisbeaumont.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /ios/MediarAI.xcodeproj/project.xcworkspace/xcuserdata/louisbeaumont.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kennedyantonio030/AI-Health-Assistant/HEAD/ios/MediarAI.xcodeproj/project.xcworkspace/xcuserdata/louisbeaumont.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true, 4 | experimental: { 5 | appDir: true, 6 | serverActions: true, 7 | instrumentationHook: true, 8 | } 9 | }; 10 | 11 | module.exports = nextConfig; 12 | 13 | -------------------------------------------------------------------------------- /components/ui/LoadingDots/LoadingDots.tsx: -------------------------------------------------------------------------------- 1 | import s from './LoadingDots.module.css'; 2 | 3 | const LoadingDots = () => { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | ); 11 | }; 12 | 13 | export default LoadingDots; 14 | -------------------------------------------------------------------------------- /app/api/evervault-any/route.ts: -------------------------------------------------------------------------------- 1 | 2 | export const runtime = 'edge' 3 | 4 | export async function POST(req: Request) { 5 | const body = await req.json() 6 | 7 | console.log('evervaulty', body) 8 | return new Response(JSON.stringify({ ...body }), { 9 | headers: { 'content-type': 'application/json' }, 10 | }) 11 | } 12 | -------------------------------------------------------------------------------- /components/ui/CrispChat.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { useEffect } from "react"; 4 | import { Crisp } from "crisp-sdk-web"; 5 | 6 | const CrispChat = () => { 7 | useEffect(() => { 8 | Crisp.configure("db4cb580-2ad4-4eb0-8bc8-4c4ab1205c9f"); 9 | }); 10 | 11 | return null; 12 | } 13 | 14 | export default CrispChat; -------------------------------------------------------------------------------- /ios/MediarAI/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "1024.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /utils/stripe.ts: -------------------------------------------------------------------------------- 1 | import Stripe from 'stripe'; 2 | 3 | export const stripe = new Stripe( 4 | process.env.STRIPE_SECRET_KEY_LIVE ?? process.env.STRIPE_SECRET_KEY ?? '', 5 | { 6 | apiVersion: '2022-11-15', 7 | appInfo: { 8 | name: 'Next.js Subscription Starter', 9 | version: '0.1.0' 10 | } 11 | } 12 | ); 13 | -------------------------------------------------------------------------------- /ios/MediarAI.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/posthog-server.ts: -------------------------------------------------------------------------------- 1 | // app/posthog.js 2 | import { PostHog } from 'posthog-node' 3 | 4 | export default function PostHogClient() { 5 | const posthogClient = new PostHog('phc_V7co1flWmfnd9Hd6LSyPRau9sARsxMEiOrmNvGeUhbJ', { 6 | host: 'https://app.posthog.com', 7 | flushAt: 1, 8 | flushInterval: 0 9 | }) 10 | return posthogClient 11 | } -------------------------------------------------------------------------------- /components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from "@/lib/utils" 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /styles/chrome-bug.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Chrome has a bug with transitions on load since 2012! 3 | * 4 | * To prevent a "pop" of content, you have to disable all transitions until 5 | * the page is done loading. 6 | * 7 | * https://lab.laukstein.com/bug/input 8 | * https://twitter.com/timer150/status/1345217126680899584 9 | */ 10 | body.loading * { 11 | transition: none !important; 12 | } 13 | -------------------------------------------------------------------------------- /app/terms/page.tsx: -------------------------------------------------------------------------------- 1 | import Markdown from '@/components/ui/Markdown'; 2 | import React from 'react'; 3 | import MarkdownPolicy from './MarkdownPolicy'; 4 | 5 | const EmptyComponent = () => { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | }; 12 | 13 | export default EmptyComponent; 14 | -------------------------------------------------------------------------------- /components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "styles/main.css", 9 | "baseColor": "slate", 10 | "cssVariables": false 11 | }, 12 | "aliases": { 13 | "components": "@/components", 14 | "utils": "@/lib/utils" 15 | } 16 | } -------------------------------------------------------------------------------- /app/privacy/page.tsx: -------------------------------------------------------------------------------- 1 | import Markdown from '@/components/ui/Markdown'; 2 | import React from 'react'; 3 | import MarkdownPolicy from './MarkdownPolicy'; 4 | 5 | const EmptyComponent = () => { 6 | return ( 7 |
8 | 9 |
10 | ); 11 | }; 12 | 13 | export default EmptyComponent; 14 | -------------------------------------------------------------------------------- /app/metrics/route.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from "@supabase/supabase-js"; 2 | import { NextRequest, NextResponse } from "next/server"; 3 | import { Database } from "@/types_db"; 4 | 5 | export const runtime = 'edge' 6 | const supabase = createClient( 7 | process.env.SUPABASE_URL!, 8 | process.env.SUPABASE_KEY! 9 | ); 10 | export async function GET(req: NextRequest) { 11 | 12 | } 13 | 14 | 15 | -------------------------------------------------------------------------------- /ios/MediarAI/Models/Model.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Model.swift 3 | // MediarAI 4 | // 5 | // Created by Louis AB on 01/09/2023. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | class Model: ObservableObject { 12 | @Published var showTab: Bool = true 13 | @Published var showNav: Bool = true 14 | @Published var loggedIn: Bool = false 15 | @Published var showSafari: Bool = false 16 | } 17 | -------------------------------------------------------------------------------- /ios/MediarAI/Components/Colors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Colors.swift 3 | // MediarAI 4 | // 5 | // Created by Louis AB on 01/09/2023. 6 | // 7 | 8 | import Foundation 9 | import SwiftUI 10 | 11 | extension Color { 12 | static let darkText = Color(red: 0.06, green: 0.09, blue: 0.16) 13 | static let lightText = Color(red: 0.39, green: 0.45, blue: 0.55) 14 | static let borderGray = Color(red: 0.80, green: 0.84, blue: 0.88) 15 | } 16 | -------------------------------------------------------------------------------- /utils/stripe-client.ts: -------------------------------------------------------------------------------- 1 | import { loadStripe, Stripe } from '@stripe/stripe-js'; 2 | 3 | let stripePromise: Promise; 4 | 5 | export const getStripe = () => { 6 | if (!stripePromise) { 7 | stripePromise = loadStripe( 8 | process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY_LIVE ?? 9 | process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY ?? 10 | '' 11 | ); 12 | } 13 | 14 | return stripePromise; 15 | }; 16 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "crons": [ 3 | { 4 | "path": "/api/multi-insights", 5 | "schedule": "0 1 * * *" 6 | }, 7 | { 8 | "path": "/api/multi-static-prompts", 9 | "schedule": "0 15 * * *" 10 | }, 11 | { 12 | "path": "/api/multi-prompts", 13 | "schedule": "0 */2 * * *" 14 | }, 15 | { 16 | "path": "/api/multi-metriport", 17 | "schedule": "*/10 * * * *" 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /ios/MediarAI.xcodeproj/xcuserdata/louis.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MediarAI.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/custom-highlight-start.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import { H } from '@highlight-run/next/client' 3 | import { useEffect } from 'react'; 4 | 5 | export function CustomHighlightStart() { 6 | useEffect(() => { 7 | const shouldStartHighlight = window.location.hostname.includes('mediar.ai') 8 | 9 | if (shouldStartHighlight) { 10 | H.start(); 11 | console.log('started highlight') 12 | 13 | return () => { 14 | H.stop() 15 | } 16 | } 17 | }) 18 | 19 | return null 20 | } 21 | 22 | -------------------------------------------------------------------------------- /app/posthog-provider.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | import posthog from 'posthog-js' 3 | import { PostHogProvider } from 'posthog-js/react' 4 | 5 | if (typeof window !== 'undefined') { 6 | posthog.init('phc_V7co1flWmfnd9Hd6LSyPRau9sARsxMEiOrmNvGeUhbJ', { 7 | api_host: 'https://app.posthog.com' 8 | }) 9 | } 10 | 11 | export default function PHProvider({ children }: { 12 | children: React.ReactNode; 13 | }) { 14 | return {children} 15 | } -------------------------------------------------------------------------------- /app/api/whatsapp-verification/route.ts: -------------------------------------------------------------------------------- 1 | import { startWhatsAppVerification } from "@/app/whatsapp-server"; 2 | 3 | export const runtime = 'edge' 4 | 5 | export async function POST(req: Request) { 6 | const { to } = await req.json() 7 | try { 8 | await startWhatsAppVerification(to); 9 | return new Response("Success", { status: 200 }); 10 | } 11 | catch (error) { 12 | console.log("Error:", error); 13 | return new Response("Error", { status: 500 }); 14 | } 15 | } -------------------------------------------------------------------------------- /instrumentation.ts: -------------------------------------------------------------------------------- 1 | // instrumentation.ts 2 | 3 | export async function register() { 4 | if (process.env.NEXT_RUNTIME === 'nodejs') { 5 | /** Conditional import required for use with Next middleware to avoid a webpack error 6 | * https://nextjs.org/docs/pages/building-your-application/routing/middleware */ 7 | const { registerHighlight } = await import('@highlight-run/next/server') 8 | 9 | registerHighlight({ 10 | projectID: process.env.NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID!, 11 | }) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/auth/sign-out/route.ts: -------------------------------------------------------------------------------- 1 | import { getURL } from '@/utils/helpers' 2 | import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' 3 | import { cookies } from 'next/headers' 4 | import { NextResponse } from 'next/server' 5 | 6 | export const dynamic = 'force-dynamic' 7 | 8 | export async function POST(request: Request) { 9 | const supabase = createRouteHandlerClient({ cookies }) 10 | 11 | await supabase.auth.signOut() 12 | 13 | return NextResponse.redirect(`${getURL()}/signin`, { 14 | status: 301, 15 | }) 16 | } -------------------------------------------------------------------------------- /app/api/evervault/route.ts: -------------------------------------------------------------------------------- 1 | import { llm } from "@/utils/llm" 2 | 3 | 4 | export const maxDuration = 300 5 | 6 | export async function POST(req: Request) { 7 | const body = await req.json() 8 | 9 | console.log('evervaulty', body) 10 | const prompt = body.prompt.trim() + "\n\nAssistant:" 11 | const response = await llm(prompt, 3, body.model || "claude-2", body.max_tokens_to_sample || 500) 12 | return new Response(JSON.stringify({ completion: response }), { 13 | headers: { 'content-type': 'application/json' }, 14 | }) 15 | } 16 | 17 | -------------------------------------------------------------------------------- /components/ui/Navbar/Navbar.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | @apply sticky top-0 bg-white z-40 transition-all duration-150 h-16 md:h-20; 3 | } 4 | 5 | .link { 6 | @apply inline-flex items-center leading-6 font-medium transition ease-in-out duration-75 cursor-pointer text-gray-700 rounded-md p-1; 7 | } 8 | 9 | .link:hover { 10 | @apply text-gray-900; 11 | } 12 | 13 | .link:focus { 14 | @apply outline-none text-gray-900 ring-2 ring-blue-500 ring-opacity-50; 15 | } 16 | 17 | .logo { 18 | @apply cursor-pointer transform duration-100 ease-in-out; 19 | } -------------------------------------------------------------------------------- /ios/MediarAI/Components/OTPTextField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OTPTextField.swift 3 | // OTPField 4 | // 5 | // Created by Satyenkumar Mourya on 23/06/19. 6 | // Copyright © 2019 Satyenkumar Mourya. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class OTPTextField: UITextField { 13 | 14 | weak var previousTextField: OTPTextField? 15 | weak var nextTextField: OTPTextField? 16 | 17 | override public func deleteBackward(){ 18 | text = "" 19 | previousTextField?.becomeFirstResponder() 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /app/pricing/page.tsx: -------------------------------------------------------------------------------- 1 | import Pricing from '@/components/Pricing'; 2 | import { 3 | getSession, 4 | getSubscription, 5 | getActiveProductsWithPrices, 6 | } from '@/app/supabase-server'; 7 | import React from 'react' 8 | import PricingPlan from './PricingPlan'; 9 | 10 | 11 | export default async function PricingPage() { 12 | const [session, products, subscription] = await Promise.all([getSession(), getActiveProductsWithPrices(), getSubscription()]); 13 | return ( 14 | 15 | ); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /ios/MediarAI/MediarAI.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.developer.applesignin 6 | 7 | Default 8 | 9 | com.apple.developer.healthkit 10 | 11 | com.apple.developer.healthkit.access 12 | 13 | health-records 14 | 15 | com.apple.developer.healthkit.background-delivery 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/_examples/route-handler/route.ts: -------------------------------------------------------------------------------- 1 | // TODO: Duplicate or move this file outside the `_examples` folder to make it a route 2 | 3 | import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' 4 | import { cookies } from 'next/headers' 5 | import { NextResponse } from 'next/server' 6 | 7 | export const dynamic = 'force-dynamic' 8 | 9 | export async function GET() { 10 | // Create a Supabase client configured to use cookies 11 | const supabase = createRouteHandlerClient({ cookies }) 12 | const { data: todos } = await supabase.from('todos').select() 13 | 14 | return NextResponse.json(todos) 15 | } 16 | -------------------------------------------------------------------------------- /app/signin/messages.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { useSearchParams } from 'next/navigation' 4 | 5 | export default function Messages() { 6 | const searchParams = useSearchParams() 7 | const error = searchParams.get('error') 8 | const message = searchParams.get('message') 9 | return ( 10 | <> 11 | {error && ( 12 |

13 | {error} 14 |

15 | )} 16 | {message && ( 17 |

18 | {message} 19 |

20 | )} 21 | 22 | ) 23 | } -------------------------------------------------------------------------------- /app/_examples/server-component/page.tsx: -------------------------------------------------------------------------------- 1 | // TODO: Duplicate or move this file outside the `_examples` folder to make it a route 2 | 3 | import { createServerComponentClient } from '@supabase/auth-helpers-nextjs' 4 | import { cookies } from 'next/headers' 5 | 6 | export const dynamic = 'force-dynamic' 7 | 8 | export default async function ServerComponent() { 9 | // Create a Supabase client configured to use cookies 10 | const supabase = createServerComponentClient({ cookies }) 11 | 12 | const { data: todos } = await supabase.from('todos').select() 13 | 14 | return
{JSON.stringify(todos, null, 2)}
15 | } 16 | -------------------------------------------------------------------------------- /ios/MediarAI/Constants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constants.swift 3 | // MediarAI 4 | // 5 | // Created by Louis AB on 01/09/2023. 6 | // 7 | 8 | import Foundation 9 | 10 | public enum Constants { 11 | static let supabaseUrl = "https://zfjdysuchblioghfuluq.supabase.co" 12 | static let supabaseKey = 13 | "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InpmamR5c3VjaGJsaW9naGZ1bHVxIiwicm9sZSI6ImFub24iLCJpYXQiOjE2OTAyMjAxNzMsImV4cCI6MjAwNTc5NjE3M30.AmjJc-va_Ohm3EdNkc9sq_OiFImrdb5S4LWWVyP0t_M" 14 | static let metriportKey = 15 | "M25CbWhBVFhCNkRTeUt4XzhTM0h2Ojg2YWY5ZGIzLWZlMzgtNDQ2OS05MzVmLWFmNGU3NzU3OWE3MQ" 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 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.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | 36 | # editors 37 | .vscode 38 | 39 | 40 | 41 | # Jupyter hacks 42 | *.ipynb 43 | 44 | *.csv 45 | 46 | -------------------------------------------------------------------------------- /app/dashboard/SaveTimezone.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import React, { useEffect } from 'react'; 4 | 5 | interface SaveTimezoneProps { 6 | saveUserTimezoneServer: (userId: string, timezone: string) => Promise; 7 | userId?: string; 8 | } 9 | 10 | const SaveTimezone: React.FC = ({ saveUserTimezoneServer, userId }) => { 11 | useEffect(() => { 12 | if (!userId) { 13 | return; 14 | } 15 | saveUserTimezoneServer(userId, Intl.DateTimeFormat().resolvedOptions().timeZone); 16 | }, [saveUserTimezoneServer, userId]); 17 | 18 | return null; 19 | } 20 | 21 | export default SaveTimezone; 22 | -------------------------------------------------------------------------------- /app/onboarding/neurosity/page.tsx: -------------------------------------------------------------------------------- 1 | import { redirect } from "next/navigation"; 2 | import { getSession } from "../../supabase-server"; 3 | import NeurosityConnect from "@/components/NeurosityConnect"; 4 | 5 | 6 | 7 | export default async function Onboarding() { 8 | const session = await getSession() 9 | if (!session?.user?.id) { 10 | return redirect('/signin'); 11 | } 12 | return ( 13 | // center stuff vertically and horizontally 14 |
15 | 16 |
17 | ) 18 | } 19 | 20 | -------------------------------------------------------------------------------- /components/ui/LoadingDots/LoadingDots.module.css: -------------------------------------------------------------------------------- 1 | .root { 2 | @apply inline-flex text-center items-center leading-7; 3 | } 4 | 5 | .root span { 6 | @apply bg-zinc-200 rounded-full h-2 w-2; 7 | animation-name: blink; 8 | animation-duration: 1.4s; 9 | animation-iteration-count: infinite; 10 | animation-fill-mode: both; 11 | margin: 0 2px; 12 | } 13 | 14 | .root span:nth-of-type(2) { 15 | animation-delay: 0.2s; 16 | } 17 | 18 | .root span:nth-of-type(3) { 19 | animation-delay: 0.4s; 20 | } 21 | 22 | @keyframes blink { 23 | 0% { 24 | opacity: 0.2; 25 | } 26 | 20% { 27 | opacity: 1; 28 | } 29 | 100% { 30 | opacity: 0.2; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ios/MediarAI.xcodeproj/xcuserdata/louisbeaumont.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MediarAI.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | BF5FC02F2AA2461A00BD9125 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /.env.local.example: -------------------------------------------------------------------------------- 1 | # Update these with your Supabase details from your project settings > API 2 | NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co 3 | NEXT_PUBLIC_SUPABASE_ANON_KEY= 4 | SUPABASE_SERVICE_ROLE_KEY= 5 | 6 | # Update these with your Stripe credentials from https://dashboard.stripe.com/apikeys 7 | NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_1234 8 | STRIPE_SECRET_KEY=sk_test_1234 9 | STRIPE_WEBHOOK_SECRET=whsec_1234 10 | 11 | # Update this with your stable site URL only for the production environment. 12 | NEXT_PUBLIC_SITE_URL=https://your-deployment-url.vercel.app 13 | 14 | OPENAI_API_KEY=xxxxxxx 15 | KV_REST_API_URL=xxxxxxx 16 | KV_REST_API_TOKEN=xxxxxxx 17 | -------------------------------------------------------------------------------- /components/icons/Logo.tsx: -------------------------------------------------------------------------------- 1 | const Logo = ({ className = '', ...props }) => ( 2 | 11 | 12 | 18 | 19 | ); 20 | 21 | export default Logo; 22 | -------------------------------------------------------------------------------- /app/onboarding/intro/GoToButton.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Button } from "@/components/ui/button"; 4 | import { Session } from "@supabase/supabase-js"; 5 | import { useRouter } from "next/navigation"; 6 | 7 | interface Props { 8 | text: string; 9 | path: string; 10 | session: Session; 11 | onClick?: (userId: string) => void; 12 | } 13 | export const GoToButton = ({ text, path, session, onClick }: Props) => { 14 | const router = useRouter(); 15 | return ( 16 | 24 | ) 25 | } -------------------------------------------------------------------------------- /app/dashboard/PosthogMail.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { Session } from "@supabase/supabase-js" 4 | import { Crisp } from "crisp-sdk-web" 5 | import posthog from "posthog-js" 6 | import { useEffect } from "react" 7 | import { H } from '@highlight-run/next/client'; 8 | 9 | export const PosthogMail = ({ session }: { session: Session }) => { 10 | useEffect(() => { 11 | if (!session?.user?.id) return 12 | posthog.identify(session.user.id, { 13 | email: session.user.email, 14 | }) 15 | Crisp.user.setEmail(session.user.email!); 16 | H.identify(session.user.email!, { 17 | id: session.user.id, 18 | }); 19 | }, [session]) 20 | 21 | return null; 22 | } 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/_examples/client-component/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | // TODO: Duplicate or move this file outside the `_examples` folder to make it a route 4 | 5 | import { createClientComponentClient } from '@supabase/auth-helpers-nextjs' 6 | import { useEffect, useState } from 'react' 7 | 8 | export default function ClientComponent() { 9 | const [todos, setTodos] = useState([]) 10 | const supabase = createClientComponentClient() 11 | 12 | useEffect(() => { 13 | const getTodos = async () => { 14 | const { data } = await supabase.from('todos').select() 15 | if (data) { 16 | setTodos(data) 17 | } 18 | } 19 | 20 | getTodos() 21 | }, [supabase, setTodos]) 22 | 23 | return
{JSON.stringify(todos, null, 2)}
24 | } 25 | -------------------------------------------------------------------------------- /app/api/completion/route.ts: -------------------------------------------------------------------------------- 1 | import { AnthropicStream, StreamingTextResponse } from 'ai' 2 | 3 | 4 | export const runtime = 'edge' 5 | 6 | export async function POST(req: Request) { 7 | const { prompt } = await req.json() 8 | 9 | const response = await fetch('https://api.anthropic.com/v1/complete', { 10 | method: 'POST', 11 | headers: { 12 | 'Content-Type': 'application/json', 13 | 'x-api-key': process.env.ANTHROPIC_API_KEY! 14 | }, 15 | body: JSON.stringify({ 16 | prompt: prompt, 17 | model: 'claude-2', 18 | max_tokens_to_sample: 1000, 19 | stream: true 20 | }) 21 | }) 22 | 23 | 24 | const stream = AnthropicStream(response) 25 | 26 | // Respond with the stream 27 | return new StreamingTextResponse(stream) 28 | } 29 | 30 | -------------------------------------------------------------------------------- /app/dev/page.tsx: -------------------------------------------------------------------------------- 1 | export default function Home() { 2 | 3 | return ( 4 |
5 |
6 | 7 |
8 |

9 | Want to access the private beta API that provides the OpenAI-like multimodal mind-body models? 10 |

11 |

12 | Reach out at louis@mediar.ai 13 |

14 |
15 | 16 |
17 |
18 | ) 19 | 20 | } 21 | 22 | -------------------------------------------------------------------------------- /components/ui/Navbar/SignOutButton.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useSupabase } from '@/app/supabase-provider'; 4 | import { useRouter } from 'next/navigation'; 5 | 6 | import s from './Navbar.module.css'; 7 | import { Neurosity } from '@neurosity/sdk'; 8 | const neurosity = new Neurosity() 9 | export default function SignOutButton() { 10 | const router = useRouter(); 11 | const { supabase } = useSupabase(); 12 | return ( 13 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as LabelPrimitive from "@radix-ui/react-label" 5 | import { cva, type VariantProps } from "class-variance-authority" 6 | 7 | import { cn } from "@/lib/utils" 8 | 9 | const labelVariants = cva( 10 | "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /ios/MediarAI/Models/HealthModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HealthKitModel.swift 3 | // MediarAI 4 | // 5 | // Created by Louis AB on 02/09/2023. 6 | // 7 | 8 | import Foundation 9 | 10 | struct HealthData: Codable { 11 | var activitiesData: [Activity] 12 | var sleepData: SleepData 13 | var weightData: Float 14 | var heartData: HeartData 15 | var mindfulnessData: MindfulnessData 16 | } 17 | 18 | struct Activity: Codable { 19 | var activityType: String 20 | var activityDuration: Double 21 | var activityCalories: Double 22 | var activityTime: Date 23 | } 24 | 25 | struct SleepData: Codable { 26 | var sleptHours: Double 27 | } 28 | 29 | struct HeartData: Codable { 30 | var avgBpm: Double 31 | var maxBpm: Double 32 | var minBpm: Double 33 | } 34 | 35 | struct MindfulnessData: Codable { 36 | var status: String 37 | } 38 | -------------------------------------------------------------------------------- /ios/MediarAI/Components/OTPFieldView.swift: -------------------------------------------------------------------------------- 1 | import SwiftUI 2 | 3 | struct OTPFieldView: UIViewRepresentable { 4 | @Binding var otp: String 5 | 6 | func makeUIView(context: Context) -> OTPStackView { 7 | let otpView = OTPStackView() 8 | otpView.delegate = context.coordinator 9 | return otpView 10 | } 11 | 12 | func updateUIView(_ uiView: OTPStackView, context: Context) { 13 | // Update your view here 14 | } 15 | 16 | func makeCoordinator() -> Coordinator { 17 | Coordinator(self) 18 | } 19 | 20 | class Coordinator: NSObject, OTPDelegate { 21 | var parent: OTPFieldView 22 | 23 | init(_ parent: OTPFieldView) { 24 | self.parent = parent 25 | } 26 | 27 | func didChangeValidity(isValid: Bool) { 28 | // Handle validity change 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/_examples/server-action/page.tsx: -------------------------------------------------------------------------------- 1 | // TODO: Duplicate or move this file outside the `_examples` folder to make it a route 2 | 3 | import { createServerActionClient } from '@supabase/auth-helpers-nextjs' 4 | import { revalidatePath } from 'next/cache' 5 | import { cookies } from 'next/headers' 6 | 7 | export const dynamic = 'force-dynamic' 8 | 9 | export default async function ServerAction() { 10 | const addTodo = async (formData: FormData) => { 11 | 'use server' 12 | const title = formData.get('title') 13 | 14 | if (title) { 15 | // Create a Supabase client configured to use cookies 16 | const supabase = createServerActionClient({ cookies }) 17 | await supabase.from('todos').insert({ title }) 18 | revalidatePath('/server-action-example') 19 | } 20 | } 21 | 22 | return ( 23 |
24 | 25 |
26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /app/signup/page.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image'; 2 | import { redirect } from 'next/navigation'; 3 | import SignUpForm from '@/app/signup/SignUpForm'; 4 | 5 | export default async function SignIn() { 6 | return redirect('/signin'); 7 | 8 | 9 | return ( 10 |
11 | 12 |
13 |

Create an account

14 | 15 |
16 | 17 | {/* */} 18 | neurosity 23 |
24 | {/* */} 25 | 26 |
27 |
28 | ); 29 | } 30 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "moduleResolution": "node", 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "baseUrl": ".", 21 | "paths": { 22 | "@/*": [ 23 | "./*" 24 | ] 25 | }, 26 | "incremental": true, 27 | "plugins": [ 28 | { 29 | "name": "next" 30 | } 31 | ] 32 | }, 33 | "include": [ 34 | "next-env.d.ts", 35 | "**/*.ts", 36 | "**/*.tsx", 37 | ".next/types/**/*.ts" 38 | ], 39 | "exclude": [ 40 | "node_modules", 41 | "supabase" 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /app/auth/sign-in/route.ts: -------------------------------------------------------------------------------- 1 | import { getURL } from '@/utils/helpers' 2 | import { createRouteHandlerClient } from '@supabase/auth-helpers-nextjs' 3 | import { cookies } from 'next/headers' 4 | import { NextResponse } from 'next/server' 5 | 6 | export const dynamic = 'force-dynamic' 7 | 8 | export async function POST(request: Request) { 9 | const formData = await request.formData() 10 | const email = String(formData.get('email')) 11 | const password = String(formData.get('password')) 12 | const supabase = createRouteHandlerClient({ cookies }) 13 | 14 | const { error } = await supabase.auth.signInWithPassword({ 15 | email, 16 | password, 17 | }) 18 | 19 | if (error) { 20 | return NextResponse.redirect( 21 | `${getURL()}/signin?error=Could not authenticate user`, 22 | { 23 | status: 301, 24 | } 25 | ) 26 | } 27 | 28 | return NextResponse.redirect(getURL(), { 29 | status: 301, 30 | }) 31 | } -------------------------------------------------------------------------------- /components/ui/feedback.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | 3 | const BoardToken = 'YOUR_BOARD_TOKEN'; 4 | 5 | const Feedback = () => { 6 | useEffect(() => { 7 | (function(w,d,i,s){function l(){if(!d.getElementById(i)){var f=d.getElementsByTagName(s)[0],e=d.createElement(s);e.type="text/javascript",e.async=!0,e.src="https://canny.io/sdk.js",f.parentNode.insertBefore(e,f)}}if("function"!=typeof w.Canny){var c=function(){c.q.push(arguments)};c.q=[],w.Canny=c,"complete"===d.readyState?l():w.attachEvent?w.attachEvent("onload",l):w.addEventListener("load",l,!1)}})(window,document,"canny-jssdk","script"); 8 | 9 | Canny('render', { 10 | boardToken: BoardToken, 11 | basePath: null, // See step 2 12 | ssoToken: null, // See step 3, 13 | theme: 'light', // options: light [default], dark, auto 14 | }); 15 | }, []); 16 | 17 | return ( 18 |
19 | ); 20 | } 21 | 22 | export default Feedback; -------------------------------------------------------------------------------- /components/ui/progress.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import * as React from "react" 4 | import * as ProgressPrimitive from "@radix-ui/react-progress" 5 | 6 | import { cn } from "@/lib/utils" 7 | 8 | const Progress = React.forwardRef< 9 | React.ElementRef, 10 | React.ComponentPropsWithoutRef 11 | >(({ className, value, ...props }, ref) => ( 12 | 20 | 24 | 25 | )) 26 | Progress.displayName = ProgressPrimitive.Root.displayName 27 | 28 | export { Progress } 29 | -------------------------------------------------------------------------------- /components/ui/toaster.tsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import { 4 | Toast, 5 | ToastClose, 6 | ToastDescription, 7 | ToastProvider, 8 | ToastTitle, 9 | ToastViewport, 10 | } from "@/components/ui/toast" 11 | import { useToast } from "@/components/ui/use-toast" 12 | 13 | export function Toaster() { 14 | const { toasts } = useToast() 15 | 16 | return ( 17 | 18 | {toasts.map(function ({ id, title, description, action, ...props }) { 19 | return ( 20 | 21 |
22 | {title && {title}} 23 | {description && ( 24 | {description} 25 | )} 26 |
27 | {action} 28 | 29 |
30 | ) 31 | })} 32 | 33 |
34 | ) 35 | } 36 | -------------------------------------------------------------------------------- /app/api/whatsapp-verification-otp/route.ts: -------------------------------------------------------------------------------- 1 | import { checkWhatsAppVerification } from "@/app/whatsapp-server"; 2 | 3 | export const runtime = 'edge' 4 | 5 | export async function POST(req: Request) { 6 | const { to, code, id } = await req.json() 7 | try { 8 | const response = await checkWhatsAppVerification(to, code); 9 | if (response.status !== 'approved') return new Response("Error", { status: 400 }); 10 | await fetch('/api/phone-verified', { 11 | method: 'POST', 12 | headers: { 13 | 'Content-Type': 'application/json' 14 | }, 15 | body: JSON.stringify({ 16 | user_id: id, 17 | phone: to, 18 | full_name: '' 19 | }) 20 | }); 21 | return new Response("Success", { status: 200 }); 22 | } 23 | catch (error) { 24 | console.log("Error:", error); 25 | return new Response("Error", { status: 500 }); 26 | } 27 | } -------------------------------------------------------------------------------- /app/signin/AuthUI.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { getURL } from '@/utils/helpers'; 4 | import { createClientComponentClient } from '@supabase/auth-helpers-nextjs'; 5 | import { Auth } from '@supabase/auth-ui-react'; 6 | import { ThemeSupa } from '@supabase/auth-ui-shared'; 7 | 8 | export default function AuthUI() { 9 | // const { supabase } = useSupabase(); 10 | const supabase = createClientComponentClient(); 11 | return ( 12 |
13 | 31 |
32 | ); 33 | } 34 | -------------------------------------------------------------------------------- /ios/MediarAI/AppView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppView.swift 3 | // MediarAI 4 | // 5 | // Created by Louis AB on 01/09/2023. 6 | // 7 | 8 | import Supabase 9 | import SwiftUI 10 | 11 | struct AppView: View { 12 | let client = SupabaseClient(supabaseURL: URL(string: Constants.supabaseUrl)!, 13 | supabaseKey: Constants.supabaseKey) 14 | 15 | @EnvironmentObject var model: Model 16 | 17 | func checkSession() { 18 | Task { 19 | do { 20 | _ = try await client.auth.session 21 | model.loggedIn = true 22 | } catch { 23 | print("### ignore if session not found: \(error)") 24 | } 25 | } 26 | } 27 | 28 | var body: some View { 29 | ContentView() 30 | .onAppear { 31 | checkSession() 32 | } 33 | } 34 | } 35 | 36 | struct AppView_Previews: PreviewProvider { 37 | static var previews: some View { 38 | AppView() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ios/MediarAI/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BGTaskSchedulerPermittedIdentifiers 6 | 7 | ai.mediar.syncHealthData 8 | 9 | NSHealthShareUsageDescription 10 | Share health usage with this app. 11 | 12 | CFBundleURLTypes 13 | 14 | 15 | CFBundleTypeRole 16 | Editor 17 | CFBundleURLName 18 | ai.mediar 19 | CFBundleURLSchemes 20 | 21 | mediar 22 | 23 | 24 | 25 | UIBackgroundModes 26 | 27 | fetch 28 | processing 29 | 30 | LSApplicationQueriesSchemes 31 | 32 | whatsapp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/account/ManageSubscriptionButton.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { Button } from '@/components/ui/button'; 4 | import { postData } from '@/utils/helpers'; 5 | 6 | import { Session } from '@supabase/supabase-js'; 7 | import { useRouter } from 'next/navigation'; 8 | 9 | interface Props { 10 | session: Session; 11 | } 12 | 13 | export default function ManageSubscriptionButton({ session }: Props) { 14 | const router = useRouter(); 15 | const redirectToCustomerPortal = async () => { 16 | try { 17 | const { url } = await postData({ 18 | url: '/api/create-portal-link' 19 | }); 20 | router.push(url); 21 | } catch (error) { 22 | if (error) return alert((error as Error).message); 23 | } 24 | }; 25 | 26 | return ( 27 |
28 | 34 |
35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | 3 | import { cn } from "@/lib/utils" 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |