@wishbone-media/spark 0.1.4 → 0.2.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wishbone-media/spark",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -12,12 +12,13 @@
12
12
  "@headlessui/vue": "^1.7.0",
13
13
  "@fortawesome/fontawesome-svg-core": "^6.7.2",
14
14
  "@fortawesome/pro-regular-svg-icons": "^6.7.2",
15
- "vue": "^3.5.0"
15
+ "pinia": "^3.0.3",
16
+ "vue": "^3.5.16"
16
17
  },
17
18
  "devDependencies": {
18
19
  "@vitejs/plugin-vue": "^5.2.4",
19
20
  "vite": "^6.3.5",
20
- "vue": "^3.5.13"
21
+ "vue": "^3.5.16"
21
22
  },
22
23
  "packageManager": "pnpm@10.11.1",
23
24
  "scripts": {
Binary file
@@ -0,0 +1,120 @@
1
+ <template>
2
+ <div class="flex grow flex-col gap-y-5 overflow-y-auto bg-white rounded-lg">
3
+ <div class="flex flex-1 flex-col">
4
+ <div class="divide-y divide-gray-200">
5
+ <div class="flex px-[22px] py-2.5 text-[12px] items-center">
6
+ <div>Mr Group Network</div>
7
+ <div class="ml-auto flex items-center">
8
+ <font-awesome-icon
9
+ :icon="Icons.farTimes"
10
+ class="h-[15px] w-[15px] shrink-0 text-gray-400 cursor-pointer"
11
+ @click="emit('close')"
12
+ />
13
+ </div>
14
+ </div>
15
+ <div
16
+ v-for="app in appsWithCurrent"
17
+ :key="app.name"
18
+ :class="app.current ? 'bg-gray-50' : 'hover:bg-gray-50'"
19
+ class="flex px-[22px] py-[15px] cursor-pointer"
20
+ @click="openNewTab(app)"
21
+ >
22
+ <div class="gap-y-1">
23
+ <div class="text-base text-gray-800 flex items-center">
24
+ <div class="font-medium">{{ app.name }}</div>
25
+ <span
26
+ v-if="app.current"
27
+ class="inline-flex items-center rounded-full bg-green-100 px-1.5 py-0.5 text-xs font-medium text-green-700 ml-1"
28
+ >
29
+ Active
30
+ </span>
31
+ </div>
32
+ <div class="text-sm text-gray-500">{{ app.description }}</div>
33
+ </div>
34
+ <div class="ml-auto flex items-center">
35
+ <font-awesome-icon
36
+ :class="app.current ? 'text-gray-700' : 'text-gray-400'"
37
+ :icon="Icons[app.icon]"
38
+ class="h-5 w-5 shrink-0"
39
+ />
40
+ </div>
41
+ </div>
42
+ <div></div>
43
+ </div>
44
+ <div class="mt-auto">
45
+ <div class="p-6">Learn More</div>
46
+ <div class="bg-gray-50 p-6">Footer</div>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </template>
51
+
52
+ <script setup>
53
+ import { computed } from 'vue'
54
+ import { Icons } from '@/plugins/fontawesome'
55
+
56
+ const props = defineProps({
57
+ appItems: {
58
+ type: Array,
59
+ default() {
60
+ return [
61
+ {
62
+ name: '3CX',
63
+ description: 'VOIP Phone',
64
+ href: 'https://3cx.letsbolt.com.au',
65
+ icon: 'farLaptopMobile',
66
+ },
67
+ {
68
+ name: 'Buzz',
69
+ description: 'Communication on the go',
70
+ href: 'https://buzz.letsbolt.com.au',
71
+ icon: 'farSatelliteDish',
72
+ },
73
+ {
74
+ name: 'Dash',
75
+ description: 'Financial powerhouse',
76
+ href: 'https://dash.letsbolt.com.au',
77
+ icon: 'farScaleBalanced',
78
+ },
79
+ {
80
+ name: 'MAPit',
81
+ description: 'Geolocation everything',
82
+ href: 'https://mapit.letsbolt.com.au',
83
+ icon: 'farStreetView',
84
+ },
85
+ {
86
+ name: 'ProspectR',
87
+ description: 'Leads management',
88
+ href: 'https://prospectr.letsbolt.com.au',
89
+ icon: 'farFaceSmileRelaxed',
90
+ },
91
+ {
92
+ name: 'ReVuze',
93
+ description: 'Get Customer feedback',
94
+ href: 'https://revuze.letsbolt.com.au',
95
+ icon: 'farComments',
96
+ },
97
+ ]
98
+ },
99
+ },
100
+ currentApp: {
101
+ type: String,
102
+ default: 'Buzz',
103
+ },
104
+ })
105
+
106
+ const emit = defineEmits(['close', 'select'])
107
+
108
+ const appsWithCurrent = computed(() => {
109
+ return props.appItems.map(app => ({
110
+ ...app,
111
+ current: app.name === props.currentApp
112
+ }))
113
+ })
114
+
115
+ const openNewTab = (app) => {
116
+ window.open(app.href, '_blank')
117
+
118
+ emit('select', app)
119
+ }
120
+ </script>
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <div class="flex grow flex-col gap-y-5 overflow-y-auto bg-white rounded-lg">
3
+ <div class="flex flex-1 flex-col">
4
+ <div class="divide-y divide-gray-200">
5
+ <div class="flex px-[22px] py-2.5 text-[12px] items-center">
6
+ <div>Filter by Brand</div>
7
+ <div class="ml-auto flex items-center">
8
+ <font-awesome-icon
9
+ :icon="Icons.farTimes"
10
+ class="size-4 text-gray-400 cursor-pointer"
11
+ @click="emit('close')"
12
+ />
13
+ </div>
14
+ </div>
15
+ <div
16
+ v-for="brand in brandFilterStore.allBrands"
17
+ :key="brand.name"
18
+ :class="brand.current ? 'bg-gray-50' : 'hover:bg-gray-50'"
19
+ class="flex px-[22px] py-[15px] cursor-pointer"
20
+ @click="selectBrand(brand)"
21
+ >
22
+ <div class="gap-y-1 flex">
23
+ <div class="flex items-center mr-4">
24
+ <img :src="brand.logo" :alt="`${brand.name} logo`" class="h-8 w-auto" />
25
+ </div>
26
+ <div class="ml-auto flex flex-col">
27
+ <div class="text-base text-gray-800 flex items-center">
28
+ <div class="font-medium">{{ brand.name }}</div>
29
+ <span
30
+ v-if="brand.current"
31
+ class="inline-flex items-center rounded-full bg-green-100 px-1.5 py-0.5 text-xs font-medium text-green-700 ml-1"
32
+ >
33
+ Current
34
+ </span>
35
+ </div>
36
+ <div class="text-sm text-gray-500">
37
+ {{ brand.current ? 'Current Brand' : 'Change to' }}
38
+ </div>
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <div></div>
43
+ </div>
44
+ <div class="mt-auto"></div>
45
+ </div>
46
+ </div>
47
+ </template>
48
+
49
+ <script setup>
50
+ import { useBrandFilterStore } from '@/stores/brand-filter'
51
+ import { Icons } from '@/plugins/fontawesome'
52
+
53
+ const emit = defineEmits(['close', 'select'])
54
+
55
+ const brandFilterStore = useBrandFilterStore()
56
+
57
+ const selectBrand = (brand) => {
58
+ emit('select', brand)
59
+ }
60
+ </script>
@@ -34,7 +34,10 @@
34
34
  position === 'left' ? 'relative left-[10px]' : 'absolute right-[10px] h-full',
35
35
  ]"
