diff --git a/imagecreator/frontend/index.html b/imagecreator/frontend/index.html
new file mode 100644
index 0000000..7df6759
--- /dev/null
+++ b/imagecreator/frontend/index.html
@@ -0,0 +1,12 @@
+
+
+
+
+
+ Image Creator
+
+
+
+
+
+
diff --git a/imagecreator/frontend/package.json b/imagecreator/frontend/package.json
new file mode 100644
index 0000000..a6e06ed
--- /dev/null
+++ b/imagecreator/frontend/package.json
@@ -0,0 +1,27 @@
+{
+ "name": "imagecreator-frontend",
+ "version": "1.0.0",
+ "private": true,
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vue-tsc && vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "vue": "^3.4.0",
+ "vue-router": "^4.2.0",
+ "pinia": "^2.1.0",
+ "axios": "^1.6.0",
+ "naive-ui": "^2.38.0"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.0",
+ "typescript": "^5.3.0",
+ "vite": "^5.0.0",
+ "vue-tsc": "^1.8.0",
+ "tailwindcss": "^3.4.0",
+ "autoprefixer": "^10.4.0",
+ "postcss": "^8.4.0"
+ }
+}
diff --git a/imagecreator/frontend/src/App.vue b/imagecreator/frontend/src/App.vue
new file mode 100644
index 0000000..a0ac050
--- /dev/null
+++ b/imagecreator/frontend/src/App.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/imagecreator/frontend/src/api/index.ts b/imagecreator/frontend/src/api/index.ts
new file mode 100644
index 0000000..6792861
--- /dev/null
+++ b/imagecreator/frontend/src/api/index.ts
@@ -0,0 +1,28 @@
+// src/api/index.ts
+import axios from 'axios'
+
+const api = axios.create({
+ baseURL: '/api',
+ timeout: 30000,
+})
+
+api.interceptors.request.use((config) => {
+ const token = localStorage.getItem('access_token')
+ if (token) {
+ config.headers.Authorization = `Bearer ${token}`
+ }
+ return config
+})
+
+api.interceptors.response.use(
+ (response) => response,
+ async (error) => {
+ if (error.response?.status === 401) {
+ localStorage.removeItem('access_token')
+ window.location.href = '/login'
+ }
+ return Promise.reject(error)
+ }
+)
+
+export default api
diff --git a/imagecreator/frontend/src/main.ts b/imagecreator/frontend/src/main.ts
new file mode 100644
index 0000000..038fb0f
--- /dev/null
+++ b/imagecreator/frontend/src/main.ts
@@ -0,0 +1,13 @@
+// src/main.ts
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import naive from 'naive-ui'
+import App from './App.vue'
+import router from './router'
+import './style.css'
+
+const app = createApp(App)
+app.use(createPinia())
+app.use(router)
+app.use(naive)
+app.mount('#app')
diff --git a/imagecreator/frontend/src/router/index.ts b/imagecreator/frontend/src/router/index.ts
new file mode 100644
index 0000000..f5d141e
--- /dev/null
+++ b/imagecreator/frontend/src/router/index.ts
@@ -0,0 +1,27 @@
+// src/router/index.ts
+import { createRouter, createWebHistory } from 'vue-router'
+
+const routes = [
+ { path: '/login', name: 'Login', component: () => import('../views/Login.vue') },
+ { path: '/register', name: 'Register', component: () => import('../views/Register.vue') },
+ { path: '/', name: 'Home', component: () => import('../views/Home.vue'), meta: { requiresAuth: true } },
+ { path: '/history', name: 'History', component: () => import('../views/History.vue'), meta: { requiresAuth: true } },
+]
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes,
+})
+
+router.beforeEach((to, from, next) => {
+ const token = localStorage.getItem('access_token')
+ if (to.meta.requiresAuth && !token) {
+ next('/login')
+ } else if ((to.path === '/login' || to.path === '/register') && token) {
+ next('/')
+ } else {
+ next()
+ }
+})
+
+export default router
diff --git a/imagecreator/frontend/src/style.css b/imagecreator/frontend/src/style.css
new file mode 100644
index 0000000..7cca9c7
--- /dev/null
+++ b/imagecreator/frontend/src/style.css
@@ -0,0 +1,10 @@
+/* src/style.css */
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+body {
+ margin: 0;
+ padding: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
diff --git a/imagecreator/frontend/tailwind.config.js b/imagecreator/frontend/tailwind.config.js
new file mode 100644
index 0000000..750ad7c
--- /dev/null
+++ b/imagecreator/frontend/tailwind.config.js
@@ -0,0 +1,11 @@
+// tailwind.config.js
+export default {
+ content: [
+ "./index.html",
+ "./src/**/*.{vue,js,ts,jsx,tsx}",
+ ],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
diff --git a/imagecreator/frontend/vite.config.ts b/imagecreator/frontend/vite.config.ts
new file mode 100644
index 0000000..24da7f8
--- /dev/null
+++ b/imagecreator/frontend/vite.config.ts
@@ -0,0 +1,20 @@
+// vite.config.ts
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+export default defineConfig({
+ plugins: [vue()],
+ server: {
+ port: 5173,
+ proxy: {
+ '/api': {
+ target: 'http://localhost:8000',
+ changeOrigin: true
+ },
+ '/uploads': {
+ target: 'http://localhost:8000',
+ changeOrigin: true
+ }
+ }
+ }
+})