first commit
This commit is contained in:
No files matched your search
+24
@@ -0,0 +1,24 @@
|
|||||||
|
# Nuxt dev/build outputs
|
||||||
|
.output
|
||||||
|
.data
|
||||||
|
.nuxt
|
||||||
|
.nitro
|
||||||
|
.cache
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Node dependencies
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Misc
|
||||||
|
.DS_Store
|
||||||
|
.fleet
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# Local env files
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
# Nuxt Minimal Starter
|
||||||
|
|
||||||
|
Look at the [Nuxt documentation](https://nuxt.com/docs/getting-started/introduction) to learn more.
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
Make sure to install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn install
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Server
|
||||||
|
|
||||||
|
Start the development server on `http://localhost:3000`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run dev
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm dev
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn dev
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
Build the application for production:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm build
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Locally preview production build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run preview
|
||||||
|
|
||||||
|
# pnpm
|
||||||
|
pnpm preview
|
||||||
|
|
||||||
|
# yarn
|
||||||
|
yarn preview
|
||||||
|
|
||||||
|
# bun
|
||||||
|
bun run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<NuxtRouteAnnouncer />
|
||||||
|
<!-- <NuxtWelcome />-->
|
||||||
|
<!-- <v-btn @click="toggleTheme">toggle theme</v-btn>-->
|
||||||
|
<NuxtLayout>
|
||||||
|
<v-app>
|
||||||
|
<NuxtPage />
|
||||||
|
</v-app>
|
||||||
|
</NuxtLayout>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { useTheme } from 'vuetify'
|
||||||
|
|
||||||
|
const theme = useTheme()
|
||||||
|
|
||||||
|
function toggleTheme () {
|
||||||
|
theme.global.name.value = theme.global.current.value.dark ? 'light' : 'dark'
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
<!-- components/form/login.vue -->
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex flex-col items-start justify-center w-full">
|
||||||
|
<CommonLogo class="h-[40px]" />
|
||||||
|
<h2 class="font-bold text-xl md:text-2xl my-4">
|
||||||
|
Login user
|
||||||
|
</h2>
|
||||||
|
<form
|
||||||
|
@submit.prevent="handleSubmitLogin"
|
||||||
|
class="flex gap-4 flex-wrap w-full">
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<label class="text-sm block">Email address:</label>
|
||||||
|
<InputText
|
||||||
|
@blur="validateEmail"
|
||||||
|
v-model="data.email.value"
|
||||||
|
:invalid="!!data.email.error"
|
||||||
|
size="small" class="w-full" type="email" name="email" placeholder="Email address" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full">
|
||||||
|
<label class="text-sm block">Confirm Password:</label>
|
||||||
|
<InputText
|
||||||
|
@blur="validatePassword"
|
||||||
|
v-model="data.password.value"
|
||||||
|
:invalid="!!data.password.error"
|
||||||
|
size="small" class="w-full" type="password" name="password" placeholder="Password" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="error-message">
|
||||||
|
<p class="text-[12px] text-red-500" v-if="!!data.email.error">{{data.email.error}}</p>
|
||||||
|
<p class="text-[12px] text-red-500" v-if="!!data.password.error">{{data.password.error}}</p>
|
||||||
|
<p class="text-[12px] text-red-500" v-if="status === 'error'">
|
||||||
|
{{error}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="submit"
|
||||||
|
:loading="status === 'loading'"
|
||||||
|
:disabled="status === 'loading' || !isFormValid"
|
||||||
|
class="text-sm md:text-md w-full justify-center h-[48px]">Login</Button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import useLogin from "~/composables/auth/userAuth";
|
||||||
|
|
||||||
|
const { data , status, error, login , isFormValid, validatePassword, validateEmail } = useLogin()
|
||||||
|
|
||||||
|
async function handleSubmitLogin() {
|
||||||
|
await login()
|
||||||
|
if(status.value === 'success') {
|
||||||
|
navigateTo('/dashboard', { replace: true })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="css">
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// composables/auth/useLogin.ts
|
||||||
|
|
||||||
|
import {z, ZodError} from "zod";
|
||||||
|
import {computed} from "vue";
|
||||||
|
|
||||||
|
export default function useLogin() {
|
||||||
|
const data = reactive({
|
||||||
|
email: {
|
||||||
|
value: '',
|
||||||
|
error: ""
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
value: '',
|
||||||
|
error: ""
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const status = ref<'idle' | 'loading' | 'success' | 'error'>('idle');
|
||||||
|
const error = ref<string | null>(null);
|
||||||
|
|
||||||
|
const validateEmail = () => {
|
||||||
|
const schema = z.string().email("Invalid email address");
|
||||||
|
try {
|
||||||
|
schema.parse(data.email.value);
|
||||||
|
data.email.error = "";
|
||||||
|
} catch (e: unknown) {
|
||||||
|
data.email.error = (e as ZodError).issues[0].message;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const validatePassword = () => {
|
||||||
|
const schema = z.string({message: "Password is required"})
|
||||||
|
.min(6, "Password must be at least 6 characters");
|
||||||
|
try {
|
||||||
|
schema.parse(data.password.value);
|
||||||
|
data.password.error = "";
|
||||||
|
} catch (e: unknown) {
|
||||||
|
data.password.error = (e as ZodError).issues[0].message;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const login = async () => {
|
||||||
|
console.log("Will Login");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isFormValid = computed(() => {
|
||||||
|
return (
|
||||||
|
data.email.value !== "" &&
|
||||||
|
data.password.value !== "" &&
|
||||||
|
data.email.error === "" &&
|
||||||
|
data.password.error === ""
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
data, login, status, error, validateEmail, validatePassword, isFormValid
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
|
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'
|
||||||
|
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
build: {
|
||||||
|
transpile: ['vuetify'],
|
||||||
|
},
|
||||||
|
modules: [
|
||||||
|
(_options, nuxt) => {
|
||||||
|
nuxt.hooks.hook('vite:extendConfig', (config) => {
|
||||||
|
// @ts-expect-error
|
||||||
|
config.plugins.push(vuetify({ autoImport: true }))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
"@pinia/nuxt",
|
||||||
|
// 'nuxt-zod-i18n',
|
||||||
|
// '@nuxtjs/i18n'
|
||||||
|
],
|
||||||
|
|
||||||
|
vite: {
|
||||||
|
vue: {
|
||||||
|
template: {
|
||||||
|
transformAssetUrls,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
compatibilityDate: '2024-11-01',
|
||||||
|
devtools: { enabled: true }
|
||||||
|
})
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "pendaftaran",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxt build",
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"generate": "nuxt generate",
|
||||||
|
"preview": "nuxt preview",
|
||||||
|
"postinstall": "nuxt prepare"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxt/icon": "1.10.3",
|
||||||
|
"@pinia/nuxt": "^0.5.5",
|
||||||
|
"axios": "^1.7.7",
|
||||||
|
"nuxt": "^3.14.1592",
|
||||||
|
"nuxt-zod-i18n": "^1.11.2",
|
||||||
|
"pinia": "^2.2.4",
|
||||||
|
"sweetalert2": "^11.14.5",
|
||||||
|
"vue": "latest",
|
||||||
|
"vue-router": "latest",
|
||||||
|
"zod": "^3.24.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@mdi/font": "^7.4.47",
|
||||||
|
"@nuxtjs/google-fonts": "^3.0.0-1",
|
||||||
|
"@nuxtjs/tailwindcss": "^6.12.2",
|
||||||
|
"sass-embedded": "^1.80.5",
|
||||||
|
"vite-plugin-vuetify": "^2.0.4",
|
||||||
|
"vuetify": "^3.7.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
halaman utama
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<!-- <p>{{ message }}</p>-->
|
||||||
|
<p>{{ token }}</p><br>
|
||||||
|
<p>{{ user }}</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {defineComponent,ref} from 'vue';
|
||||||
|
import {useCookie} from "#app";
|
||||||
|
import {useAuthentication} from "~/store/login";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
const {userAuth} = useAuthentication()
|
||||||
|
const {user} = storeToRefs(useAuthentication())
|
||||||
|
|
||||||
|
const token = ref('')
|
||||||
|
token.value = useCookie('token');
|
||||||
|
// token.value = user;
|
||||||
|
const param = {
|
||||||
|
'token': useCookie('token'),
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
// await userAuth(useCookie('token'))
|
||||||
|
userAuth(param)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <div class="page">-->
|
||||||
|
<!-- well play-->
|
||||||
|
<!-- </div>-->
|
||||||
|
<!-- <Login />-->
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
sdaasd
|
||||||
|
<script setup lang="ts">
|
||||||
|
// import Login from "~/components/login.vue";
|
||||||
|
|
||||||
|
</script>
|
||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-img
|
||||||
|
class="mx-auto my-6"
|
||||||
|
max-width="228"
|
||||||
|
src="https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-v3-slim-text-light.svg"
|
||||||
|
></v-img>
|
||||||
|
|
||||||
|
<v-card
|
||||||
|
class="mx-auto pa-12 pb-8"
|
||||||
|
elevation="8"
|
||||||
|
max-width="448"
|
||||||
|
rounded="lg"
|
||||||
|
>
|
||||||
|
<!-- <div class="text-subtitle-1 text-medium-emphasis">Account</div>-->
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
density="compact"
|
||||||
|
placeholder="Email address"
|
||||||
|
prepend-inner-icon="mdi-email-outline"
|
||||||
|
variant="outlined"
|
||||||
|
></v-text-field>
|
||||||
|
|
||||||
|
<!-- <div class="text-subtitle-1 text-medium-emphasis d-flex align-center justify-space-between">-->
|
||||||
|
<!-- Password-->
|
||||||
|
|
||||||
|
<!-- <a-->
|
||||||
|
<!-- class="text-caption text-decoration-none text-blue"-->
|
||||||
|
<!-- href="#"-->
|
||||||
|
<!-- rel="noopener noreferrer"-->
|
||||||
|
<!-- target="_blank"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- Forgot login password?</a>-->
|
||||||
|
<!-- </div>-->
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
|
||||||
|
:type="visible ? 'text' : 'password'"
|
||||||
|
density="compact"
|
||||||
|
placeholder="Enter your password"
|
||||||
|
prepend-inner-icon="mdi-lock-outline"
|
||||||
|
variant="outlined"
|
||||||
|
@click:append-inner="visible = !visible"
|
||||||
|
></v-text-field>
|
||||||
|
|
||||||
|
<v-card
|
||||||
|
class="mb-6"
|
||||||
|
color="surface-variant"
|
||||||
|
variant="tonal"
|
||||||
|
>
|
||||||
|
<!-- <v-card-text class="text-medium-emphasis text-caption">-->
|
||||||
|
<!-- Warning: After 3 consecutive failed login attempts, you account will be temporarily locked for three hours. If you must login now, you can also click "Forgot login password?" below to reset the login password.-->
|
||||||
|
<!-- </v-card-text>-->
|
||||||
|
</v-card>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
class="mb-8"
|
||||||
|
color="blue"
|
||||||
|
size="large"
|
||||||
|
variant="tonal"
|
||||||
|
block
|
||||||
|
@click="login"
|
||||||
|
>
|
||||||
|
Log In
|
||||||
|
</v-btn>
|
||||||
|
<p>{{token}}</p>
|
||||||
|
<p>{{ resAuth.data }}</p>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <v-card-text class="text-center">-->
|
||||||
|
<!-- <a-->
|
||||||
|
<!-- class="text-blue text-decoration-none"-->
|
||||||
|
<!-- href="#"-->
|
||||||
|
<!-- rel="noopener noreferrer"-->
|
||||||
|
<!-- target="_blank"-->
|
||||||
|
<!-- >-->
|
||||||
|
<!-- Sign up now <v-icon icon="mdi-chevron-right"></v-icon>-->
|
||||||
|
<!-- </a>-->
|
||||||
|
<!-- </v-card-text>-->
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {ref} from 'vue';
|
||||||
|
import {fetch} from "ofetch";
|
||||||
|
import {useRouter} from "#vue-router";
|
||||||
|
import {storeToRefs} from "pinia";
|
||||||
|
import {useCookie} from "#app";
|
||||||
|
import {useAuthentication} from "~/store/login";
|
||||||
|
|
||||||
|
const {auth} = useAuthentication()
|
||||||
|
const {resAuth} = storeToRefs(useAuthentication())
|
||||||
|
const visible = ref(false);
|
||||||
|
const router = useRouter()
|
||||||
|
const email = ref('');
|
||||||
|
const password = ref('');
|
||||||
|
const token = ref('')
|
||||||
|
const body = {
|
||||||
|
'email': '[email protected]',
|
||||||
|
'password': '123',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const login = async () => {
|
||||||
|
try {
|
||||||
|
await auth(body);
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
token.value = useCookie('token');
|
||||||
|
navigateTo({
|
||||||
|
path: '/homePage',
|
||||||
|
// query: {
|
||||||
|
// token: useCookie('token')
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<v-img
|
||||||
|
class="mx-auto my-6"
|
||||||
|
max-width="228"
|
||||||
|
src="https://cdn.vuetifyjs.com/docs/images/logos/vuetify-logo-v3-slim-text-light.svg"
|
||||||
|
></v-img>
|
||||||
|
|
||||||
|
<v-card
|
||||||
|
class="mx-auto pa-12 pb-8"
|
||||||
|
elevation="8"
|
||||||
|
max-width="448"
|
||||||
|
rounded="lg"
|
||||||
|
>
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
v-model="user_name"
|
||||||
|
density="compact"
|
||||||
|
placeholder="User Name"
|
||||||
|
prepend-inner-icon="mdi-account-key-outline"
|
||||||
|
variant="outlined"
|
||||||
|
></v-text-field>
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
v-model="name"
|
||||||
|
density="compact"
|
||||||
|
placeholder="User Name"
|
||||||
|
prepend-inner-icon="mdi-account-circle-outline"
|
||||||
|
variant="outlined"
|
||||||
|
></v-text-field>
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
v-model="email"
|
||||||
|
density="compact"
|
||||||
|
placeholder="Email address"
|
||||||
|
prepend-inner-icon="mdi-email-outline"
|
||||||
|
variant="outlined"
|
||||||
|
></v-text-field>
|
||||||
|
|
||||||
|
<v-text-field
|
||||||
|
v-model="password"
|
||||||
|
density="compact"
|
||||||
|
placeholder="Enter your password"
|
||||||
|
prepend-inner-icon="mdi-lock-outline"
|
||||||
|
variant="outlined"
|
||||||
|
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
|
||||||
|
:type="visible ? 'text' : 'password'"
|
||||||
|
@click:append-inner="visible = !visible"
|
||||||
|
></v-text-field>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <v-text-field-->
|
||||||
|
<!-- v-model:value="password"-->
|
||||||
|
<!-- :append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"-->
|
||||||
|
<!-- :type="visible ? 'text' : 'password'"-->
|
||||||
|
<!-- density="compact"-->
|
||||||
|
<!-- placeholder="Enter your password"-->
|
||||||
|
<!-- prepend-inner-icon="mdi-lock-outline"-->
|
||||||
|
<!-- variant="outlined"-->
|
||||||
|
<!-- @click:append-inner="visible = !visible"-->
|
||||||
|
<!-- ></v-text-field>-->
|
||||||
|
|
||||||
|
<v-card
|
||||||
|
class="mb-6"
|
||||||
|
color="surface-variant"
|
||||||
|
variant="tonal"
|
||||||
|
>
|
||||||
|
</v-card>
|
||||||
|
|
||||||
|
<v-btn
|
||||||
|
class="mb-8"
|
||||||
|
color="blue"
|
||||||
|
size="large"
|
||||||
|
variant="tonal"
|
||||||
|
block
|
||||||
|
@click="register"
|
||||||
|
>
|
||||||
|
Register
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
</v-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import {fetch} from "ofetch";
|
||||||
|
import {useRouter} from "#vue-router";
|
||||||
|
|
||||||
|
const router=useRouter();
|
||||||
|
const visible = ref(false);
|
||||||
|
const user_name = ref('');
|
||||||
|
const name = ref('');
|
||||||
|
const email = ref('');
|
||||||
|
const password = ref('');
|
||||||
|
|
||||||
|
const register = async () => {
|
||||||
|
console.log(user_name.value);
|
||||||
|
console.log(name.value);
|
||||||
|
console.log(email.value);
|
||||||
|
console.log(password.value);
|
||||||
|
const response=await fetch('http://127.0.0.1:8000/api/register', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: JSON.stringify({
|
||||||
|
"name": name.value,
|
||||||
|
"user_name": user_name.value,
|
||||||
|
"email": email.value,
|
||||||
|
// "password": "123"
|
||||||
|
"password": password.value
|
||||||
|
})
|
||||||
|
});
|
||||||
|
console.log(response.status)
|
||||||
|
if (response.status != 200) {
|
||||||
|
console.log('gagal');
|
||||||
|
}else{
|
||||||
|
await router.push('/login');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
// import this after install `@mdi/font` package
|
||||||
|
import '@mdi/font/css/materialdesignicons.css'
|
||||||
|
|
||||||
|
import 'vuetify/styles'
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import { createVuetify } from 'vuetify'
|
||||||
|
|
||||||
|
const customTheme = {
|
||||||
|
dark: false,
|
||||||
|
colors: {
|
||||||
|
background: '#FFFFFF',
|
||||||
|
surface: '#FFFFFF',
|
||||||
|
'surface-bright': '#FFFFFF',
|
||||||
|
'surface-light': '#EEEEEE',
|
||||||
|
'surface-variant': '#424242',
|
||||||
|
'on-surface-variant': '#EEEEEE',
|
||||||
|
primary: '#1867C0',
|
||||||
|
'primary-darken-1': '#1F5592',
|
||||||
|
secondary: '#48A9A6',
|
||||||
|
'secondary-darken-1': '#018786',
|
||||||
|
error: '#B00020',
|
||||||
|
info: '#2196F3',
|
||||||
|
success: '#4CAF50',
|
||||||
|
warning: '#FB8C00',
|
||||||
|
},
|
||||||
|
variables: {
|
||||||
|
'border-color': '#000000',
|
||||||
|
'border-opacity': 0.12,
|
||||||
|
'high-emphasis-opacity': 0.87,
|
||||||
|
'medium-emphasis-opacity': 0.60,
|
||||||
|
'disabled-opacity': 0.38,
|
||||||
|
'idle-opacity': 0.04,
|
||||||
|
'hover-opacity': 0.04,
|
||||||
|
'focus-opacity': 0.12,
|
||||||
|
'selected-opacity': 0.08,
|
||||||
|
'activated-opacity': 0.12,
|
||||||
|
'pressed-opacity': 0.12,
|
||||||
|
'dragged-opacity': 0.08,
|
||||||
|
'theme-kbd': '#212529',
|
||||||
|
'theme-on-kbd': '#FFFFFF',
|
||||||
|
'theme-code': '#F5F5F5',
|
||||||
|
'theme-on-code': '#000000',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineNuxtPlugin((app) => {
|
||||||
|
const vuetify = createVuetify({
|
||||||
|
// ... your configuration
|
||||||
|
theme: {
|
||||||
|
defaultTheme: 'customTheme',
|
||||||
|
themes: {
|
||||||
|
customTheme,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
app.vueApp.use(vuetify)
|
||||||
|
})
|
||||||
Generated
+6586
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
const body = await readBody(event);
|
||||||
|
// const email = body.email
|
||||||
|
// const password = body.password
|
||||||
|
console.log(body.email)
|
||||||
|
console.log(body.password)
|
||||||
|
try {
|
||||||
|
const response = await axios.post("http://10.10.150.129:8082/api/login/" + body);
|
||||||
|
return response.data
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error posting to surat kontrol API:", error);
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
statusMessage: "Failed to fetch data from surat kontrol API",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"extends": "../.nuxt/tsconfig.server.json"
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import {H3Event} from "h3";
|
||||||
|
import Client from "~/utils/api/client";
|
||||||
|
|
||||||
|
export const ServerApi = (event: H3Event) => {
|
||||||
|
const {apiUrl} = useRuntimeConfig().public;
|
||||||
|
const accessToken = getCookie(event, 'Authorization');
|
||||||
|
const refreshToken = getCookie(event, 'Refresh-Token');
|
||||||
|
|
||||||
|
console.log(`Access Token: ${accessToken}`);
|
||||||
|
console.log(`Refresh Token: ${refreshToken}`);
|
||||||
|
|
||||||
|
const client = new Client(apiUrl as string, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${accessToken}`,
|
||||||
|
'Refresh-Token': `Bearer ${refreshToken}`
|
||||||
|
} as HeadersInit
|
||||||
|
})
|
||||||
|
return client;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
import {defineStore} from "pinia";
|
||||||
|
import {ref} from "vue";
|
||||||
|
import {useCookie} from "#app";
|
||||||
|
|
||||||
|
|
||||||
|
// ___________________AUTH_________________________
|
||||||
|
export const useAuthentication = defineStore("Authentication", () => {
|
||||||
|
// ________________AUTH____________________________
|
||||||
|
const resAuth = ref<any[]>([]);
|
||||||
|
const auth = async (body: Record<string, any>) => {
|
||||||
|
try {
|
||||||
|
resAuth.value = await $fetch("http://127.0.0.1:8000/api/login/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: JSON.stringify(body)
|
||||||
|
});
|
||||||
|
// resultAuth.value = resAuth._rawValue;
|
||||||
|
// console.log(resAuth._rawValue.token);
|
||||||
|
useCookie('token').value = resAuth._rawValue.token;
|
||||||
|
} catch (err) {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 400,
|
||||||
|
statusMessage: "Failed to fetch data from Authentication API",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// __________________USER AUTH_______________________________________
|
||||||
|
const user = ref<any[]>([]);
|
||||||
|
const userAuth = async (body: Record<string, any>) => {
|
||||||
|
console.log(body.token)
|
||||||
|
try {
|
||||||
|
user.value = await $fetch("http://127.0.0.1:8000/api/userAuth/", {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': `Bearer ${useCookie('token').value}`,
|
||||||
|
'X-Requested-With': 'XMLHttpRequest',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
console.log(user.value)
|
||||||
|
console.log(user)
|
||||||
|
} catch (err) {
|
||||||
|
navigateTo({
|
||||||
|
path: '/login',
|
||||||
|
});
|
||||||
|
throw createError({
|
||||||
|
statusCode: 400,
|
||||||
|
statusMessage: "Failed to fetch data from User Auth API",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {auth, resAuth, userAuth, user}
|
||||||
|
})
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
// https://nuxt.com/docs/guide/concepts/typescript
|
||||||
|
"extends": "./.nuxt/tsconfig.json"
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import type {FetchOptions} from 'ofetch';
|
||||||
|
|
||||||
|
export default class Client {
|
||||||
|
options?: FetchOptions;
|
||||||
|
baseUrl: string;
|
||||||
|
|
||||||
|
constructor(baseUrl: string, options?: FetchOptions) {
|
||||||
|
this.options = options;
|
||||||
|
this.baseUrl = baseUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
async raw<T>(url: string, method: 'GET' | 'HEAD' | 'PATCH' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'get' | 'head' | 'patch' | 'post' | 'put' | 'delete' | 'connect' | 'options' | 'trace') {
|
||||||
|
try {
|
||||||
|
const response = await $fetch.raw<T>(`${this.baseUrl}${url}`, {
|
||||||
|
// ...options,
|
||||||
|
...this.options,
|
||||||
|
method
|
||||||
|
})
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async post<T>(ur: string, options?: FetchOptions,) {
|
||||||
|
try {
|
||||||
|
const response = await $fetch.raw<T>(`${this.baseUrl}${ur}`, {
|
||||||
|
...options,
|
||||||
|
...this.options,
|
||||||
|
method: 'POST'
|
||||||
|
})
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async get<T>(ur: string, options?: FetchOptions,) {
|
||||||
|
try {
|
||||||
|
const response = await $fetch.raw<T>(`${this.baseUrl}${ur}`, {
|
||||||
|
...options,
|
||||||
|
...this.options,
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async put<T>(ur: string, options?: FetchOptions,) {
|
||||||
|
try {
|
||||||
|
const response = await $fetch.raw<T>(`${this.baseUrl}${ur}`, {
|
||||||
|
...options,
|
||||||
|
...this.options,
|
||||||
|
method: 'PUT'
|
||||||
|
})
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async del<T>(ur: string, options?: FetchOptions,) {
|
||||||
|
try {
|
||||||
|
const response = await $fetch.raw<T>(`${this.baseUrl}${ur}`, {
|
||||||
|
...options,
|
||||||
|
...this.options,
|
||||||
|
method: 'DELETE'
|
||||||
|
})
|
||||||
|
return response;
|
||||||
|
} catch (err) {
|
||||||
|
return Promise.reject(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user