first commit

This commit is contained in:
Sas Andy
2024-08-12 08:42:51 +07:00
parent 6deeec116e
commit 2051b6439d
82 changed files with 78274 additions and 0 deletions

17991
css/materialdesignicon.css Normal file

File diff suppressed because it is too large Load Diff

30
css/styles.css Normal file
View File

@@ -0,0 +1,30 @@
@font-face {
font-family: "Roboto";
src: url("../fonts/Roboto-Light.woff2") format("woff2"),
url("../fonts/Roboto-Light.woff") format("woff"),
url("../fonts/Roboto-Light.ttf") format("truetype");
font-weight: 300;
font-style: normal;
}
@font-face {
font-family: "Roboto";
src: url("../fonts/Roboto-Regular.woff2") format("woff2"),
url("../fonts/Roboto-Regular.woff") format("woff"),
url("../fonts/Roboto-Regular.ttf") format("truetype");
font-weight: 400;
font-style: normal;
}
@font-face {
font-family: "Roboto";
src: url("../fonts/Roboto-Medium.woff2") format("woff2"),
url("../fonts/Roboto-Medium.woff") format("woff"),
url("../fonts/Roboto-Medium.ttf") format("truetype");
font-weight: 500;
font-style: normal;
}
body {
font-family: "Roboto", sans-serif;
}

25295
css/vuetify.css Normal file

File diff suppressed because it is too large Load Diff

BIN
fonts/Roboto-Light.woff2 Normal file

Binary file not shown.

BIN
fonts/Roboto-Medium.woff2 Normal file

Binary file not shown.

BIN
fonts/Roboto-Regular.woff2 Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

3
index.php Normal file
View File

@@ -0,0 +1,3 @@
<?php
header('Location: /westone-ui/test/');
?>

2
libraries/axios.js Normal file

File diff suppressed because one or more lines are too long

6690
libraries/vue-i18n.global.js Normal file

File diff suppressed because it is too large Load Diff

1839
libraries/vue3-sfc-loader.js Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2102
libraries/vuetify3.js Normal file

File diff suppressed because it is too large Load Diff

13
libraries/vuex.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
// components/ComponentA.js
const ComponentA = {
template: `
<div>
<h2>Component A</h2>
<p>Count: {{ count }}</p>
<v-btn @click="increment">Increment</v-btn>
<v-btn @click="decrement">Decrement</v-btn>
</div>
`,
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.dispatch('increment');
},
decrement() {
this.$store.dispatch('decrement');
}
}
};

View File

@@ -0,0 +1,21 @@
// components/ComponentB.js
const ComponentB = {
template: `
<div>
<h2>Component B</h2>
<p>Data: {{ data }}</p>
<v-btn @click="fetchData">Fetch Data</v-btn>
</div>
`,
computed: {
data() {
return this.$store.state.data;
}
},
methods: {
async fetchData() {
await this.$store.dispatch('fetchData');
}
}
};

View File

@@ -0,0 +1,116 @@
<template>
<div>
<v-container class="mb-6">
<v-row align="end" style="min-height: 480px;" no-gutters justify="center">
askldoisa
{{ email }}
<v-col>
<div class="d-flex justify-center">
<v-sheet class="pa-2 ma-2">
<h2 class="text-h6 font-weight-black">
{{ $t("message.login") }}
</h2>
</v-sheet>
</div>
<div class="d-flex justify-center mb-6">
<v-card
class="mx-auto pa-12 pb-8"
elevation="0"
min-width="400"
rounded="lg"
>
<div class="text-subtitle-1 text-medium-emphasis">
{{ $t("message.email") }}
</div>
<v-text-field
density="compact"
:placeholder="$t('message.placeholderEmail')"
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"
>
{{ $t("message.password") }}
<a
class="text-caption text-decoration-none text-blue"
href="#"
rel="noopener noreferrer"
target="_blank"
>
{{ $t("message.forgotPassword") }}</a
>
</div>
<v-text-field
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
:type="visible ? 'text' : 'password'"
density="compact"
:placeholder="$t('message.placeholderPassword')"
prepend-inner-icon="mdi-lock-outline"
variant="outlined"
@click:append-inner="visible = !visible"
></v-text-field>
<div class="text-center">
<v-btn
:loading="loading"
@click="login"
class="mt-8 text-none"
color="primary"
size="large"
variant="elevated"
block
>
{{ $t("message.login") }}
<template v-slot:loader>
<v-progress-linear indeterminate></v-progress-linear>
</template>
</v-btn>
</div>
</v-card>
</div>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script type="module">
export default {
name: "CobaComponent",
computed: {
// Akses state dari store
count() {
return this.$store.state.coba.count;
},
email() {
return this.$store.state.coba.email;
},
},
methods: {
// Dispatch action ke store
increment() {
this.$store.dispatch("increment");
},
},
};
// export default {
// name: "HelloWorld",
// // setup() {
// // // const store = useStore();
// // const email = computed(() => $store.state.email);
// // },
// computed: {
// email: {
// get() {
// return this.$store.state.store.email;
// },
// },
// },
// };
</script>
<style scoped>
h1 {
color: blue;
}
</style>

View File

@@ -0,0 +1,49 @@
<template>
<div>
<v-container class="mb-6">
<h1>Component 2</h1>
<h2>{{ email }}</h2>
</v-container>
</div>
</template>
<script type="module">
export default {
name: "component2",
computed: {
// Akses state dari store
count() {
return this.$store.state.coba2.count;
},
email() {
return this.$store.state.coba2.email;
},
},
methods: {
// Dispatch action ke store
increment() {
this.$store.dispatch("increment");
},
},
};
// export default {
// name: "HelloWorld",
// // setup() {
// // // const store = useStore();
// // const email = computed(() => $store.state.email);
// // },
// computed: {
// email: {
// get() {
// return this.$store.state.store.email;
// },
// },
// },
// };
</script>
<style scoped>
h1 {
color: blue;
}
</style>

View File

@@ -0,0 +1,50 @@
<template>
<v-app id="inspire">
<one-navbar></one-navbar>
<v-main>
<div class="w-100 rounded-xl mb-6 bg-primary-lighten mr-2 pa-3">
<h1 class="primary-lighten--text">Main component</h1>
<h2>{{ email }}</h2>
<v-btn color="primary" class="text-white">Secondary Button</v-btn>
<v-btn
class="text-white text-subtitle-1"
color="primary"
size="small"
variant="flat"
>
Create Event
</v-btn>
<coba-component></coba-component>
</div>
</v-main>
</v-app>
</template>
<script type="module">
import CobaComponent from "./coba.vue";
import NavbarComponent from "./one-navbar.vue";
export default {
name: "component2",
components: {
"coba-component": CobaComponent,
"one-navbar": NavbarComponent,
},
computed: {
// Akses state dari store
count() {
return this.$store.state.coba2.count;
},
email() {
return this.$store.state.coba2.email;
},
},
methods: {
// Dispatch action ke store
increment() {
this.$store.dispatch("increment");
},
},
};
</script>
<style scoped></style>

