first
This commit is contained in:
153
inspond-nuxt-safekiso/components/StatisticsTable1.vue
Normal file
153
inspond-nuxt-safekiso/components/StatisticsTable1.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<div class="flex flex-col">
|
||||
<div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div
|
||||
class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8"
|
||||
>
|
||||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
v-for="(heading, index) in headings"
|
||||
:key="index"
|
||||
:width="
|
||||
heading['widthRatio'] != ''
|
||||
? heading['widthRatio'] + '%'
|
||||
: '100%'
|
||||
"
|
||||
:class="
|
||||
index == 0
|
||||
? 'py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 md:pl-0'
|
||||
: 'py-3.5 px-3 text-left text-sm font-semibold text-gray-900'
|
||||
"
|
||||
scope="col"
|
||||
>
|
||||
{{ heading['title'] }}
|
||||
</th>
|
||||
|
||||
<th
|
||||
v-for="(action, index) in actions"
|
||||
:key="index + headings.length"
|
||||
:width="actions.length * 1"
|
||||
class="relative py-3.5 pl-3 pr-4 sm:pr-6 md:pr-0"
|
||||
scope="col"
|
||||
>
|
||||
<span class="sr-only">{{ action }}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
<tr v-for="(item, itemIndex) in data" :key="itemIndex">
|
||||
<td
|
||||
v-for="(heading, index) in headings"
|
||||
:key="index"
|
||||
:class="
|
||||
index == 0
|
||||
? 'whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 md:pl-0'
|
||||
: 'whitespace-nowrap py-4 px-3 text-sm text-gray-500'
|
||||
"
|
||||
>
|
||||
{{
|
||||
columnFilter
|
||||
? columnFilter(
|
||||
heading['key'],
|
||||
item[heading['key']]
|
||||
)
|
||||
: item[heading['key']]
|
||||
}}
|
||||
</td>
|
||||
|
||||
<td
|
||||
class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 md:pr-0"
|
||||
>
|
||||
<a
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
href="javascript:void(0)"
|
||||
:class="index != 0 ? 'ml-3' : ''"
|
||||
class="text-indigo-600 hover:text-indigo-900"
|
||||
@click="doAction(action, item[actionKey])"
|
||||
>{{ action
|
||||
}}<span class="sr-only"
|
||||
>, {{ item['serial'] }}</span
|
||||
></a
|
||||
>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="data.length == 0">
|
||||
<td
|
||||
:colspan="headings.length"
|
||||
class="whitespace-nowrap py-4 px-3 text-sm text-gray-500"
|
||||
>
|
||||
{{ noDataMessage }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th
|
||||
v-for="(heading, index) in headings"
|
||||
:key="index"
|
||||
:width="
|
||||
heading['widthRatio'] != ''
|
||||
? heading['widthRatio'] + '%'
|
||||
: '100%'
|
||||
"
|
||||
:class="
|
||||
index == 0
|
||||
? 'py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 md:pl-0'
|
||||
: 'py-3.5 px-3 text-left text-sm font-semibold text-gray-900'
|
||||
"
|
||||
scope="col"
|
||||
>
|
||||
{{
|
||||
index == 0
|
||||
? '합계'
|
||||
: calcSum(heading['key'])
|
||||
}}
|
||||
</th>
|
||||
|
||||
<th
|
||||
v-for="(action, index) in actions"
|
||||
:key="index + headings.length"
|
||||
:width="actions.length * 1"
|
||||
class="relative py-3.5 pl-3 pr-4 sm:pr-6 md:pr-0"
|
||||
scope="col"
|
||||
>
|
||||
<span class="sr-only">{{ action }}</span>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
headings: { type: Array<object>, required: true },
|
||||
actions: { type: Array<string>, default: [] },
|
||||
data: { type: Array<object>, required: true },
|
||||
actionKey: { type: String, default: 'serial' },
|
||||
columnFilter: {
|
||||
type: Function,
|
||||
default: (key: string, val: string) => val,
|
||||
},
|
||||
doAction: {
|
||||
type: Function,
|
||||
default: (key: string) => {
|
||||
return key;
|
||||
},
|
||||
},
|
||||
noDataMessage: { type: String, default: '조회된 데이터가 없습니다.' },
|
||||
});
|
||||
|
||||
function calcSum(tag) {
|
||||
let tmpSum = 0;
|
||||
for (let i = 0; i < props.data.length; i++) {
|
||||
tmpSum += props.data[i][tag];
|
||||
}
|
||||
return tmpSum;
|
||||
}
|
||||
</script>
|
||||
96
inspond-nuxt-safekiso/components/StickyFooter.vue
Normal file
96
inspond-nuxt-safekiso/components/StickyFooter.vue
Normal file
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<section
|
||||
class="block fixed bottom-0 inset-x-0 z-50 shadow-lg text-gray-800 bg-gray-700 dark:bg-dark backdrop-blur-lg bg-opacity-30 dark:bg-opacity-30 dark:text-gray-400 border-t-2 border-royal/20"
|
||||
>
|
||||
<div id="tabs" class="flex justify-between">
|
||||
<a
|
||||
href="#"
|
||||
class="w-full focus:text-royal hover:text-royal justify-center inline-block text-center pt-2 pb-1 hover:bg-white"
|
||||
activeClass="dark:text-gray-100 text-black"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6 inline-block mb-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"
|
||||
/>
|
||||
</svg>
|
||||
<span class="tab block text-xs">Home</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
class="w-full focus:text-royal hover:text-royal justify-center inline-block text-center pt-2 pb-1 hover:bg-white"
|
||||
activeClass="dark:text-gray-100 text-black"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6 inline-block mb-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="tab block text-xs">Categories</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
class="w-full focus:text-royal hover:text-royal justify-center inline-block text-center pt-2 pb-1 hover:bg-white"
|
||||
activeClass="dark:text-gray-100 text-black"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6 inline-block mb-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="tab block text-xs">Gallery</span>
|
||||
</a>
|
||||
<a
|
||||
href="#"
|
||||
class="w-full focus:text-royal hover:text-royal justify-center inline-block text-center pt-2 pb-1 hover:bg-white"
|
||||
activeClass="dark:text-gray-100 text-black"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6 inline-block mb-1"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
|
||||
/>
|
||||
</svg>
|
||||
<span class="tab block text-xs">About</span>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts"></script>
|
||||
|
||||
<style lang="css" scoped></style>
|
||||
75
inspond-nuxt-safekiso/components/barChart.ts
Normal file
75
inspond-nuxt-safekiso/components/barChart.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { defineComponent, h, PropType } from 'vue';
|
||||
|
||||
import { Bar } from 'vue-chartjs';
|
||||
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
BarElement,
|
||||
CategoryScale,
|
||||
LinearScale,
|
||||
Plugin,
|
||||
} from 'chart.js';
|
||||
|
||||
ChartJS.register(
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
BarElement,
|
||||
CategoryScale,
|
||||
LinearScale
|
||||
);
|
||||
|
||||
export default defineComponent({
|
||||
name: 'BarChart',
|
||||
components: {
|
||||
Bar,
|
||||
},
|
||||
props: {
|
||||
chartId: {
|
||||
type: String,
|
||||
default: 'bar-chart',
|
||||
},
|
||||
chartData: {
|
||||
type: Object,
|
||||
},
|
||||
chartOptions: {
|
||||
type: Object,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 400,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400,
|
||||
},
|
||||
cssClasses: {
|
||||
default: '',
|
||||
type: String,
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<Partial<CSSStyleDeclaration>>,
|
||||
default: () => {},
|
||||
},
|
||||
plugins: {
|
||||
type: Array as PropType<Plugin<'bar'>[]>,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
return () =>
|
||||
h(Bar, {
|
||||
chartData: props.chartData,
|
||||
chartOptions: props.chartOptions,
|
||||
chartId: props.chartId,
|
||||
width: props.width,
|
||||
height: props.height,
|
||||
cssClasses: props.cssClasses,
|
||||
styles: props.styles,
|
||||
plugins: props.plugins,
|
||||
});
|
||||
},
|
||||
});
|
||||
76
inspond-nuxt-safekiso/components/lineChart.ts
Normal file
76
inspond-nuxt-safekiso/components/lineChart.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import { defineComponent, h, PropType } from 'vue';
|
||||
|
||||
import { Line } from 'vue-chartjs';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
CategoryScale,
|
||||
Plugin,
|
||||
} from 'chart.js';
|
||||
|
||||
ChartJS.register(
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
LineElement,
|
||||
LinearScale,
|
||||
PointElement,
|
||||
CategoryScale
|
||||
);
|
||||
|
||||
export default defineComponent({
|
||||
name: 'LineChart',
|
||||
components: {
|
||||
Line,
|
||||
},
|
||||
props: {
|
||||
chartId: {
|
||||
type: String,
|
||||
default: 'line-chart',
|
||||
},
|
||||
chartData: {
|
||||
type: Object,
|
||||
},
|
||||
chartOptions: {
|
||||
type: Object,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 400,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400,
|
||||
},
|
||||
cssClasses: {
|
||||
default: '',
|
||||
type: String,
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<Partial<CSSStyleDeclaration>>,
|
||||
default: () => {},
|
||||
},
|
||||
plugins: {
|
||||
type: Array as PropType<Plugin<'line'>[]>,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
return () =>
|
||||
h(Line, {
|
||||
chartData: props.chartData,
|
||||
chartOptions: props.chartOptions,
|
||||
chartId: props.chartId,
|
||||
width: props.width,
|
||||
height: props.height,
|
||||
cssClasses: props.cssClasses,
|
||||
styles: props.styles,
|
||||
plugins: props.plugins,
|
||||
});
|
||||
},
|
||||
});
|
||||
66
inspond-nuxt-safekiso/components/pieChart.ts
Normal file
66
inspond-nuxt-safekiso/components/pieChart.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { defineComponent, h, PropType } from 'vue';
|
||||
|
||||
import { Pie } from 'vue-chartjs';
|
||||
import {
|
||||
Chart as ChartJS,
|
||||
Title,
|
||||
Tooltip,
|
||||
Legend,
|
||||
ArcElement,
|
||||
CategoryScale,
|
||||
Plugin,
|
||||
} from 'chart.js';
|
||||
|
||||
ChartJS.register(Title, Tooltip, Legend, ArcElement, CategoryScale);
|
||||
|
||||
export default defineComponent({
|
||||
name: 'PieChart',
|
||||
components: {
|
||||
Pie,
|
||||
},
|
||||
props: {
|
||||
chartId: {
|
||||
type: String,
|
||||
default: 'pie-chart',
|
||||
},
|
||||
chartData: {
|
||||
type: Object,
|
||||
},
|
||||
chartOptions: {
|
||||
type: Object,
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 400,
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400,
|
||||
},
|
||||
cssClasses: {
|
||||
default: '',
|
||||
type: String,
|
||||
},
|
||||
styles: {
|
||||
type: Object as PropType<Partial<CSSStyleDeclaration>>,
|
||||
default: () => {},
|
||||
},
|
||||
plugins: {
|
||||
type: Array as PropType<Plugin<'pie'>[]>,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
return () =>
|
||||
h(Pie, {
|
||||
chartData: props.chartData,
|
||||
chartOptions: props.chartOptions,
|
||||
chartId: props.chartId,
|
||||
width: props.width,
|
||||
height: props.height,
|
||||
cssClasses: props.cssClasses,
|
||||
styles: props.styles,
|
||||
plugins: props.plugins,
|
||||
});
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user