diff --git a/.browserslistrc b/.browserslistrc new file mode 100644 index 0000000..dc3bc09 --- /dev/null +++ b/.browserslistrc @@ -0,0 +1,4 @@ +> 1% +last 2 versions +not dead +not ie 11 diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7053c49 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +[*.{js,jsx,ts,tsx,vue}] +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json new file mode 100644 index 0000000..dcf85eb --- /dev/null +++ b/.eslintrc-auto-import.json @@ -0,0 +1,72 @@ +{ + "globals": { + "Component": true, + "ComponentPublicInstance": true, + "ComputedRef": true, + "EffectScope": true, + "ExtractDefaultPropTypes": true, + "ExtractPropTypes": true, + "ExtractPublicPropTypes": true, + "InjectionKey": true, + "PropType": true, + "Ref": true, + "VNode": true, + "WritableComputedRef": true, + "computed": true, + "createApp": true, + "customRef": true, + "defineAsyncComponent": true, + "defineComponent": true, + "effectScope": true, + "getCurrentInstance": true, + "getCurrentScope": true, + "h": true, + "inject": true, + "isProxy": true, + "isReactive": true, + "isReadonly": true, + "isRef": true, + "markRaw": true, + "nextTick": true, + "onActivated": true, + "onBeforeMount": true, + "onBeforeRouteLeave": true, + "onBeforeRouteUpdate": true, + "onBeforeUnmount": true, + "onBeforeUpdate": true, + "onDeactivated": true, + "onErrorCaptured": true, + "onMounted": true, + "onRenderTracked": true, + "onRenderTriggered": true, + "onScopeDispose": true, + "onServerPrefetch": true, + "onUnmounted": true, + "onUpdated": true, + "provide": true, + "reactive": true, + "readonly": true, + "ref": true, + "resolveComponent": true, + "shallowReactive": true, + "shallowReadonly": true, + "shallowRef": true, + "toRaw": true, + "toRef": true, + "toRefs": true, + "toValue": true, + "triggerRef": true, + "unref": true, + "useAttrs": true, + "useCssModule": true, + "useCssVars": true, + "useLink": true, + "useRoute": true, + "useRouter": true, + "useSlots": true, + "watch": true, + "watchEffect": true, + "watchPostEffect": true, + "watchSyncEffect": true + } +} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..6e7e1b1 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,10 @@ +module.exports = { + root: true, + env: { + node: true, + }, + extends: [ + 'plugin:vue/vue3-essential', + 'eslint:recommended', + ], +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..00272c3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +.DS_Store +node_modules +/dist + +# local env files +.env.local +.env.*.local + +# Log files +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Editor directories and files +.idea +.vscode +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.env +.firebaserc diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..db4c6d9 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,2 @@ +dist +node_modules \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..b969984 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,20 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "htmlWhitespaceSensitivity": "css", + "insertPragma": false, + "jsxBracketSameLine": false, + "jsxSingleQuote": true, + "printWidth": 120, + "proseWrap": "preserve", + "quoteProps": "as-needed", + "requirePragma": false, + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "all", + "useTabs": false, + "vueIndentScriptAndStyle": false, + "endOfLine": "lf", + "singleAttributePerLine": true +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..2140d2d --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# 🌟 Vue ChatGPT AI + +✨ Powered by Modern Technologies + +- **Vue 3**: The versatile powerhouse that makes building dynamic user interfaces a breeze. +- **Vuetify 3**: Elevate your design with the elegance of Material Design, right at your fingertips. +- **Pinia**: Your go-to state management solution, as easy as pie, and just as satisfying. +- **Vite**: Lightning-fast build tool that ensures your development experience is as smooth as silk. +- **Firebase**: Real-time magic for your database and storage needs, ensuring your data is always in sync. +- **OpenAI**: The brains behind the operation, bringing sophisticated AI chat capabilities to your app. + +This project harnesses these cutting-edge technologies to deliver a seamless and responsive chat interface, enriched with AI-driven interactions. Enjoy the power of real-time data, sleek design, and intelligent conversation in one cohesive package. + +https://github.com/mustafacagri/vue3-chatgpt-ai-initial/assets/7488394/1fd4179b-f5d6-41a4-b2e4-4f1fc4b91a41 + +## 🚀 Features + +1. **Real-time AI Chat** + + - **OpenAI Integration**: Leverage the power of OpenAI's ChatGPT for intelligent and dynamic conversations. + - **Seamless Interaction**: Chat with the AI in real-time, with instant responses and fluid interaction. + +2. **Multi-format Support** + + - **Text Messages**: Exchange plain text messages effortlessly. + - **Image Support**: Send and receive images directly in the chat. + - **Audio Messages**: Record and share audio clips with ease. + +3. **Persistent Chat History** + + - **Local Storage**: Messages are saved locally, ensuring chat history is retained even after the page refreshes. + - **Firebase Realtime Database**: Store messages in the cloud for access across multiple devices. + +4. **User-friendly Interface** + + - **Vuetify 3**: Aesthetic and intuitive design with Material Design components. + - **Responsive Layout**: Optimized for both desktop and mobile devices. + +5. **State Management** + + - **Pinia**: Simplified and intuitive state management for maintaining the chat application state. + +6. **Efficient Development Workflow** + + - **Vite**: Fast build tool for an efficient development experience. + - **Modular Code Structure**: Clean and maintainable codebase with Vue 3's Composition API. + +7. **Security and Scalability** + + - **Firebase Authentication**: Secure user authentication to protect chat data. + - **Scalable Infrastructure**: Firebase backend ensures scalability and reliability as the user base grows. + +8. **File Management** + - **Firebase Storage**: Store and manage images and audio files securely in the cloud. + +## 🛠️ Setup Instructions + +### Cloning and Running Locally + +To get started, clone the repository and run the development server: + +```bash +git clone https://github.com/your/repository.git +cd repository-name +yarn install +yarn dev +``` + +The application will be running at http://localhost:5017/. + +### 🔥 Firebase Integration + +To fully utilize Firebase features: + +1. **Create a Firebase Project:** + + - Navigate to the [Firebase Console](https://console.firebase.google.com/) and create a new project. + +2. **Enable Firebase Services:** + + - In your Firebase project settings, enable Firebase Storage to store files like images and audio. + +3. **Obtain Firebase Configuration:** + - Go to your Firebase project settings and find the Firebase SDK snippet. You'll need to copy the configuration details including: + - `apiKey` + - `authDomain` + - `databaseURL` + - `projectId` + - `storageBucket` + - `messagingSenderId` + - `appId` +4. **Add Firebase Configuration to `.env` File:** + - Create a `.env` file in the root directory of your project if it doesn't exist. + - Add your Firebase configuration details to the `.env` file using the following format: + ```env + VITE_FIREBASE_API_KEY=your-firebase-api-key + VITE_FIREBASE_AUTH_DOMAIN=your-auth-domain + VITE_FIREBASE_DATABASE_URL=your-database-url + VITE_FIREBASE_PROJECT_ID=your-firebase-project-id + VITE_FIREBASE_STORAGE_BUCKET=your-firebase-storage-bucket + VITE_FIREBASE_MESSAGING_SENDER_ID=your-messaging-sender-id + VITE_FIREBASE_APP_ID=your-firebase-app-id + ``` + +### 🗄️ Local Storage + +Messages are stored in local storage using the `useStorage` hook from `@vueuse/core`. This ensures that chat history persists even when the page is refreshed. + +### 🤖 How to Obtain OpenAI API Key + +1. **Sign up for OpenAI API:** + + - Go to the [OpenAI website](https://www.openai.com/) and sign up for an account. + +2. **Generate API Key:** + + - After signing in, navigate to your account settings or API section to generate a new API key specifically for ChatGPT. + - Copy the generated API key. + +3. **Add OpenAI API Key to `.env` File:** + - Open or create the `.env` file in your project directory. + - Add your OpenAI API key to the `.env` file using the following format: + ```env + VITE_OPENAI_API_KEY=your-openai-api-key + ``` + +## How can I support? 🌟 + +- ⭐ Star my GitHub repo +- 🛠 Create pull requests, submit bugs, suggest new features or updates diff --git a/database.rules.json b/database.rules.json new file mode 100644 index 0000000..f54493d --- /dev/null +++ b/database.rules.json @@ -0,0 +1,7 @@ +{ + /* Visit https://firebase.google.com/docs/database/security to learn more about security rules. */ + "rules": { + ".read": false, + ".write": false + } +} \ No newline at end of file diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..a4cf09a --- /dev/null +++ b/firebase.json @@ -0,0 +1,8 @@ +{ + "database": { + "rules": "database.rules.json" + }, + "storage": { + "rules": "storage.rules" + } +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..d0a1b85 --- /dev/null +++ b/index.html @@ -0,0 +1,40 @@ + + + + + + Vue - ChatGPT AI + + + + + + + +
+ + + diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 0000000..dad0634 --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "allowJs": true, + "target": "es5", + "module": "esnext", + "baseUrl": "./", + "moduleResolution": "bundler", + "paths": { + "@/*": [ + "src/*" + ] + }, + "lib": [ + "esnext", + "dom", + "dom.iterable", + "scripthost" + ] + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..366e973 --- /dev/null +++ b/package.json @@ -0,0 +1,46 @@ +{ + "name": "vue3-chatgpt-ai", + "version": "0.0.1", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "lint": "eslint . --fix --ignore-path .gitignore" + }, + "dependencies": { + "@firebase/app": "^0.10.3", + "@firebase/database": "^1.0.5", + "@firebase/storage": "^0.12.5", + "@mdi/font": "7.4.47", + "@vueuse/core": "^10.9.0", + "core-js": "^3.37.0", + "lodash": "^4.17.21", + "moment": "^2.30.1", + "openai": "^4.45.0", + "roboto-fontface": "*", + "vite-plugin-pages": "^0.32.1", + "vue": "^3.4.27", + "vue-i18n": "^9.13.1", + "vuetify": "^3.6.5" + }, + "devDependencies": { + "@vitejs/plugin-vue": "^5.0.4", + "eslint": "^9.2.0", + "eslint-config-standard": "^17.1.0", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-n": "^17.6.0", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-vue": "^9.26.0", + "pinia": "^2.1.7", + "sass": "^1.77.1", + "unplugin-auto-import": "^0.17.6", + "unplugin-fonts": "^1.1.1", + "unplugin-vue-components": "^0.27.0", + "unplugin-vue-router": "^0.8.6", + "vite": "^5.2.11", + "vite-plugin-vue-layouts": "^0.11.0", + "vite-plugin-vuetify": "^2.0.3", + "vue-router": "^4.3.2" + } +} diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png new file mode 100644 index 0000000..a773286 Binary files /dev/null and b/public/android-chrome-192x192.png differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png new file mode 100644 index 0000000..b3b0d73 Binary files /dev/null and b/public/android-chrome-512x512.png differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..270d8a8 Binary files /dev/null and b/public/apple-touch-icon.png differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png new file mode 100644 index 0000000..83efc65 Binary files /dev/null and b/public/favicon-16x16.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png new file mode 100644 index 0000000..3a4d97d Binary files /dev/null and b/public/favicon-32x32.png differ diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..7827b5a Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/site.webmanifest b/public/site.webmanifest new file mode 100644 index 0000000..45dc8a2 --- /dev/null +++ b/public/site.webmanifest @@ -0,0 +1 @@ +{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..6cd0998 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,10 @@ + + + diff --git a/src/CONSTANTS.js b/src/CONSTANTS.js new file mode 100644 index 0000000..f27ff7e --- /dev/null +++ b/src/CONSTANTS.js @@ -0,0 +1,54 @@ +export default { + defaultPage: 'text', + pages: { + text: 'text', + image: 'image', + audio: 'audio', + }, + defaultModels: { + text: 'gpt-3.5-turbo', + image: 'dall-e-2', + audio: 'tts-1', + }, + image: { + sizes: { 'dall-e-2': ['256x256', '512x512', '1024x1024'], 'dall-e-3': ['1024x1024', '1792x1024', '1024x1792 '] }, + defaultSizes: { 'dall-e-2': '256x256', 'dall-e-3': '1024x1024' }, + }, + audio: { + voices: ['alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer'], + defaultVoice: 'alloy', + formats: ['mp3', 'opus', 'aac', 'flac', 'wav', 'pcm'], + defaultFormat: 'mp3', + mimeMaps: { + mp3: 'audio/mp3', + opus: 'audio/ogg', + aac: 'audio/aac', + flac: 'audio/flac', + wav: 'audio/wav', + pcm: 'audio/L16', + }, + speeds: [0.25, 1, 4], + defaultSpeed: 1, + }, + models: { + text: [ + 'gpt-3.5-turbo', + 'gpt-3.5-turbo-0125', + 'gpt-3.5-turbo-1106', + 'gpt-3.5-turbo-instruct ', + 'gpt-4-turbo', + 'gpt-4-turbo-2024-04-09', + 'gpt-4-turbo-preview', + 'gpt-4-0125-preview', + 'gpt-4-1106-preview', + 'gpt-4-0613', + 'gpt-4-vision-preview', + 'gpt-4-1106-vision-preview', + 'gpt-4', + 'gpt-4-32k', + 'gpt-4-32k-0613', + ], + image: ['dall-e-2', 'dall-e-3'], + audio: ['tts-1', 'tts-1-hd'], + }, +} diff --git a/src/components/PageContainer.vue b/src/components/PageContainer.vue new file mode 100644 index 0000000..2023e54 --- /dev/null +++ b/src/components/PageContainer.vue @@ -0,0 +1,260 @@ +