View File

@@ -0,0 +1,54 @@
<template>
<div>
<!-- :location="$vuetify.display.mobile ? 'bottom' : undefined" -->
<v-navigation-drawer style="border: 0;" v-model="drawer">
<v-list-item class="ml-2 mt-3">
<v-img
:aspect-ratio="1"
max-height="42px"
max-width="132px"
class="bg-white"
src="images/logo.png"
></v-img>
</v-list-item>
</v-navigation-drawer>
<v-app-bar class="elevation-0">
<v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
<v-app-bar-title>Application</v-app-bar-title>
</v-app-bar>
</div>
</template>
<script type="module">
export default {
name: "NavbarComponent",
data() {
return {
drawer: false,
};
},
computed: {
// Akses state dari store
count() {
return this.$store.state.coba2.count;
},
email() {
return this.$store.state.coba2.email;
},
},
methods: {
// Dispatch action ke store
increment() {
this.$store.dispatch("increment");
},
},
};
</script>
<style scoped>
h1 {
color: blue;
}
</style>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.4 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 594 KiB

BIN
login-coba/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

190
login-coba/index.html Normal file
View File

@@ -0,0 +1,190 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WESTONE</title>
<!-- Vuetify CSS -->
<link href="../css/vuetify.css" rel="stylesheet" />
<!-- Local Stylesheet for Fonts -->
<link rel="stylesheet" href="../css/styles.css" />
<link href="../css/materialdesignicon.css" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
<!-- Vue.js -->
<!-- <script src="https://unpkg.com/vue@next"></script> -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- <script src="../libraries/vue3.4.36.global.prod.js"></script> -->
<!-- Vuex -->
<script src="../libraries/vuex.js"></script>
<!-- Vuetify -->
<script src="../libraries/vuetify3.js"></script>
<!-- vue-i18n -->
<script src="../libraries/vue-i18n.global.js"></script>
<!-- Axios -->
<script src="../libraries/axios.js"></script>
<!-- Store JS -->
<!-- <script src="store.js"></script> -->
<!-- Component JS -->
<script src="components/ComponentA.js"></script>
<script src="components/ComponentB.js"></script>
<script src="theme.js"></script>
<!-- <script src="https://unpkg.com/vue3-sfc-loader/dist/vue3-sfc-loader.iife.js"></script> -->
<script src="../libraries/vue3-sfc-loader.js"></script>
<script type="module">
const { loadModule } = window["vue3-sfc-loader"];
import coba from "./modules/coba.js";
import coba2 from "./modules/coba2.js";
// import theme from "./theme.js";
const store = Vuex.createStore({
modules: {
coba: coba,
coba2: coba2,
},
});
const options = {
moduleCache: {
vue: Vue,
},
getFile(url) {
return fetch(url).then((response) =>
response.ok ? response.text() : Promise.reject(response)
);
},
addStyle(textContent) {
const style = document.createElement("style");
style.textContent = textContent;
const ref = document.head.getElementsByTagName("style")[0] || null;
document.head.insertBefore(style, ref);
},
};
// Locale messages
const messages = {
en: {
message: {
login: "Login",
email: "Email",
password: "Password",
forgotPassword: "Forgot password?",
placeholderEmail: "Enter your email",
placeholderPassword: "Enter your password",
},
},
id: {
message: {
login: "Masuk",
email: "Surel",
password: "Kata Sandi",
forgotPassword: "Lupa kata sandi?",
placeholderEmail: "Isikan email anda",
placeholderPassword: "Isikan kata sandi anda",
},
},
};
// Get the browser's preferred language
const browserLocale = navigator.language || navigator.languages[0];
// Initialize vue-i18n
const i18n = VueI18n.createI18n({
locale: browserLocale.startsWith("id") ? "id" : "en", // Set locale based on browser setting
fallbackLocale: "en", // Set fallback locale
messages, // Set locale messages
});
// Vue App
const app = Vue.createApp({
components: {
"component-a": ComponentA,
"component-b": ComponentB,
},
data() {
return {
visible: false,
bg_src: "./images/bg_cover.svg",
items: [
{
src: "./images/frame_1.svg",
},
{
src: "./images/frame_1.svg",
},
],
loading: false, // Initialize loading state
};
},
// <one-navbar></one-navbar>
template: `
<main-component></main-component>
`,
// <v-row no-gutters>
// <v-col cols="8">
// <hello-world></hello-world>
// <hello-world2></hello-world2>
// </v-col>
// <v-col cols="4">
// <div class="d-flex justify-center mb-6 mt-4 bg-surface-variant">
// <v-img
// class="bg-white"
// height="86px"
// src="./images/logo.svg"
// ></v-img>
// </div>
// </v-col>
// </v-row>
});
// themes: {
// light: {
// primary: "#2196F3",
// "primary-lighten": "#E3F2FD",
// "primary-darken": "#0D47A1",
// secondary: "#03a9f4",
// accent: "#ff5722",
// error: "#f44336",
// warning: "#ff9800",
// info: "#2196f3",
// success: "#4caf50",
// },
// dark: dark,
// },
// dark: false,
// // defaultTheme: "myCustomLightTheme",
const vuetify = Vuetify.createVuetify({
theme: {
themes: CustomTheme,
},
});
app.use(store);
app.use(vuetify);
app.use(i18n);
const components = {
"hello-world2": "./components/coba2.vue",
"hello-world": "./components/coba.vue",
"one-navbar": "./components/one-navbar.vue",
"main-component": "./components/main.vue",
};
Promise.all(
Object.entries(components).map(([name, path]) => {
return loadModule(path, options).then((component) => {
app.component(name, component);
});
})
)
.then(() => {
app.mount("#app");
})
.catch((error) => {
console.error("Error loading components:", error);
});
</script>
</body>
</html>

View File

