@icvdeveloper/common-module 0.0.17 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +15 -0
- package/dist/runtime/components/core/Modal.vue +2 -2
- package/dist/runtime/components/forms/AlertBox.vue +21 -0
- package/dist/runtime/components/forms/SwitchInput.vue +96 -0
- package/dist/runtime/components/forms/TextInput.vue +6 -1
- package/dist/runtime/components/profile/Profile.vue +149 -0
- package/dist/runtime/components/profile/components/Sidebar.vue +27 -0
- package/dist/runtime/components/profile/components/SidebarNavItem.vue +39 -0
- package/dist/runtime/components/profile/tabs/Favorites.vue +21 -0
- package/dist/runtime/components/profile/tabs/GeneralInformation.vue +122 -0
- package/dist/runtime/components/profile/tabs/ProfileImage.vue +75 -0
- package/dist/runtime/composables/index.d.ts +11 -0
- package/dist/runtime/composables/index.mjs +11 -0
- package/dist/runtime/composables/useAuth.d.ts +5 -0
- package/dist/runtime/composables/useAuth.mjs +11 -0
- package/dist/runtime/models/authUser.d.ts +1 -1
- package/dist/runtime/models/globalConfig.d.ts +1 -0
- package/dist/runtime/plugin.mjs +2 -0
- package/dist/runtime/store/auth.d.ts +2 -0
- package/dist/runtime/store/auth.mjs +36 -2
- package/dist/runtime/store/templateConfigs.d.ts +1 -1
- package/package.json +2 -2
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { join, resolve } from 'path';
|
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
3
|
import { defineNuxtModule, useLogger, installModule, addPlugin, addAutoImportDir, addComponentsDir } from '@nuxt/kit';
|
|
4
4
|
import svgLoader from 'vite-svg-loader';
|
|
5
|
+
import { find, remove } from 'lodash-es';
|
|
5
6
|
|
|
6
7
|
// -- Unbuild CommonJS Shims --
|
|
7
8
|
import __cjs_url__ from 'url';
|
|
@@ -143,6 +144,20 @@ const module = defineNuxtModule({
|
|
|
143
144
|
extensions: ["vue"],
|
|
144
145
|
prefix: "Common"
|
|
145
146
|
});
|
|
147
|
+
addComponentsDir({
|
|
148
|
+
path: join(runtimeDir, "components/profile"),
|
|
149
|
+
extensions: ["vue"],
|
|
150
|
+
prefix: "Common"
|
|
151
|
+
});
|
|
152
|
+
nuxt.hook("app:resolve", (nuxt2) => {
|
|
153
|
+
const piniaRuntime = find(nuxt2.plugins, (object) => {
|
|
154
|
+
return object.src.includes("@pinia");
|
|
155
|
+
});
|
|
156
|
+
nuxt2.plugins = remove(nuxt2.plugins, (object) => {
|
|
157
|
+
return !object.src.includes("@pinia");
|
|
158
|
+
});
|
|
159
|
+
nuxt2.plugins.unshift(piniaRuntime);
|
|
160
|
+
});
|
|
146
161
|
}
|
|
147
162
|
});
|
|
148
163
|
|
|
@@ -20,9 +20,9 @@ const emit = defineEmits(["trigger", "clicked"]);
|
|
|
20
20
|
const { visible, modalSize, noScroll, showClose, usePadding } = toRefs(props);
|
|
21
21
|
|
|
22
22
|
const modalClass = computed(() => {
|
|
23
|
-
const padding = usePadding ? "p-6" : "";
|
|
23
|
+
const padding = usePadding.value ? "p-6" : "";
|
|
24
24
|
const classes = `relative w-full ${padding} m-auto flex-col flex rounded shadow bg-white modal-box`;
|
|
25
|
-
if (noScroll) {
|
|
25
|
+
if (noScroll.value) {
|
|
26
26
|
return classes + ` max-h-full overflow-hidden`;
|
|
27
27
|
} else {
|
|
28
28
|
return classes + ` overflow-y-auto`;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { toRefs } from "vue";
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
errors: Array<any>;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const props = defineProps<Props>();
|
|
9
|
+
|
|
10
|
+
const { errors } = toRefs(props);
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red">
|
|
15
|
+
<span class="inline-block align-middle">
|
|
16
|
+
<ul>
|
|
17
|
+
<li v-for="error in errors" :key="error[0]">{{ error[0] }}</li>
|
|
18
|
+
</ul>
|
|
19
|
+
</span>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
|
|
4
|
+
interface Props {
|
|
5
|
+
isEnabled: boolean;
|
|
6
|
+
color?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
10
|
+
color: "#4D4D4D",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const value = ref<boolean>(props.isEnabled);
|
|
14
|
+
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
(event: "toggle", value: boolean): void;
|
|
17
|
+
}>();
|
|
18
|
+
|
|
19
|
+
const toggle = () => {
|
|
20
|
+
value.value = !value.value;
|
|
21
|
+
emit("toggle", value.value);
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template id="switch-button">
|
|
26
|
+
<div class="switch-button-control">
|
|
27
|
+
<div
|
|
28
|
+
class="switch-button"
|
|
29
|
+
:class="{ enabled: value }"
|
|
30
|
+
:style="{ '--color': color }"
|
|
31
|
+
@click="toggle"
|
|
32
|
+
>
|
|
33
|
+
<div class="button" />
|
|
34
|
+
</div>
|
|
35
|
+
<div class="switch-button-label">
|
|
36
|
+
<slot />
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style lang="scss" scoped>
|
|
42
|
+
.switch-button-control {
|
|
43
|
+
display: flex;
|
|
44
|
+
flex-direction: row;
|
|
45
|
+
align-items: center;
|
|
46
|
+
|
|
47
|
+
.switch-button {
|
|
48
|
+
$switch-button-height: 1.6em;
|
|
49
|
+
$switch-button-color: var(--color);
|
|
50
|
+
$switch-button-border-thickness: 2px;
|
|
51
|
+
$switch-transition: all 0.3s ease-in-out;
|
|
52
|
+
$switch-is-rounded: true;
|
|
53
|
+
|
|
54
|
+
height: $switch-button-height;
|
|
55
|
+
width: calc(#{$switch-button-height} * 2);
|
|
56
|
+
border: $switch-button-border-thickness solid $switch-button-color;
|
|
57
|
+
box-shadow: inset 0px 0px $switch-button-border-thickness 0px
|
|
58
|
+
rgba(0, 0, 0, 0.33);
|
|
59
|
+
border-radius: if($switch-is-rounded, $switch-button-height, 0);
|
|
60
|
+
|
|
61
|
+
transition: $switch-transition;
|
|
62
|
+
|
|
63
|
+
$button-side-length: calc(
|
|
64
|
+
#{$switch-button-height} - (2 * #{$switch-button-border-thickness})
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
|
|
69
|
+
.button {
|
|
70
|
+
height: $button-side-length;
|
|
71
|
+
width: $button-side-length;
|
|
72
|
+
border: $switch-button-border-thickness solid $switch-button-color;
|
|
73
|
+
border-radius: if($switch-is-rounded, $button-side-length, 0);
|
|
74
|
+
background: $switch-button-color;
|
|
75
|
+
|
|
76
|
+
transition: $switch-transition;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
&.enabled {
|
|
80
|
+
background-color: $switch-button-color;
|
|
81
|
+
box-shadow: none;
|
|
82
|
+
|
|
83
|
+
.button {
|
|
84
|
+
background: white;
|
|
85
|
+
transform: translateX(
|
|
86
|
+
calc(#{$button-side-length} + (2 *#{$switch-button-border-thickness}))
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.switch-button-label {
|
|
93
|
+
margin-left: 10px;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { toRefs, reactive, ref, computed } from "vue";
|
|
3
|
+
import { find } from "lodash-es";
|
|
4
|
+
import { storeToRefs } from "pinia";
|
|
5
|
+
import { useAuthStore } from "../../store/auth";
|
|
6
|
+
import Sidebar from "./components/Sidebar.vue";
|
|
7
|
+
import SidebarNavItem from "./components/SidebarNavItem.vue";
|
|
8
|
+
import TabGeneralInformation from "./tabs/GeneralInformation.vue";
|
|
9
|
+
import TabFavorites from "./tabs/Favorites.vue";
|
|
10
|
+
import TabProfileImage from "./tabs/ProfileImage.vue";
|
|
11
|
+
|
|
12
|
+
type Props = {
|
|
13
|
+
visible?: boolean;
|
|
14
|
+
showFavorites?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type Tab = {
|
|
18
|
+
id: number;
|
|
19
|
+
name: string;
|
|
20
|
+
component: Component | null;
|
|
21
|
+
shouldShow: boolean;
|
|
22
|
+
selected: boolean;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// props
|
|
26
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
27
|
+
visible: false,
|
|
28
|
+
showFavorites: false,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// data
|
|
32
|
+
const { visible, showFavorites } = toRefs(props);
|
|
33
|
+
const { user } = storeToRefs(useAuthStore());
|
|
34
|
+
const tabs = reactive<Tab[]>([
|
|
35
|
+
{
|
|
36
|
+
id: 1,
|
|
37
|
+
name: "General Information",
|
|
38
|
+
component: TabGeneralInformation,
|
|
39
|
+
shouldShow: true,
|
|
40
|
+
selected: true,
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 2,
|
|
44
|
+
name: "Profile Image",
|
|
45
|
+
component: TabProfileImage,
|
|
46
|
+
shouldShow: true,
|
|
47
|
+
selected: false,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 3,
|
|
51
|
+
name: "Favorites",
|
|
52
|
+
component: TabFavorites,
|
|
53
|
+
shouldShow: showFavorites.value,
|
|
54
|
+
selected: false,
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
id: 4,
|
|
58
|
+
name: "Logout",
|
|
59
|
+
component: null,
|
|
60
|
+
shouldShow: true,
|
|
61
|
+
selected: false,
|
|
62
|
+
},
|
|
63
|
+
]);
|
|
64
|
+
|
|
65
|
+
// emits
|
|
66
|
+
const emit = defineEmits<{
|
|
67
|
+
(event: "close"): void;
|
|
68
|
+
}>();
|
|
69
|
+
|
|
70
|
+
// computed
|
|
71
|
+
const selectedTab = computed<Tab>(() => {
|
|
72
|
+
return find(tabs, {
|
|
73
|
+
selected: true,
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// actions
|
|
78
|
+
const { logout } = useAuthStore();
|
|
79
|
+
const closeModal = () => {
|
|
80
|
+
emit("close");
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const setTab = (id: number) => {
|
|
84
|
+
if (id === 4) {
|
|
85
|
+
logout();
|
|
86
|
+
closeModal();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const currentSelected = find(tabs, {
|
|
91
|
+
selected: true,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (currentSelected) {
|
|
95
|
+
currentSelected.selected = false;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const newSelected = find(tabs, {
|
|
99
|
+
id,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
newSelected.selected = true;
|
|
103
|
+
};
|
|
104
|
+
</script>
|
|
105
|
+
|
|
106
|
+
<template>
|
|
107
|
+
<CommonModal
|
|
108
|
+
:use-padding="false"
|
|
109
|
+
modal-size="60"
|
|
110
|
+
:visible="visible"
|
|
111
|
+
@trigger="closeModal"
|
|
112
|
+
>
|
|
113
|
+
<template #modal-body>
|
|
114
|
+
<div class="p-2">
|
|
115
|
+
<div class="flex flex-col md:flex-row w-full p-5">
|
|
116
|
+
<Sidebar :name="user.name">
|
|
117
|
+
<SidebarNavItem
|
|
118
|
+
v-for="tab in tabs"
|
|
119
|
+
:id="tab.id"
|
|
120
|
+
:key="tab.id"
|
|
121
|
+
class="cursor-pointer"
|
|
122
|
+
:active="tab.selected === true"
|
|
123
|
+
@click="setTab"
|
|
124
|
+
>
|
|
125
|
+
{{ tab.name }}
|
|
126
|
+
</SidebarNavItem>
|
|
127
|
+
</Sidebar>
|
|
128
|
+
|
|
129
|
+
<div class="md:w-3/4 content-container ml-0 md:ml-2">
|
|
130
|
+
<div
|
|
131
|
+
v-if="selectedTab"
|
|
132
|
+
class="rounded overflow-hidden shadow-lg w-full h-full p-5"
|
|
133
|
+
>
|
|
134
|
+
<h2 class="mb-4">
|
|
135
|
+
{{ selectedTab.name }}
|
|
136
|
+
</h2>
|
|
137
|
+
|
|
138
|
+
<component
|
|
139
|
+
:is="selectedTab.component"
|
|
140
|
+
v-if="selectedTab.component && selectedTab.shouldShow"
|
|
141
|
+
:user="user"
|
|
142
|
+
/>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</template>
|
|
148
|
+
</CommonModal>
|
|
149
|
+
</template>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { toRefs } from "vue";
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
name: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const props = defineProps<Props>();
|
|
9
|
+
|
|
10
|
+
const { name } = toRefs(props);
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<div
|
|
15
|
+
class="md:w-1/4 rounded overflow-hidden shadow-lg md:mr-2 mt-1 mb-4 md:mb-0 md:mt-0"
|
|
16
|
+
>
|
|
17
|
+
<div class="px-6 py-4">
|
|
18
|
+
<div class="font-bold text-xl mb-2">
|
|
19
|
+
{{ name }}
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<nav class="flex-grow md:block pb-0 md:pb-4 md:overflow-y-auto">
|
|
23
|
+
<slot />
|
|
24
|
+
</nav>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
</template>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { toRefs } from "vue";
|
|
3
|
+
|
|
4
|
+
type Props = {
|
|
5
|
+
active: boolean;
|
|
6
|
+
id: number;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const props = defineProps<Props>();
|
|
10
|
+
|
|
11
|
+
// reactive prop data
|
|
12
|
+
const { active, id } = toRefs(props);
|
|
13
|
+
|
|
14
|
+
// emits
|
|
15
|
+
const emit = defineEmits<{
|
|
16
|
+
(event: "click", value: number): void;
|
|
17
|
+
}>();
|
|
18
|
+
|
|
19
|
+
// methods
|
|
20
|
+
const onClick = () => {
|
|
21
|
+
emit("click", id.value);
|
|
22
|
+
};
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<template>
|
|
26
|
+
<a
|
|
27
|
+
:class="{ active: active }"
|
|
28
|
+
class="sidebar-nav-item block px-4 py-2 mt-2 mx-1 text-black text-sm no-underline font-semibold rounded-lg hover:bg-gray-500 focus:text-white hover:text-white focus:bg-gray-500 focus:outline-none focus:shadow-outline"
|
|
29
|
+
@click="onClick"
|
|
30
|
+
>
|
|
31
|
+
<slot />
|
|
32
|
+
</a>
|
|
33
|
+
</template>
|
|
34
|
+
|
|
35
|
+
<style scoped>
|
|
36
|
+
.active {
|
|
37
|
+
@apply bg-gray-500 text-white;
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { storeToRefs } from "pinia";
|
|
3
|
+
import { useAuthStore } from "../../../store/auth";
|
|
4
|
+
|
|
5
|
+
const { user } = storeToRefs(useAuthStore());
|
|
6
|
+
</script>
|
|
7
|
+
|
|
8
|
+
<template>
|
|
9
|
+
<div>
|
|
10
|
+
<div
|
|
11
|
+
v-for="favorite in user.favorites"
|
|
12
|
+
:key="favorite.id"
|
|
13
|
+
class="py-2 border-b"
|
|
14
|
+
>
|
|
15
|
+
<h3 class="pb-2">
|
|
16
|
+
{{ favorite.name }}
|
|
17
|
+
</h3>
|
|
18
|
+
<div v-html="favorite.description" />
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { storeToRefs } from "pinia";
|
|
3
|
+
import { ref, reactive } from "vue";
|
|
4
|
+
import { useAuthStore } from "../../../store/auth";
|
|
5
|
+
|
|
6
|
+
const { user } = storeToRefs(useAuthStore());
|
|
7
|
+
const formData = reactive({
|
|
8
|
+
title: user.value.title,
|
|
9
|
+
name: user.value.name,
|
|
10
|
+
company: user.value.company,
|
|
11
|
+
linkedin_url: user.value.linkedin_url,
|
|
12
|
+
twitter_url: user.value.twitter_url,
|
|
13
|
+
video_chat: user.value.video_chat ?? false,
|
|
14
|
+
});
|
|
15
|
+
const errors = ref<[]>([]);
|
|
16
|
+
const wasSaved = ref<boolean>(false);
|
|
17
|
+
|
|
18
|
+
// methods
|
|
19
|
+
const { update } = useAuthStore();
|
|
20
|
+
|
|
21
|
+
const toggleChat = (value: boolean) => {
|
|
22
|
+
formData.video_chat = value;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const handleForm = () => {
|
|
26
|
+
errors.value = [];
|
|
27
|
+
|
|
28
|
+
update(formData)
|
|
29
|
+
.then(() => {
|
|
30
|
+
wasSaved.value = true;
|
|
31
|
+
})
|
|
32
|
+
.catch((error) => {
|
|
33
|
+
if (error.response === 422) {
|
|
34
|
+
errors.value = error.response.data.errors;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<template>
|
|
41
|
+
<div class="flex justify-between flex-col">
|
|
42
|
+
<CommonAlertBox v-if="errors" :errors="errors" />
|
|
43
|
+
|
|
44
|
+
<div>
|
|
45
|
+
<div class="mb-4">
|
|
46
|
+
<label class="block text-grey-darker text-sm font-bold mb-2">
|
|
47
|
+
Title
|
|
48
|
+
</label>
|
|
49
|
+
<CommonTextInput
|
|
50
|
+
v-model="formData.title"
|
|
51
|
+
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight focus:outline-none focus:shadow-outline"
|
|
52
|
+
type="text"
|
|
53
|
+
placeholder="Title"
|
|
54
|
+
/>
|
|
55
|
+
</div>
|
|
56
|
+
<div class="mb-4">
|
|
57
|
+
<label class="block text-grey-darker text-sm font-bold mb-2">
|
|
58
|
+
Name
|
|
59
|
+
</label>
|
|
60
|
+
<CommonTextInput
|
|
61
|
+
v-model="formData.name"
|
|
62
|
+
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight focus:outline-none focus:shadow-outline"
|
|
63
|
+
type="text"
|
|
64
|
+
placeholder="Name"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="mb-4">
|
|
68
|
+
<label class="block text-grey-darker text-sm font-bold mb-2">
|
|
69
|
+
Company
|
|
70
|
+
</label>
|
|
71
|
+
<CommonTextInput
|
|
72
|
+
v-model="formData.company"
|
|
73
|
+
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight focus:outline-none focus:shadow-outline"
|
|
74
|
+
type="text"
|
|
75
|
+
placeholder="Company"
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="mb-4">
|
|
79
|
+
<label class="block text-grey-darker text-sm font-bold mb-2">
|
|
80
|
+
LinkedIn
|
|
81
|
+
</label>
|
|
82
|
+
<CommonTextInput
|
|
83
|
+
v-model="formData.linkedin_url"
|
|
84
|
+
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight focus:outline-none focus:shadow-outline"
|
|
85
|
+
type="text"
|
|
86
|
+
placeholder="LinkedIn URL"
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
<div class="mb-4">
|
|
90
|
+
<label class="block text-grey-darker text-sm font-bold mb-2">
|
|
91
|
+
Twitter
|
|
92
|
+
</label>
|
|
93
|
+
<CommonTextInput
|
|
94
|
+
v-model="formData.twitter_url"
|
|
95
|
+
class="shadow appearance-none border rounded w-full py-2 px-3 text-grey-darker leading-tight focus:outline-none focus:shadow-outline"
|
|
96
|
+
type="text"
|
|
97
|
+
placeholder="Twitter URL"
|
|
98
|
+
/>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<div class="mb-4">
|
|
102
|
+
<CommonSwitchInput
|
|
103
|
+
:is-enabled="formData.video_chat"
|
|
104
|
+
@toggle="toggleChat"
|
|
105
|
+
>
|
|
106
|
+
Enable Video Chat
|
|
107
|
+
</CommonSwitchInput>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<div>
|
|
111
|
+
<p v-if="wasSaved" class="text-green">Your profile was saved!</p>
|
|
112
|
+
|
|
113
|
+
<button
|
|
114
|
+
class="bg-blue hover:bg-blue-dark text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
|
|
115
|
+
type="button"
|
|
116
|
+
@click="handleForm"
|
|
117
|
+
>
|
|
118
|
+
Save
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</template>
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref, reactive } from "vue";
|
|
3
|
+
import { storeToRefs } from "pinia";
|
|
4
|
+
import { useAuthStore } from "../../../store/auth";
|
|
5
|
+
|
|
6
|
+
const { user } = storeToRefs(useAuthStore());
|
|
7
|
+
const wasSaved = ref<boolean>(false);
|
|
8
|
+
const errors = ref<[]>([]);
|
|
9
|
+
const formData = reactive({
|
|
10
|
+
profile_image: null,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
// methods
|
|
14
|
+
const { update } = useAuthStore();
|
|
15
|
+
|
|
16
|
+
const onFileChanged = (e) => {
|
|
17
|
+
errors.value = [];
|
|
18
|
+
|
|
19
|
+
const files = e.target.files || e.dataTransfer.files;
|
|
20
|
+
|
|
21
|
+
formData.profile_image = files[0];
|
|
22
|
+
|
|
23
|
+
update(formData)
|
|
24
|
+
.then(() => {
|
|
25
|
+
wasSaved.value = true;
|
|
26
|
+
})
|
|
27
|
+
.catch((error) => {
|
|
28
|
+
if (error.response.status === 422) {
|
|
29
|
+
errors.value = error.response.data.errors;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<template>
|
|
36
|
+
<div>
|
|
37
|
+
<div>
|
|
38
|
+
<CommonAlertBox :errors="errors" />
|
|
39
|
+
|
|
40
|
+
<img
|
|
41
|
+
v-if="user.profile_image"
|
|
42
|
+
:src="user.profile_image"
|
|
43
|
+
width="100"
|
|
44
|
+
height="100"
|
|
45
|
+
alt=""
|
|
46
|
+
/>
|
|
47
|
+
|
|
48
|
+
<div class="overflow-hidden relative w-64 mt-4 mb-4">
|
|
49
|
+
<p v-if="wasSaved" class="text-green">Your profile Image was saved!</p>
|
|
50
|
+
|
|
51
|
+
<button
|
|
52
|
+
class="rounded bg-blue hover:bg-blue-light text-white font-bold py-2 px-4 w-full inline-flex items-center"
|
|
53
|
+
>
|
|
54
|
+
<svg
|
|
55
|
+
fill="#FFF"
|
|
56
|
+
height="18"
|
|
57
|
+
viewBox="0 0 24 24"
|
|
58
|
+
width="18"
|
|
59
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
60
|
+
>
|
|
61
|
+
<path d="M0 0h24v24H0z" fill="none" />
|
|
62
|
+
<path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z" />
|
|
63
|
+
</svg>
|
|
64
|
+
<span class="ml-2">Change Profile Image</span>
|
|
65
|
+
</button>
|
|
66
|
+
<input
|
|
67
|
+
class="cursor-pointer absolute block py-2 px-4 w-full opacity-0 pin-r pin-t"
|
|
68
|
+
type="file"
|
|
69
|
+
accept="image/*"
|
|
70
|
+
@change="onFileChanged"
|
|
71
|
+
/>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</template>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./useAgenda";
|
|
2
|
+
export * from "./useAnalytics";
|
|
3
|
+
export * from "./useApi";
|
|
4
|
+
export * from "./useAuth";
|
|
5
|
+
export * from "./useConferenceHelpers";
|
|
6
|
+
export * from "./useDateFormat";
|
|
7
|
+
export * from "./useLogin";
|
|
8
|
+
export * from "./usePresentation";
|
|
9
|
+
export * from "./usePresenter";
|
|
10
|
+
export * from "./usePresenters";
|
|
11
|
+
export * from "./useV3plusCommonModule";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from "./useAgenda.mjs";
|
|
2
|
+
export * from "./useAnalytics.mjs";
|
|
3
|
+
export * from "./useApi.mjs";
|
|
4
|
+
export * from "./useAuth.mjs";
|
|
5
|
+
export * from "./useConferenceHelpers.mjs";
|
|
6
|
+
export * from "./useDateFormat.mjs";
|
|
7
|
+
export * from "./useLogin.mjs";
|
|
8
|
+
export * from "./usePresentation.mjs";
|
|
9
|
+
export * from "./usePresenter.mjs";
|
|
10
|
+
export * from "./usePresenters.mjs";
|
|
11
|
+
export * from "./useV3plusCommonModule.mjs";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { computed } from "vue";
|
|
2
|
+
import { useTemplateConfigsStore } from "../store/templateConfigs.mjs";
|
|
3
|
+
export const useAuth = () => {
|
|
4
|
+
const { globalConfigValue } = useTemplateConfigsStore();
|
|
5
|
+
const isLoginDisabled = computed(() => {
|
|
6
|
+
return !globalConfigValue("login_disabled") || globalConfigValue("login_process") === "disabled";
|
|
7
|
+
});
|
|
8
|
+
return {
|
|
9
|
+
isLoginDisabled
|
|
10
|
+
};
|
|
11
|
+
};
|
|
@@ -54,6 +54,7 @@ export interface Global {
|
|
|
54
54
|
html_header: HTMLVariable;
|
|
55
55
|
link_color: ColorVariable;
|
|
56
56
|
link_hover: ColorVariable;
|
|
57
|
+
login_disabled: ToggleVariable;
|
|
57
58
|
login_disabled_user_email: TextVariable;
|
|
58
59
|
login_disabled_user_password: TextVariable;
|
|
59
60
|
login_process: SelectVariable;
|
package/dist/runtime/plugin.mjs
CHANGED
|
@@ -2,6 +2,7 @@ import { defineNuxtPlugin } from "#app";
|
|
|
2
2
|
import { computed } from "vue";
|
|
3
3
|
import { storeToRefs } from "pinia";
|
|
4
4
|
import NProgress from "nprogress";
|
|
5
|
+
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
|
5
6
|
import { createV3plusCommonPlugin } from "./v3plusCommonPlugin.mjs";
|
|
6
7
|
import { usePortalStore } from "./store/portal.mjs";
|
|
7
8
|
import { useConferencesStore } from "./store/conferences.mjs";
|
|
@@ -12,6 +13,7 @@ export default defineNuxtPlugin((nuxtApp) => {
|
|
|
12
13
|
portalHash,
|
|
13
14
|
apiUrl
|
|
14
15
|
});
|
|
16
|
+
nuxtApp.$pinia.use(piniaPluginPersistedstate);
|
|
15
17
|
nuxtApp.$router.beforeEach(async (to, from) => {
|
|
16
18
|
NProgress.start();
|
|
17
19
|
const portalStore = usePortalStore();
|
|
@@ -11,4 +11,6 @@ export declare const useAuthStore: import("pinia").StoreDefinition<"auth", AuthS
|
|
|
11
11
|
isLoggedIn: (state: AuthStoreState) => boolean;
|
|
12
12
|
}, {
|
|
13
13
|
login(params: LoginParams): Promise<AuthUser>;
|
|
14
|
+
logout(): Promise<void>;
|
|
15
|
+
update(data: AuthUser): Promise<void>;
|
|
14
16
|
}>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineStore } from "pinia";
|
|
2
2
|
import { useApi } from "../composables/useApi.mjs";
|
|
3
3
|
export const useAuthStore = defineStore("auth", {
|
|
4
|
+
persist: true,
|
|
4
5
|
state: () => ({
|
|
5
6
|
user: null
|
|
6
7
|
}),
|
|
@@ -17,16 +18,49 @@ export const useAuthStore = defineStore("auth", {
|
|
|
17
18
|
method: "POST",
|
|
18
19
|
body: params
|
|
19
20
|
}).then((response) => {
|
|
20
|
-
this.
|
|
21
|
+
this.user = response;
|
|
21
22
|
const conferencesStore = useConferencesStore();
|
|
22
23
|
conferencesStore.getConferences().then(() => {
|
|
23
24
|
conferencesStore.getCurrentConference();
|
|
24
25
|
});
|
|
25
|
-
resolve(response
|
|
26
|
+
resolve(response);
|
|
26
27
|
}).catch((error) => {
|
|
27
28
|
reject(error);
|
|
28
29
|
});
|
|
29
30
|
});
|
|
31
|
+
},
|
|
32
|
+
logout() {
|
|
33
|
+
return new Promise((resolve) => {
|
|
34
|
+
this.user = null;
|
|
35
|
+
const conferencesStore = useConferencesStore();
|
|
36
|
+
conferencesStore.getConferences().then(() => {
|
|
37
|
+
conferencesStore.getCurrentConference();
|
|
38
|
+
});
|
|
39
|
+
resolve();
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
update(data) {
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
const request = useApi();
|
|
45
|
+
if (data.profile_image) {
|
|
46
|
+
const formData = new FormData();
|
|
47
|
+
formData.append("profile_image", data.profile_image, "profile_image");
|
|
48
|
+
request("user", { method: "POST", body: formData }).then((response) => {
|
|
49
|
+
resolve();
|
|
50
|
+
}).catch((error) => {
|
|
51
|
+
reject(error);
|
|
52
|
+
});
|
|
53
|
+
} else {
|
|
54
|
+
request("user", {
|
|
55
|
+
method: "POST",
|
|
56
|
+
body: data
|
|
57
|
+
}).then((response) => {
|
|
58
|
+
resolve();
|
|
59
|
+
}).catch((error) => {
|
|
60
|
+
reject(error);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
30
64
|
}
|
|
31
65
|
}
|
|
32
66
|
});
|
|
@@ -11,7 +11,7 @@ export interface TemplateConfigState {
|
|
|
11
11
|
}
|
|
12
12
|
export declare const useTemplateConfigsStore: import("pinia").StoreDefinition<"templateConfigs", TemplateConfigState, {
|
|
13
13
|
globalConfigValue: (state: TemplateConfigState) => (path: GlobalConfigKey, defaultValue?: any) => any;
|
|
14
|
-
globalConfig: (state: TemplateConfigState) => <T extends "accent_color_1" | "accent_color_2" | "accent_color_3" | "affiliate_page_button_alias" | "azure_ad_client_id" | "azure_ad_message" | "azure_ad_tenant_id" | "azure_ad_user_password" | "body_color_1" | "body_color_2" | "body_color_3" | "body_color_4" | "body_color_5" | "body_color_6" | "body_font_1" | "body_font_2" | "button_color_1" | "button_color_2" | "captions_bg_color" | "captions_font" | "captions_text_color" | "conference_photo_headers" | "custom_css" | "enable_peer5" | "enable_text_chat" | "enable_video_chat" | "external_reg_url" | "global_color_1" | "global_color_2" | "global_color_3" | "global_color_4" | "global_color_5" | "global_color_6" | "header_font_1" | "header_font_2" | "header_titles" | "heading_color_1" | "heading_color_2" | "heading_color_3" | "heading_color_4" | "heading_color_5" | "heading_color_6" | "hide_user_profile" | "html_footer" | "html_header" | "link_color" | "link_hover" | "login_disabled_user_email" | "login_disabled_user_password" | "login_process" | "login_redirect_enabled" | "muted_photo_headers" | "nav_color_1" | "nav_color_2" | "nav_color_3" | "nav_color_4" | "nav_color_5" | "paragraph_color_1" | "paragraph_color_2" | "presenter_icon_color_style" | "reg_button_alias" | "reg_button_enabled" | "secure_site_access_enabled" | "townhall_registration_enabled" | "townhall_registration_group" | "view_archive_button_alias" | "view_now_button_alias" | "view_preview_button_alias">(path: T, defaultValue?: any) => GlobalConfigKeyType<T>;
|
|
14
|
+
globalConfig: (state: TemplateConfigState) => <T extends "accent_color_1" | "accent_color_2" | "accent_color_3" | "affiliate_page_button_alias" | "azure_ad_client_id" | "azure_ad_message" | "azure_ad_tenant_id" | "azure_ad_user_password" | "body_color_1" | "body_color_2" | "body_color_3" | "body_color_4" | "body_color_5" | "body_color_6" | "body_font_1" | "body_font_2" | "button_color_1" | "button_color_2" | "captions_bg_color" | "captions_font" | "captions_text_color" | "conference_photo_headers" | "custom_css" | "enable_peer5" | "enable_text_chat" | "enable_video_chat" | "external_reg_url" | "global_color_1" | "global_color_2" | "global_color_3" | "global_color_4" | "global_color_5" | "global_color_6" | "header_font_1" | "header_font_2" | "header_titles" | "heading_color_1" | "heading_color_2" | "heading_color_3" | "heading_color_4" | "heading_color_5" | "heading_color_6" | "hide_user_profile" | "html_footer" | "html_header" | "link_color" | "link_hover" | "login_disabled" | "login_disabled_user_email" | "login_disabled_user_password" | "login_process" | "login_redirect_enabled" | "muted_photo_headers" | "nav_color_1" | "nav_color_2" | "nav_color_3" | "nav_color_4" | "nav_color_5" | "paragraph_color_1" | "paragraph_color_2" | "presenter_icon_color_style" | "reg_button_alias" | "reg_button_enabled" | "secure_site_access_enabled" | "townhall_registration_enabled" | "townhall_registration_group" | "view_archive_button_alias" | "view_now_button_alias" | "view_preview_button_alias">(path: T, defaultValue?: any) => GlobalConfigKeyType<T>;
|
|
15
15
|
pagesConfigValue: (state: TemplateConfigState) => (path: NestedKeyOf<Pages>, defaultValue?: any, conferenceId?: number) => any;
|
|
16
16
|
}, {
|
|
17
17
|
setPortalTemplateConfig(payload: any): Promise<TemplateConfig>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@icvdeveloper/common-module",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"lodash-es": "^4.17.21",
|
|
32
32
|
"nprogress": "^0.2.0",
|
|
33
33
|
"pinia": "^2.0.17",
|
|
34
|
-
"pinia-plugin-persistedstate": "^1.
|
|
34
|
+
"pinia-plugin-persistedstate": "^2.1.1",
|
|
35
35
|
"sass": "^1.54.2",
|
|
36
36
|
"sass-loader": "^13.0.2",
|
|
37
37
|
"vite-svg-loader": "^3.4.0"
|