36
36
  >
37
- <component :is="overlayInstance.state.content" v-bind="$attrs" />
37
+ <component
38
+ :is="overlayInstance.state.content"
39
+ v-bind="{ ...$attrs, ...overlayInstance.state.props }"
40
+ />
38
41
  </DialogPanel>
39
42
  </TransitionChild>
40
43
  </div>
@@ -1,5 +1,7 @@
1
1
  import SparkAlert from './SparkAlert.vue'
2
+ import SparkAppSelector from './SparkAppSelector.vue'
3
+ import SparkBrandSelector from './SparkBrandSelector.vue'
2
4
  import SparkModal from './SparkModal.vue'
3
5
  import SparkOverlay from './SparkOverlay.vue'
4
6
 
5
- export { SparkAlert, SparkModal, SparkOverlay }
7
+ export { SparkAlert, SparkAppSelector, SparkBrandSelector, SparkModal, SparkOverlay }
@@ -4,6 +4,7 @@ export function useSparkOverlay() {
4
4
  const state = reactive({
5
5
  isVisible: false,
6
6
  content: null,
7
+ props: {},
7
8
  })
8
9
 
9
10
  const toggle = () => {
@@ -18,12 +19,13 @@ export function useSparkOverlay() {
18
19
  state.isVisible = true
19
20
  }
20
21
 
21
- const setContent = (content) => {
22
+ const setContent = (content, props = {}) => {
22
23
  state.content = markRaw(content)
24
+ state.props = props
23
25
  }
24
26
 
25
- const show = (content) => {
26
- if (content) setContent(content)
27
+ const show = (content, props = {}) => {
28
+ if (content) setContent(content, props)
27
29
  open()
28
30
  }
29
31
 
package/src/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './components/index.js'
2
2
  export * from './composables/index.js'
3
- export * from './plugins/index.js'
3
+ export * from './plugins/index.js'
4
+ export * from './stores/index.js'
@@ -7,6 +7,13 @@ import {
7
7
  faCircleXmark,
8
8
  faXmark,
9
9
  faCheck,
10
+ faTimes,
11
+ faLaptopMobile,
12
+ faSatelliteDish,
13
+ faScaleBalanced,
14
+ faStreetView,
15
+ faFaceSmileRelaxed,
16
+ faComments,
10
17
  } from '@fortawesome/pro-regular-svg-icons'
11
18
 
12
19
  export const Icons = {
@@ -16,6 +23,13 @@ export const Icons = {
16
23
  farCircleXmark: faCircleXmark,
17
24
  farXmark: faXmark,
18
25
  farCheck: faCheck,
26
+ farTimes: faTimes,
27
+ farLaptopMobile: faLaptopMobile,
28
+ farSatelliteDish: faSatelliteDish,
29
+ farScaleBalanced: faScaleBalanced,
30
+ farStreetView: faStreetView,
31
+ farFaceSmileRelaxed: faFaceSmileRelaxed,
32
+ farComments: faComments,
19
33
  }
20
34
 
21
35
  export function addSparkIcons() {
@@ -0,0 +1,40 @@
1
+ import { defineStore } from 'pinia'
2
+ import { computed, reactive } from 'vue'
3
+
4
+ import mrPestControllerLogo from '@/assets/images/mr-pest-controller.png'
5
+ import mrGutterCleaningLogo from '@/assets/images/mr-gutter-cleaning.png'
6
+ import mrAntennaLogo from '@/assets/images/mr-antenna.png'
7
+
8
+ export const useBrandFilterStore = defineStore('brandFilter', () => {
9
+ const state = reactive({
10
+ brands: [
11
+ {
12
+ name: 'Mr Pest Controller',
13
+ logo: mrPestControllerLogo,
14
+ current: false,
15
+ },
16
+ {
17
+ name: 'Mr Gutter Cleaning',
18
+ logo: mrGutterCleaningLogo,
19
+ current: false,
20
+ },
21
+ { name: 'Mr Antenna', logo: mrAntennaLogo, current: true },
22
+ ],
23
+ })
24
+
25
+ const currentBrand = computed(() => state.brands.find((item) => item.current))
26
+ const allBrands = computed(() => state.brands)
27
+
28
+ const toggleBrand = (brand) => {
29
+ state.brands.forEach((item) => {
30
+ item.current = item === brand
31
+ })
32
+ }
33
+
34
+ return {
35
+ state,
36
+ currentBrand,
37
+ allBrands,
38
+ toggleBrand,
39
+ }
40
+ })
@@ -0,0 +1 @@
1
+ export * from './brand-filter.js'