@@ -0,0 +1,88 @@
// store/store.js
// src/store.js
// import { createStore } from '../../vuex.js';
// const store = createStore({
// state: {
// count: 0,
// email: "asadkjdda"
// },
// mutations: {
// increment(state) {
// state.count++;
// }
// },
// actions: {
// increment({ commit }) {
// commit('increment');
// }
// },
// getters: {
// count: (state) => state.count
// }
// });
// export default store;
const URL = "/westone-api/v1/system/auth";
const store = Vuex.createStore({
state() {
return {
count: 0,
data: null,
email: "lashlkdsa",
password: null,
dialog_success: false
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
},
setEmail(state, data) {
state.email = data;
},
setPassword(state, data) {
state.password = data;
},
setDialogSuccess(state, data) {
state.dialog_success = data;
}
},
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
async loginState({ state, commit }) {
const params = {
email: state.email,
password: state.pasword
};
try {
const response = await axios.post(URL + '/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
},
async LoginParam({ commit }, params) {
try {
const response = await axios.post(URL + '/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
}
}
});
export default store

View File

@@ -0,0 +1,88 @@
// store/store.js
// src/store.js
// import { createStore } from '../../vuex.js';
// const store = createStore({
// state: {
// count: 0,
// email: "asadkjdda"
// },
// mutations: {
// increment(state) {
// state.count++;
// }
// },
// actions: {
// increment({ commit }) {
// commit('increment');
// }
// },
// getters: {
// count: (state) => state.count
// }
// });
// export default store;
const URL = "/westone-api/v1/system/auth";
const store = Vuex.createStore({
state() {
return {
count: 0,
data: null,
email: "lashlkdsa",
password: null,
dialog_success: false
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
},
setEmail(state, data) {
state.email = data;
},
setPassword(state, data) {
state.password = data;
},
setDialogSuccess(state, data) {
state.dialog_success = data;
}
},
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
async loginState({ state, commit }) {
const params = {
email: state.email,
password: state.pasword
};
try {
const response = await axios.post(URL + '/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
},
async LoginParam({ commit }, params) {
try {
const response = await axios.post(URL + '/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
}
}
});
export default store;

View File

@@ -0,0 +1,13 @@
import coba from "coba.js";
import coba2 from "coba2.js";
// import system from "../../../apps/modules/system/system.js";
// import handover from "./modules/handover.js";
export const store = Vuex.createStore({
modules: {
coba: coba,
coba2: coba2,
},
});

14
login-coba/store.js Normal file
View File

@@ -0,0 +1,14 @@
import coba from "./modules/coba.js";
import coba2 from "./modules/coba2.js";
// import system from "../../../apps/modules/system/system.js";
// import handover from "./modules/handover.js";
const store = Vuex.createStore({
modules: {
coba: coba,
coba2: coba2,
},
});
export default store;

18
login-coba/theme.js Normal file
View File

@@ -0,0 +1,18 @@
var CustomTheme = {
light: {
dark: false,
colors: {
primary: "#FFC107",
// primary: "#2196F3",
"primary-lighten": "#E3F2FD",
"primary-darken": "#0D47A1",
white: "#FFFFFF",
secondary: "#03a9f4",
accent: "#ff5722",
error: "#f44336",
warning: "#ff9800",
info: "#2196f3",
success: "#4caf50",
},
},
}

View File

@@ -0,0 +1,26 @@
// components/ComponentA.js
const ComponentA = {
template: `
<div>
<h2>Component A</h2>
<p>Count: {{ count }}</p>
<v-btn @click="increment">Increment</v-btn>
<v-btn @click="decrement">Decrement</v-btn>
</div>
`,
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.dispatch('increment');
},
decrement() {
this.$store.dispatch('decrement');
}
}
};

View File

@@ -0,0 +1,22 @@
// components/ComponentB.js
const ComponentB = {
template: `
<div>
<h2>Component B</h2>
<p>Data: {{ data }}</p>
<v-btn @click="fetchData">Fetch Data</v-btn>
</div>
`,
computed: {
data() {
return this.$store.state.data;
}
},
methods: {
async fetchData() {
await this.$store.dispatch('fetchData');
}
}
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.4 MiB

4292
login/images/bg_image.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 MiB

30
login/images/frame_1.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 594 KiB

9
login/images/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

193
login/index.html Normal file
View File

@@ -0,0 +1,193 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WESTONE</title>
<!-- Vuetify CSS -->
<link href="../css/vuetify.css" rel="stylesheet">
<!-- Local Stylesheet for Fonts -->
<link rel="stylesheet" href="../css/styles.css">
<link href="../css/materialdesignicon.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<!-- Vue.js -->
<script src="../libraries/vue3.4.36.global.prod.js"></script>
<!-- Vuex -->
<script src="../libraries/vuex.js"></script>
<!-- Vuetify -->
<script src="../libraries/vuetify3.js"></script>
<!-- vue-i18n -->
<script src="../libraries/vue-i18n.global.js"></script>
<!-- Axios -->
<script src="../libraries/axios.js"></script>
<!-- Store JS -->
<script src="store/store.js"></script>
<!-- Component JS -->
<script src="components/ComponentA.js"></script>
<script src="components/ComponentB.js"></script>
<script>
// Locale messages
const messages = {
en: {
message: {
login: 'Login',
email: 'Email',
password: 'Password',
forgotPassword: 'Forgot password?',
placeholderEmail: 'Enter your email',
placeholderPassword: 'Enter your password'
}
},
id: {
message: {
login: 'Masuk',
email: 'Surel',
password: 'Kata Sandi',
forgotPassword: 'Lupa kata sandi?',
placeholderEmail: 'Isikan email anda',
placeholderPassword: 'Isikan kata sandi anda'
}
}
};
// Get the browser's preferred language
const browserLocale = navigator.language || navigator.languages[0];
// Initialize vue-i18n
const i18n = VueI18n.createI18n({
locale: browserLocale.startsWith('id') ? 'id' : 'en', // Set locale based on browser setting
fallbackLocale: 'en', // Set fallback locale
messages, // Set locale messages
});
// Vue App
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
},
data () {
return {
visible: false,
bg_src: './images/bg_cover.svg',
items: [
{
src: './images/frame_1.svg',
},
{
src: './images/frame_1.svg',
}
],
loading: false // Initialize loading state
}
},
methods: {
async login() {
await this.$store.dispatch('loginState');
}
},
template: `
<v-row no-gutters>
<v-col cols="8">
<v-img
:aspect-ratio="1"
class="bg-white"
:src="bg_src"
width="100vw"
height="100vh"
cover
></v-img>
</v-col>
<v-col cols="4">
<div class="d-flex justify-center mb-6 mt-4 bg-surface-variant">
<v-img
class="bg-white"
height="86px"
src="./images/logo.svg"
></v-img>
</div>
<v-container class="mb-6">
<v-row
align="end"
style="min-height: 480px"
no-gutters
justify="center"
>
<v-col>
<div class="d-flex justify-center">
<v-sheet class="pa-2 ma-2">
<h2 class="text-h6 font-weight-black">{{ $t('message.login') }}</h2>
</v-sheet>
</div>
<div class="d-flex justify-center mb-6">
<v-card
class="mx-auto pa-12 pb-8"
elevation="0"
min-width="400"
rounded="lg"
>
<div class="text-subtitle-1 text-medium-emphasis">{{ $t('message.email') }}</div>
<v-text-field
density="compact"
:placeholder="$t('message.placeholderEmail')"
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">
{{ $t('message.password') }}
<a
class="text-caption text-decoration-none text-blue"
href="#"
rel="noopener noreferrer"
target="_blank"
>
{{ $t('message.forgotPassword') }}</a>
</div>
<v-text-field
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
:type="visible ? 'text' : 'password'"
density="compact"
:placeholder="$t('message.placeholderPassword')"
prepend-inner-icon="mdi-lock-outline"
variant="outlined"
@click:append-inner="visible = !visible"
></v-text-field>
<div class="text-center">
<v-btn
:loading="loading"
@click="login"
class="mt-8 text-none"
color="blue"
size="large"
variant="elevated"
block
>
{{ $t('message.login') }}
<template v-slot:loader>
<v-progress-linear indeterminate></v-progress-linear>
</template>
</v-btn>
</div>
</v-card>
</div>
</v-col>
</v-row>
</v-container>
</v-col>
</v-row>
`
});
const vuetify = Vuetify.createVuetify();
app.use(store);
app.use(vuetify);
app.use(i18n);
app.mount('#app');
</script>
</body>
</html>

67
login/store/store.js Normal file
View File

@@ -0,0 +1,67 @@
// store/store.js
const URL = "/westone-api/v1/system/auth";
const store = Vuex.createStore({
state() {
return {
count: 0,
data: null,
email:null,
password:null,
dialog_success:false,
loading:false
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
},
setEmail(state, data) {
state.email = data;
},
setPassword(state, data) {
state.password = data;
},
setDialogSuccess(state, data) {
state.dialog_success = data;
},
setLoading(state, data) {
state.loading = data;
},
},
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
async loginState({ state, commit }) {
const params = {
email: state.email,
password: state.pasword
};
try {
const response = await axios.post(URL+'/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
},
async LoginParam({ commit }, params) {
try {
const response = await axios.post(URL+'/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
}
}
});

View File

@@ -0,0 +1,25 @@
// components/ComponentA.js
const ComponentA = {
template: `
<div>
<h2>Component A</h2>
<p>Count: {{ count }}</p>
<v-btn @click="increment">Increment</v-btn>
<v-btn @click="decrement">Decrement</v-btn>
</div>
`,
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.dispatch('increment');
},
decrement() {
this.$store.dispatch('decrement');
}
}
};

View File

@@ -0,0 +1,21 @@
// components/ComponentB.js
const ComponentB = {
template: `
<div>
<h2>Component B</h2>
<p>Data: {{ data }}</p>
<v-btn @click="fetchData">Fetch Data</v-btn>
</div>
`,
computed: {
data() {
return this.$store.state.data;
}
},
methods: {
async fetchData() {
await this.$store.dispatch('fetchData');
}
}
};

View File

@@ -0,0 +1,116 @@
<template>
<div>
<v-container class="mb-6">
<v-row align="end" style="min-height: 480px;" no-gutters justify="center">
askldoisa
{{ email }}
<v-col>
<div class="d-flex justify-center">
<v-sheet class="pa-2 ma-2">
<h2 class="text-h6 font-weight-black">
{{ $t("message.login") }}
</h2>
</v-sheet>
</div>
<div class="d-flex justify-center mb-6">
<v-card
class="mx-auto pa-12 pb-8"
elevation="0"
min-width="400"
rounded="lg"
>
<div class="text-subtitle-1 text-medium-emphasis">
{{ $t("message.email") }}
</div>
<v-text-field
density="compact"
:placeholder="$t('message.placeholderEmail')"
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"
>
{{ $t("message.password") }}
<a
class="text-caption text-decoration-none text-blue"
href="#"
rel="noopener noreferrer"
target="_blank"
>
{{ $t("message.forgotPassword") }}</a
>
</div>
<v-text-field
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
:type="visible ? 'text' : 'password'"
density="compact"
:placeholder="$t('message.placeholderPassword')"
prepend-inner-icon="mdi-lock-outline"
variant="outlined"
@click:append-inner="visible = !visible"
></v-text-field>
<div class="text-center">
<v-btn
:loading="loading"
@click="login"
class="mt-8 text-none"
color="blue"
size="large"
variant="elevated"
block
>
{{ $t("message.login") }}
<template v-slot:loader>
<v-progress-linear indeterminate></v-progress-linear>
</template>
</v-btn>
</div>
</v-card>
</div>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script type="module">
export default {
name: "CobaComponent",
computed: {
// Akses state dari store
count() {
return this.$store.state.count;
},
email() {
return this.$store.state.email;
},
},
methods: {
// Dispatch action ke store
increment() {
this.$store.dispatch("increment");
},
},
};
// export default {
// name: "HelloWorld",
// // setup() {
// // // const store = useStore();
// // const email = computed(() => $store.state.email);
// // },
// computed: {
// email: {
// get() {
// return this.$store.state.store.email;
// },
// },
// },
// };
</script>
<style scoped>
h1 {
color: blue;
}
</style>

View File

@@ -0,0 +1,48 @@
<template>
<div>
<v-container class="mb-6">
<h1>Component 2</h1>
</v-container>
</div>
</template>
<script type="module">
export default {
name: "component2",
computed: {
// Akses state dari store
count() {
return this.$store.state.count;
},
email() {
return this.$store.state.email;
},
},
methods: {
// Dispatch action ke store
increment() {
this.$store.dispatch("increment");
},
},
};
// export default {
// name: "HelloWorld",
// // setup() {
// // // const store = useStore();
// // const email = computed(() => $store.state.email);
// // },
// computed: {
// email: {
// get() {
// return this.$store.state.store.email;
// },
// },
// },
// };
</script>
<style scoped>
h1 {
color: blue;
}
</style>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.4 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 594 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

150
loginmulti/index.html Normal file
View File

@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WESTONE</title>
<!-- Vuetify CSS -->
<link href="../css/vuetify.css" rel="stylesheet" />
<!-- Local Stylesheet for Fonts -->
<link rel="stylesheet" href="../css/styles.css" />
<link href="../css/materialdesignicon.css" rel="stylesheet" />
</head>
<body>
<div id="app">
<v-row no-gutters>
<v-col cols="8">
<hello-world></hello-world>
<hello-world2></hello-world2>
</v-col>
<v-col cols="4">
<div class="d-flex justify-center mb-6 mt-4 bg-surface-variant">
<v-img
class="bg-white"
height="86px"
src="./images/logo.svg"
></v-img>
</div>
</v-col>
</v-row>
</div>
<!-- Vue.js -->
<!-- <script src="https://unpkg.com/vue@next"></script> -->
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<!-- <script src="../libraries/vue3.4.36.global.prod.js"></script> -->
<!-- Vuex -->
<script src="../libraries/vuex.js"></script>
<!-- Vuetify -->
<script src="../libraries/vuetify3.js"></script>
<!-- vue-i18n -->
<script src="../libraries/vue-i18n.global.js"></script>
<!-- Axios -->
<script src="../libraries/axios.js"></script>
<!-- Store JS -->
<script src="store/store.js"></script>
<!-- Component JS -->
<script src="components/ComponentA.js"></script>
<script src="components/ComponentB.js"></script>
<!-- <script src="https://unpkg.com/vue3-sfc-loader/dist/vue3-sfc-loader.iife.js"></script> -->
<script src="../libraries/vue3-sfc-loader.js"></script>
<script>
const { loadModule } = window["vue3-sfc-loader"];
const options = {
moduleCache: {
vue: Vue,
},
getFile(url) {
return fetch(url).then((response) =>
response.ok ? response.text() : Promise.reject(response)
);
},
addStyle(textContent) {
const style = document.createElement("style");
style.textContent = textContent;
const ref = document.head.getElementsByTagName("style")[0] || null;
document.head.insertBefore(style, ref);
},
};
// Locale messages
const messages = {
en: {
message: {
login: "Login",
email: "Email",
password: "Password",
forgotPassword: "Forgot password?",
placeholderEmail: "Enter your email",
placeholderPassword: "Enter your password",
},
},
id: {
message: {
login: "Masuk",
email: "Surel",
password: "Kata Sandi",
forgotPassword: "Lupa kata sandi?",
placeholderEmail: "Isikan email anda",
placeholderPassword: "Isikan kata sandi anda",
},
},
};
// Get the browser's preferred language
const browserLocale = navigator.language || navigator.languages[0];
// Initialize vue-i18n
const i18n = VueI18n.createI18n({
locale: browserLocale.startsWith("id") ? "id" : "en", // Set locale based on browser setting
fallbackLocale: "en", // Set fallback locale
messages, // Set locale messages
});
// Vue App
const app = Vue.createApp({
data() {
return {
visible: false,
bg_src: "./images/bg_cover.svg",
items: [
{
src: "./images/frame_1.svg",
},
{
src: "./images/frame_1.svg",
},
],
loading: false, // Initialize loading state
};
}
});
const vuetify = Vuetify.createVuetify();
app.use(window.store);
app.use(vuetify);
app.use(i18n);
const components = {
"hello-world2": "./components/coba2.vue",
"hello-world": "./components/coba.vue",
};
Promise.all(
Object.entries(components).map(([name, path]) => {
return loadModule(path, options).then((component) => {
app.component(name, component);
});
})
)
.then(() => {
app.mount("#app");
})
.catch((error) => {
console.error("Error loading components:", error);
});
</script>
</body>
</html>

View File

@@ -0,0 +1,40 @@
// src/store/moduleA.js
const moduleA = {
namespaced: true,
state() {
return {
count: 0,
data: null
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
}
},
actions: {
async login({ state, commit }) {
const params = {
email: state.email,
password: state.password
};
try {
const response = await axios.post(URL + '/login', params);
commit('setData', response.data);
} catch (error) {
console.error('Error:', error);
}
}
}
};
// Export moduleA as a global variable
window.moduleA = moduleA;

View File

@@ -0,0 +1,26 @@
// src/store/moduleB.js
const moduleB = {
namespaced: true,
state() {
return {
email: 'example@example.com',
password: null,
dialog_success: false
};
},
mutations: {
setEmail(state, data) {
state.email = data;
},
setPassword(state, data) {
state.password = data;
},
setDialogSuccess(state, data) {
state.dialog_success = data;
}
}
};
// Export moduleB as a global variable
window.moduleB = moduleB;

View File

@@ -0,0 +1,9 @@
const store = new Vuex.Store({
modules: {
moduleA: window.moduleA,
moduleB: window.moduleB
}
});
// Export store
window.store = store;

View File

@@ -0,0 +1,26 @@
// components/ComponentA.js
const ComponentA = {
template: `
<div>
<h2>Component A</h2>
<p>Count: {{ count }}</p>
<v-btn @click="increment">Increment</v-btn>
<v-btn @click="decrement">Decrement</v-btn>
</div>
`,
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.dispatch('increment');
},
decrement() {
this.$store.dispatch('decrement');
}
}
};

View File

@@ -0,0 +1,22 @@
// components/ComponentB.js
const ComponentB = {
template: `
<div>
<h2>Component B</h2>
<p>Data: {{ data }}</p>
<v-btn @click="fetchData">Fetch Data</v-btn>
</div>
`,
computed: {
data() {
return this.$store.state.data;
}
},
methods: {
async fetchData() {
await this.$store.dispatch('fetchData');
}
}
};

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.4 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 594 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

188
loginstephen/index.html Normal file
View File

@@ -0,0 +1,188 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WESTONE</title>
<!-- Vuetify CSS -->
<link href="../css/vuetify.css" rel="stylesheet">
<!-- Local Stylesheet for Fonts -->
<link rel="stylesheet" href="../css/styles.css">
<link href="../css/materialdesignicon.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<!-- Vue.js -->
<script src="../libraries/vue3.4.36.global.prod.js"></script>
<!-- Vuex -->
<script src="../libraries/vuex.js"></script>
<!-- Vuetify -->
<script src="../libraries/vuetify3.js"></script>
<!-- vue-i18n -->
<script src="../libraries/vue-i18n.global.js"></script>
<!-- Axios -->
<script src="../libraries/axios.js"></script>
<!-- Store JS -->
<script src="store/store.js"></script>
<!-- Component JS -->
<script src="components/ComponentA.js"></script>
<script src="components/ComponentB.js"></script>
<script>
// Locale messages
const messages = {
en: {
message: {
login: 'Login',
email: 'Email',
password: 'Password',
forgotPassword: 'Forgot password?',
placeholderEmail: 'Enter your email',
placeholderPassword: 'Enter your password'
}
},
id: {
message: {
login: 'Masuk',
email: 'Surel',
password: 'Kata Sandi',
forgotPassword: 'Lupa kata sandi?',
placeholderEmail: 'Isikan email anda',
placeholderPassword: 'Isikan kata sandi anda'
}
}
};
// Get the browser's preferred language
const browserLocale = navigator.language || navigator.languages[0];
// Initialize vue-i18n
const i18n = VueI18n.createI18n({
locale: browserLocale.startsWith('id') ? 'id' : 'en', // Set locale based on browser setting
fallbackLocale: 'en', // Set fallback locale
messages, // Set locale messages
});
// Vue App
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
},
data () {
return {
visible: false,
bg_src: './images/bg_cover.svg',
items: [
{
src: './images/frame_1.svg',
},
{
src: './images/frame_1.svg',
}
],
loading: false // Initialize loading state
}
},
template: `
<v-row no-gutters>
<v-col cols="8">
<v-img
:aspect-ratio="1"
class="bg-white"
:src="bg_src"
width="100vw"
height="100vh"
cover
></v-img>
</v-col>
<v-col cols="4">
<div class="d-flex justify-center mb-6 mt-4 bg-surface-variant">
<v-img
class="bg-white"
height="86px"
src="./images/logo.svg"
></v-img>
</div>
<v-container class="mb-6">
<v-row
align="end"
style="min-height: 480px"
no-gutters
justify="center"
>
<v-col>
<div class="d-flex justify-center">
<v-sheet class="pa-2 ma-2">
<h2 class="text-h6 font-weight-black">{{ $t('message.login') }}</h2>
</v-sheet>
</div>
<div class="d-flex justify-center mb-6">
<v-card
class="mx-auto pa-12 pb-8"
elevation="0"
min-width="400"
rounded="lg"
>
<div class="text-subtitle-1 text-medium-emphasis">{{ $t('message.email') }}</div>
<v-text-field
density="compact"
:placeholder="$t('message.placeholderEmail')"
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">
{{ $t('message.password') }}
<a
class="text-caption text-decoration-none text-blue"
href="#"
rel="noopener noreferrer"
target="_blank"
>
{{ $t('message.forgotPassword') }}</a>
</div>
<v-text-field
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
:type="visible ? 'text' : 'password'"
density="compact"
:placeholder="$t('message.placeholderPassword')"
prepend-inner-icon="mdi-lock-outline"
variant="outlined"
@click:append-inner="visible = !visible"
></v-text-field>
<div class="text-center">
<v-btn
:loading="loading"
@click="loading = !loading"
class="mt-8 text-none"
color="blue"
size="large"
variant="elevated"
block
>
{{ $t('message.login') }}
<template v-slot:loader>
<v-progress-linear indeterminate></v-progress-linear>
</template>
</v-btn>
</div>
</v-card>
</div>
</v-col>
</v-row>
</v-container>
</v-col>
</v-row>
`
});
const vuetify = Vuetify.createVuetify();
app.use(store);
app.use(vuetify);
app.use(i18n);
app.mount('#app');
</script>
</body>
</html>

View File

@@ -0,0 +1,63 @@
// store/store.js
const URL = "/westone-api/system/";
const store = Vuex.createStore({
state() {
return {
count: 0,
data: null,
email:null,
password:null,
dialog_success:false
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
},
setEmail(state, data) {
state.email = data;
},
setPassword(state, data) {
state.password = data;
},
setDialogSuccess(state, data) {
state.dialog_success = data;
}
},
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
async loginState({ state, commit }) {
const params = {
email: state.email,
password: state.pasword
};
try {
const response = await axios.post(URL+'/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
},
async LoginParam({ commit }, params) {
try {
const response = await axios.post(URL+'/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
}
}
});

View File

@@ -0,0 +1,25 @@
// components/ComponentA.js
const ComponentA = {
template: `
<div>
<h2>Component A</h2>
<p>Count: {{ count }}</p>
<v-btn @click="increment">Increment</v-btn>
<v-btn @click="decrement">Decrement</v-btn>
</div>
`,
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.dispatch('increment');
},
decrement() {
this.$store.dispatch('decrement');
}
}
};

View File

@@ -0,0 +1,21 @@
// components/ComponentB.js
const ComponentB = {
template: `
<div>
<h2>Component B</h2>
<p>Data: {{ data }}</p>
<v-btn @click="fetchData">Fetch Data</v-btn>
</div>
`,
computed: {
data() {
return this.$store.state.data;
}
},
methods: {
async fetchData() {
await this.$store.dispatch('fetchData');
}
}
};

View File

@@ -0,0 +1,92 @@
<template>
<div>
<v-container class="mb-6">
<v-row align="end" style="min-height: 480px;" no-gutters justify="center">
<v-col>
<div class="d-flex justify-center">
<v-sheet class="pa-2 ma-2">
<h2 class="text-h6 font-weight-black">
{{ $t("message.login") }} {{ email }}
</h2>
</v-sheet>
</div>
<div class="d-flex justify-center mb-6">
<v-card
class="mx-auto pa-12 pb-8"
elevation="0"
min-width="400"
rounded="lg"
>
<div class="text-subtitle-1 text-medium-emphasis">
{{ $t("message.email") }}
</div>
<v-text-field
density="compact"
:placeholder="$t('message.placeholderEmail')"
prepend-inner-icon="mdi-email-outline"
variant="outlined"
v-model="email"
></v-text-field>
<div
class="text-subtitle-1 text-medium-emphasis d-flex align-center justify-space-between"
>
{{ $t("message.password") }}
<a
class="text-caption text-decoration-none text-blue"
href="#"
rel="noopener noreferrer"
target="_blank"
>
{{ $t("message.forgotPassword") }}</a
>
</div>
<v-text-field
:append-inner-icon="visible ? 'mdi-eye-off' : 'mdi-eye'"
:type="visible ? 'text' : 'password'"
density="compact"
:placeholder="$t('message.placeholderPassword')"
prepend-inner-icon="mdi-lock-outline"
variant="outlined"
@click:append-inner="visible = !visible"
></v-text-field>
<div class="text-center">
<v-btn
:loading="loading"
@click="login"
class="mt-8 text-none"
color="blue"
size="large"
variant="elevated"
block
>
{{ $t("message.login") }}
<template v-slot:loader>
<v-progress-linear indeterminate></v-progress-linear>
</template>
</v-btn>
</div>
</v-card>
</div>
</v-col>
</v-row>
</v-container>
</div>
</template>
<script>
export default {
name: "HelloWorld",
setup() {
const store = useStore();
const email = computed(() => store.state.email);
return { email };
}
};
</script>
<style scoped>
h1 {
color: blue;
}
</style>

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 4.4 MiB

4292
loginv2/images/bg_image.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 24 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 594 KiB

9
loginv2/images/logo.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

139
loginv2/index.html Normal file
View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WESTONE</title>
<!-- Vuetify CSS -->
<link href="../css/vuetify.css" rel="stylesheet" />
<!-- Local Stylesheet for Fonts -->
<link rel="stylesheet" href="../css/styles.css" />
<link href="../css/materialdesignicon.css" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
<!-- Vue.js -->
<script src="../libraries/vue3.4.36.global.prod.js"></script>
<!-- Vuex -->
<script src="../libraries/vuex.js"></script>
<!-- Vuetify -->
<script src="../libraries/vuetify3.js"></script>
<!-- vue-i18n -->
<script src="../libraries/vue-i18n.global.js"></script>
<!-- Axios -->
<script src="../libraries/axios.js"></script>
<!-- Store JS -->
<script src="store/store.js"></script>
<!-- Component JS -->
<script src="components/ComponentA.js"></script>
<script src="components/ComponentB.js"></script>
<!-- <script src="https://unpkg.com/vue3-sfc-loader/dist/vue3-sfc-loader.iife.js"></script> -->
<script src="../libraries/vue3-sfc-loader.js"></script>
<script>
const { loadModule } = window["vue3-sfc-loader"];
const options = {
moduleCache: {
vue: Vue,
},
getFile(url) {
return fetch(url).then((response) =>
response.ok ? response.text() : Promise.reject(response)
);
},
addStyle(textContent) {
const style = document.createElement("style");
style.textContent = textContent;
const ref = document.head.getElementsByTagName("style")[0] || null;
document.head.insertBefore(style, ref);
},
};
// Locale messages
const messages = {
en: {
message: {
login: "Login",
email: "Email",
password: "Password",
forgotPassword: "Forgot password?",
placeholderEmail: "Enter your email",
placeholderPassword: "Enter your password",
},
},
id: {
message: {
login: "Masuk",
email: "Surel",
password: "Kata Sandi",
forgotPassword: "Lupa kata sandi?",
placeholderEmail: "Isikan email anda",
placeholderPassword: "Isikan kata sandi anda",
},
},
};
// Get the browser's preferred language
const browserLocale = navigator.language || navigator.languages[0];
// Initialize vue-i18n
const i18n = VueI18n.createI18n({
locale: browserLocale.startsWith("id") ? "id" : "en", // Set locale based on browser setting
fallbackLocale: "en", // Set fallback locale
messages, // Set locale messages
});
// Vue App
const app = Vue.createApp({
components: {
"component-a": ComponentA,
"component-b": ComponentB,
},
data() {
return {
visible: false,
bg_src: "./images/bg_cover.svg",
items: [
{
src: "./images/frame_1.svg",
},
{
src: "./images/frame_1.svg",
},
],
loading: false, // Initialize loading state
};
},
template: `
<v-row no-gutters>
<v-col cols="8">
<hello-world></hello-world>
</v-col>
<v-col cols="4">
<div class="d-flex justify-center mb-6 mt-4 bg-surface-variant">
<v-img
class="bg-white"
height="86px"
src="./images/logo.svg"
></v-img>
</div>
</v-col>
</v-row>
`,
});
const vuetify = Vuetify.createVuetify();
app.use(store);
app.use(vuetify);
app.use(i18n);
loadModule("./components/coba.vue", options).then((component) => {
app.component("hello-world", component);
app.mount("#app");
});
</script>
</body>
</html>

64
loginv2/store/store.js Normal file
View File

@@ -0,0 +1,64 @@
// store/store.js
const URL = "/westone-api/v1/system/auth";
const store = Vuex.createStore({
state() {
return {
count: 0,
data: null,
email:null,
password:null,
dialog_success:false
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
},
setEmail(state, data) {
state.email = data;
},
setPassword(state, data) {
state.password = data;
},
setDialogSuccess(state, data) {
state.dialog_success = data;
}
},
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
async loginState({ state, commit }) {
const params = {
email: state.email,
password: state.pasword
};
try {
const response = await axios.post(URL+'/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
},
async LoginParam({ commit }, params) {
try {
const response = await axios.post(URL+'/login', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
}
}
});
export default store;

View File

@@ -0,0 +1,48 @@
<!-- components/AnotherComponent.vue -->
<template>
<v-container>
<v-row>
<v-col>
<h2>{{ $t('anotherComponent.title') }}</h2>
<v-text-field v-model="param2" :label="$t('anotherComponent.param2Label')"></v-text-field>
<p>{{ $t('anotherComponent.param2') }}: {{ param2 }}</p>
<v-btn @click="sendData">{{ $t('anotherComponent.sendDataButton') }}</v-btn>
<div v-if="data">{{ $t('anotherComponent.response') }}: {{ data }}</div>
<div v-if="error">{{ $t('anotherComponent.error') }}: {{ error.message }}</div>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
computed: {
param2: {
get() {
return this.$store.state.param2;
},
set(value) {
this.$store.commit('setParam2', value);
}
},
data() {
return this.$store.state.data;
},
error() {
return this.$store.state.error;
}
},
methods: {
sendData() {
this.$store.dispatch('sendData');
}
}
};
</script>
<style scoped>
h2 {
color: green;
}
</style>

View File

@@ -0,0 +1,34 @@
<!-- components/ComponentA.vue -->
<template>
<v-container>
<v-row>
<v-col>
<h2>{{ $t('message.login') }}</h2>
<v-text-field v-model="param1" :label="$t('message.email')"></v-text-field>
<p>{{ $t('message.param1') }}: {{ param1 }}</p>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
computed: {
param1: {
get() {
return this.$store.state.param1;
},
set(value) {
this.$store.commit('setParam1', value);
}
}
}
};
</script>
<style scoped>
h2 {
color: blue;
}
</style>

View File

@@ -0,0 +1,48 @@
<!-- components/ComponentB.vue -->
<template>
<v-container>
<v-row>
<v-col>
<h2>{{ $t('message.login') }}</h2>
<v-text-field v-model="param2" :label="$t('message.password')"></v-text-field>
<p>{{ $t('message.param2') }}: {{ param2 }}</p>
<v-btn @click="sendData">{{ $t('message.login') }}</v-btn>
<div v-if="data">{{ $t('message.response') }}: {{ data }}</div>
<div v-if="error">{{ $t('message.error') }}: {{ error.message }}</div>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
computed: {
param2: {
get() {
return this.$store.state.param2;
},
set(value) {
this.$store.commit('setParam2', value);
}
},
data() {
return this.$store.state.data;
},
error() {
return this.$store.state.error;
}
},
methods: {
sendData() {
this.$store.dispatch('sendData');
}
}
};
</script>
<style scoped>
h2 {
color: green;
}
</style>

View File

@@ -0,0 +1,34 @@
<!-- components/MyComponent.vue -->
<template>
<v-container>
<v-row>
<v-col>
<h2>{{ $t('myComponent.title') }}</h2>
<v-text-field v-model="param1" :label="$t('myComponent.param1Label')"></v-text-field>
<p>{{ $t('myComponent.param1') }}: {{ param1 }}</p>
</v-col>
</v-row>
</v-container>
</template>
<script>
export default {
computed: {
param1: {
get() {
return this.$store.state.param1;
},
set(value) {
this.$store.commit('setParam1', value);
}
}
}
};
</script>
<style scoped>
h2 {
color: blue;
}
</style>

102
pakaivue/index.html Normal file
View File

@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue App with SFC Loader</title>
<!-- Vuetify CSS -->
<link href="../css/vuetify.css" rel="stylesheet">
<!-- Local Stylesheet for Fonts -->
<link rel="stylesheet" href="../css/styles.css">
<link href="../css/materialdesignicon.css" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<!-- Vue.js -->
<script src="../libraries/vue3.4.36.global.prod.js"></script>
<!-- Vuex -->
<script src="../libraries/vuex.js"></script>
<!-- Vuetify -->
<script src="../libraries/vuetify3.js"></script>
<!-- vue-i18n -->
<script src="../libraries/vue-i18n.global.js"></script>
<!-- Axios -->
<script src="../libraries/axios.js"></script>
<!-- vue-sfc-loader -->
<script src="../libraries/vue3-sfc-loader.js"></script>
<!-- Store JS -->
<script type="module">
import store from './store/index.js';
const { loadModule } = window['vue-sfc-loader'];
const messages = {
en: {
message: {
login: 'Login',
email: 'Email',
password: 'Password',
forgotPassword: 'Forgot password?',
placeholderEmail: 'Enter your email',
placeholderPassword: 'Enter your password',
param1: 'Parameter 1',
param2: 'Parameter 2',
response: 'Response',
error: 'Error'
}
},
id: {
message: {
login: 'Masuk',
email: 'Surel',
password: 'Kata Sandi',
forgotPassword: 'Lupa kata sandi?',
placeholderEmail: 'Isikan email anda',
placeholderPassword: 'Isikan kata sandi anda',
param1: 'Parameter 1',
param2: 'Parameter 2',
response: 'Respons',
error: 'Kesalahan'
}
}
};
const browserLocale = navigator.language || navigator.languages[0];
const i18n = VueI18n.createI18n({
locale: browserLocale.startsWith('id') ? 'id' : 'en',
fallbackLocale: 'en',
messages,
});
const options = {
moduleCache: {
vue: Vue,
},
getFile(url) {
return fetch(url).then(response => response.ok ? response.text() : Promise.reject(response));
},
addStyle(textContent) {
const style = Object.assign(document.createElement('style'), { textContent });
const ref = document.head.getElementsByTagName('style')[0] || null;
document.head.insertBefore(style, ref);
}
};
const app = Vue.createApp({
components: {
'component-a': Vue.defineAsyncComponent(() => loadModule('./components/ComponentA.vue', options)),
'component-b': Vue.defineAsyncComponent(() => loadModule('./components/ComponentB.vue', options))
}
});
const vuetify = Vuetify.createVuetify();
app.use(store);
app.use(vuetify);
app.use(i18n);
app.mount('#app');
</script>
</body>
</html>

45
pakaivue/store/index.js Normal file
View File

@@ -0,0 +1,45 @@
// store/index.js
import { createStore } from '../../libraries/vuex.js';
import axios from '../../libraries/axios.js';
const store = createStore({
state() {
return {
data: null,
error: null,
param1: 'value1',
param2: 'value2'
};
},
mutations: {
setData(state, payload) {
state.data = payload;
},
setError(state, error) {
state.error = error;
},
setParam1(state, value) {
state.param1 = value;
},
setParam2(state, value) {
state.param2 = value;
}
},
actions: {
async sendData({ state, commit }) {
const params = {
param1: state.param1,
param2: state.param2
};
try {
const response = await axios.post('https://example.com/api/endpoint', params);
commit('setData', response.data);
} catch (error) {
commit('setError', error);
}
}
}
});
export default store;

View File

@@ -0,0 +1,26 @@
// components/ComponentA.js
const ComponentA = {
template: `
<div>
<h2>Component A</h2>
<p>Count: {{ count }}</p>
<v-btn @click="increment">Increment</v-btn>
<v-btn @click="decrement">Decrement</v-btn>
</div>
`,
computed: {
count() {
return this.$store.state.count;
}
},
methods: {
increment() {
this.$store.dispatch('increment');
},
decrement() {
this.$store.dispatch('decrement');
}
}
};

View File

@@ -0,0 +1,22 @@
// components/ComponentB.js
const ComponentB = {
template: `
<div>
<h2>Component B</h2>
<p>Data: {{ data }}</p>
<v-btn @click="fetchData">Fetch Data</v-btn>
</div>
`,
computed: {
data() {
return this.$store.state.data;
}
},
methods: {
async fetchData() {
await this.$store.dispatch('fetchData');
}
}
};

View File

@@ -0,0 +1,77 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue 3 with Vuetify, Vuex, and Multiple Components</title>
<!-- Vuetify CSS -->
<link href="https://cdn.jsdelivr.net/npm/vuetify@3/dist/vuetify.min.css" rel="stylesheet">
<!-- Google Fonts (optional) -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
</head>
<body>
<div id="app"></div>
<!-- Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue@3"></script>
<!-- Vuex -->
<script src="https://cdn.jsdelivr.net/npm/vuex@next"></script>
<!-- Vuetify -->
<script src="https://cdn.jsdelivr.net/npm/vuetify@3"></script>
<!-- Axios -->
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<!-- Store JS -->
<script src="store/store.js"></script>
<!-- Component JS -->
<script src="components/ComponentA.js"></script>
<script src="components/ComponentB.js"></script>
<script>
// Define Vue components in global scope
//Vue.createApp({}).component('component-a', ComponentA);
//Vue.createApp({}).component('component-b', ComponentB);
// Vue App
const app = Vue.createApp({
components: {
'component-a': ComponentA,
'component-b': ComponentB
},
setup() {
const store = Vuex.useStore();
const count = Vue.computed(() => store.state.count);
const data = Vue.computed(() => store.state.data);
function increment() {
store.dispatch('increment');
}
function decrement() {
store.dispatch('decrement');
}
function fetchData() {
store.dispatch('fetchData');
}
return { count, data, increment, decrement, fetchData };
},
template: `
<v-container>
<v-card>
<component-a></component-a>
<component-b></component-b>
</v-container>
`
});
const vuetify = Vuetify.createVuetify();
app.use(store);
app.use(vuetify);
app.mount('#app');
</script>
</body>
</html>

View File

@@ -0,0 +1,46 @@
// store/store.js
const store = Vuex.createStore({
state() {
return {
count: 0,
data: null
};
},
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
setData(state, payload) {
state.data = payload;
}
},
actions: {
increment({ commit }) {
commit('increment');
},
decrement({ commit }) {
commit('decrement');
},
async fetchData({ commit }) {
try {
let prm = {
"bank": "",
"account": "",
"current_page": 1,
"lastid": -1,
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJNX1VzZXJJRCI6IjIiLCJNX1VzZXJFbWFpbCI6Impva29AZ21haWwuY29tIiwiTV9Vc2VyVXNlcm5hbWUiOiJqb2tvQGdtYWlsLmNvbSIsIk1fVXNlckdyb3VwRGFzaGJvYXJkIjoib25lLXVpXC90ZXN0XC92dWV4XC9jcG9uZS1zZXR1cC1tY3UtdjNcLyIsIk1fVXNlckRlZmF1bHRUX1NhbXBsZVN0YXRpb25JRCI6IjEiLCJNX1N0YWZmTmFtZSI6IlBFVFVHQVMgU0FNUExFIExBQiIsImlzX2NvdXJpZXIiOiJOIiwidGltZV9hdXRvbG9nb3V0IjoiMTAwMDAwMDAiLCJpcCI6IjE2Ny4xNzIuNjcuNTMiLCJhZ2VudCI6IkdvLWh0dHAtY2xpZW50XC8xLjEiLCJ2ZXJzaW9uIjoidjIiLCJsYXN0LWxvZ2luIjoiMjAyNC0wNy0yNiAwODo0NjozNyJ9.hd-Qt5Y2n9y5In3S1kTbvNkQ7kqG0pcbjajNcJdqAvM"
}
const response = await axios.post('https://cpone.aplikasi.web.id/one-api/mockup/masterdata/bank/lookupbankbyname',prm);
console.log(response.data.data.records)
commit('setData', response.data.data.records);
} catch (error) {
console.error('Error fetching data:', error);
}
}
}
});