build: add vscode launch config and tailwind config
Add launch configuration for Chrome debugging in VSCode and set up TailwindCSS configuration with animations and theme customization
This commit is contained in:
Vendored
+15
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "chrome",
|
||||||
|
"request": "launch",
|
||||||
|
"name": "Launch Chrome against localhost",
|
||||||
|
"url": "http://localhost:3000",
|
||||||
|
"webRoot": "${workspaceFolder}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -95,3 +95,24 @@ The basic git workflow follows these steps:
|
|||||||
- Example: `feat: add new feature`
|
- Example: `feat: add new feature`
|
||||||
4. Push your changes to `dev`
|
4. Push your changes to `dev`
|
||||||
5. Create a pull request from `dev` to `main`
|
5. Create a pull request from `dev` to `main`
|
||||||
|
ini yang pakai reka tadi (kemajuan wkwkw)
|
||||||
|
{
|
||||||
|
"$schema": "https://shadcn-vue.com/schema.json",
|
||||||
|
"style": "new-york",
|
||||||
|
"typescript": true,
|
||||||
|
"tailwind": {
|
||||||
|
"config": "",
|
||||||
|
"css": "app/assets/css/tailwind.css",
|
||||||
|
"baseColor": "neutral",
|
||||||
|
"cssVariables": true,
|
||||||
|
"prefix": ""
|
||||||
|
},
|
||||||
|
"aliases": {
|
||||||
|
"components": "~/components/pub",
|
||||||
|
"composables": "~/composables",
|
||||||
|
"utils": "~/lib/utils",
|
||||||
|
"ui": "~/components/pub/ui",
|
||||||
|
"lib": "~/lib"
|
||||||
|
},
|
||||||
|
"iconLibrary": "lucide"
|
||||||
|
}
|
||||||
|
|||||||
+38
-40
@@ -21,9 +21,9 @@
|
|||||||
--muted: 210 25% 95%;
|
--muted: 210 25% 95%;
|
||||||
--muted-foreground: 210 15% 50%;
|
--muted-foreground: 210 15% 50%;
|
||||||
|
|
||||||
/* Accent - Professional Blue */
|
/* Accent - Neutral Gray */
|
||||||
--accent: 210 100% 50%;
|
--accent: 210 40% 96%;
|
||||||
--accent-foreground: 0 0% 100%;
|
--accent-foreground: 222.2 84% 4.9%;
|
||||||
--destructive: 0 75% 55%;
|
--destructive: 0 75% 55%;
|
||||||
--destructive-foreground: 0 0% 100%;
|
--destructive-foreground: 0 0% 100%;
|
||||||
--border: 210 20% 88%;
|
--border: 210 20% 88%;
|
||||||
@@ -67,45 +67,43 @@
|
|||||||
--sidebar-accent-foreground: 240 5.9% 10%;
|
--sidebar-accent-foreground: 240 5.9% 10%;
|
||||||
--sidebar-border: 220 13% 91%;
|
--sidebar-border: 220 13% 91%;
|
||||||
--sidebar-ring: 217.2 91.2% 59.8%;
|
--sidebar-ring: 217.2 91.2% 59.8%;
|
||||||
|
/* .dark { */
|
||||||
|
/* --background: 210 25% 8%; */
|
||||||
|
/* --foreground: 210 20% 95%; */
|
||||||
|
/* --card: 210 25% 10%; */
|
||||||
|
/* --card-foreground: 210 20% 95%; */
|
||||||
|
/* --popover: 210 25% 10%; */
|
||||||
|
/* --popover-foreground: 210 20% 95%; */
|
||||||
|
/* --primary: 150 75% 45%; */
|
||||||
|
/* --primary-foreground: 0 0% 100%; */
|
||||||
|
/* --primary-hover: 150 75% 50%; */
|
||||||
|
/* --secondary: 210 25% 15%; */
|
||||||
|
/* --secondary-foreground: 210 20% 90%; */
|
||||||
|
/* --muted: 210 25% 15%; */
|
||||||
|
/* --muted-foreground: 210 15% 65%; */
|
||||||
|
/* --accent: 210 100% 55%; */
|
||||||
|
/* --accent-foreground: 0 0% 100%; */
|
||||||
|
/* --destructive: 0 75% 60%; */
|
||||||
|
/* --destructive-foreground: 0 0% 100%; */
|
||||||
|
/* --border: 210 25% 20%; */
|
||||||
|
/* --input: 210 25% 15%; */
|
||||||
|
/* --ring: 150 75% 45%; */
|
||||||
|
/* --success: 150 75% 50%; */
|
||||||
|
/* --warning: 45 95% 65%; */
|
||||||
|
/* --info: 210 100% 60%; */
|
||||||
|
/* --gradient-primary: linear-gradient(135deg, hsl(150 75% 45%), hsl(150 75% 55%)); */
|
||||||
|
/* --gradient-medical: linear-gradient(135deg, hsl(150 75% 45%), hsl(210 100% 55%)); */
|
||||||
|
/* --gradient-subtle: linear-gradient(180deg, hsl(210 25% 8%), hsl(210 25% 12%)); */
|
||||||
|
/* --sidebar-background: 240 5.9% 10%; */
|
||||||
|
/* --sidebar-foreground: 240 4.8% 95.9%; */
|
||||||
|
/* --sidebar-primary: 224.3 76.3% 48%; */
|
||||||
|
/* --sidebar-primary-foreground: 0 0% 100%; */
|
||||||
|
/* --sidebar-accent: 240 3.7% 15.9%; */
|
||||||
|
/* --sidebar-accent-foreground: 240 4.8% 95.9%; */
|
||||||
|
/* --sidebar-border: 240 3.7% 15.9%; */
|
||||||
|
/* --sidebar-ring: 217.2 91.2% 59.8%; */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .dark { */
|
|
||||||
/* --background: 210 25% 8%; */
|
|
||||||
/* --foreground: 210 20% 95%; */
|
|
||||||
/* --card: 210 25% 10%; */
|
|
||||||
/* --card-foreground: 210 20% 95%; */
|
|
||||||
/* --popover: 210 25% 10%; */
|
|
||||||
/* --popover-foreground: 210 20% 95%; */
|
|
||||||
/* --primary: 150 75% 45%; */
|
|
||||||
/* --primary-foreground: 0 0% 100%; */
|
|
||||||
/* --primary-hover: 150 75% 50%; */
|
|
||||||
/* --secondary: 210 25% 15%; */
|
|
||||||
/* --secondary-foreground: 210 20% 90%; */
|
|
||||||
/* --muted: 210 25% 15%; */
|
|
||||||
/* --muted-foreground: 210 15% 65%; */
|
|
||||||
/* --accent: 210 100% 55%; */
|
|
||||||
/* --accent-foreground: 0 0% 100%; */
|
|
||||||
/* --destructive: 0 75% 60%; */
|
|
||||||
/* --destructive-foreground: 0 0% 100%; */
|
|
||||||
/* --border: 210 25% 20%; */
|
|
||||||
/* --input: 210 25% 15%; */
|
|
||||||
/* --ring: 150 75% 45%; */
|
|
||||||
/* --success: 150 75% 50%; */
|
|
||||||
/* --warning: 45 95% 65%; */
|
|
||||||
/* --info: 210 100% 60%; */
|
|
||||||
/* --gradient-primary: linear-gradient(135deg, hsl(150 75% 45%), hsl(150 75% 55%)); */
|
|
||||||
/* --gradient-medical: linear-gradient(135deg, hsl(150 75% 45%), hsl(210 100% 55%)); */
|
|
||||||
/* --gradient-subtle: linear-gradient(180deg, hsl(210 25% 8%), hsl(210 25% 12%)); */
|
|
||||||
/* --sidebar-background: 240 5.9% 10%; */
|
|
||||||
/* --sidebar-foreground: 240 4.8% 95.9%; */
|
|
||||||
/* --sidebar-primary: 224.3 76.3% 48%; */
|
|
||||||
/* --sidebar-primary-foreground: 0 0% 100%; */
|
|
||||||
/* --sidebar-accent: 240 3.7% 15.9%; */
|
|
||||||
/* --sidebar-accent-foreground: 240 4.8% 95.9%; */
|
|
||||||
/* --sidebar-border: 240 3.7% 15.9%; */
|
|
||||||
/* --sidebar-ring: 217.2 91.2% 59.8%; */
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
/* Keyframes for Animations */
|
/* Keyframes for Animations */
|
||||||
@keyframes accordion-down {
|
@keyframes accordion-down {
|
||||||
from {
|
from {
|
||||||
|
|||||||
@@ -1,260 +1,51 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { DateValue } from '@internationalized/date'
|
|
||||||
import type { DateRange } from 'radix-vue'
|
import type { DateRange } from 'radix-vue'
|
||||||
import type { Grid } from 'radix-vue/date'
|
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import { CalendarDate } from '@internationalized/date'
|
import {
|
||||||
import { Calendar as CalendarIcon, ChevronLeft, ChevronRight } from 'lucide-vue-next'
|
CalendarDate,
|
||||||
import { RangeCalendarRoot, useDateFormatter } from 'radix-vue'
|
DateFormatter,
|
||||||
import { createMonth, toDate } from 'radix-vue/date'
|
getLocalTimeZone,
|
||||||
import { buttonVariants } from '~/components/pub/ui/button'
|
} from '@internationalized/date'
|
||||||
|
import { Calendar as CalendarIcon } from 'lucide-vue-next'
|
||||||
import { cn } from '~/lib/utils'
|
import { cn } from '~/lib/utils'
|
||||||
|
|
||||||
// Props untuk kustomisasi
|
const df = new DateFormatter('en-US', {
|
||||||
interface Props {
|
dateStyle: 'medium',
|
||||||
modelValue?: DateRange
|
|
||||||
placeholder?: string
|
|
||||||
class?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
placeholder: 'Pick a date range',
|
|
||||||
class: '',
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const value = ref({
|
||||||
'update:modelValue': [value: DateRange]
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const value = ref(props.modelValue || {
|
|
||||||
start: new CalendarDate(2022, 1, 20),
|
start: new CalendarDate(2022, 1, 20),
|
||||||
end: new CalendarDate(2022, 2, 9),
|
end: new CalendarDate(2022, 1, 20).add({ days: 20 }),
|
||||||
}) as Ref<DateRange>
|
}) as Ref<DateRange>
|
||||||
|
|
||||||
watch(value, (newValue) => {
|
|
||||||
emit('update:modelValue', newValue)
|
|
||||||
}, { deep: true })
|
|
||||||
|
|
||||||
const locale = ref('en-US')
|
|
||||||
const formatter = useDateFormatter(locale.value)
|
|
||||||
|
|
||||||
const placeholder = ref(value.value.start) as Ref<DateValue>
|
|
||||||
const secondMonthPlaceholder = ref(value.value.end) as Ref<DateValue>
|
|
||||||
|
|
||||||
// Create independent month grids
|
|
||||||
const firstMonth = ref(
|
|
||||||
createMonth({
|
|
||||||
dateObj: placeholder.value,
|
|
||||||
locale: locale.value,
|
|
||||||
fixedWeeks: true,
|
|
||||||
weekStartsOn: 0,
|
|
||||||
}),
|
|
||||||
) as Ref<Grid<DateValue>>
|
|
||||||
|
|
||||||
const secondMonth = ref(
|
|
||||||
createMonth({
|
|
||||||
dateObj: secondMonthPlaceholder.value,
|
|
||||||
locale: locale.value,
|
|
||||||
fixedWeeks: true,
|
|
||||||
weekStartsOn: 0,
|
|
||||||
}),
|
|
||||||
) as Ref<Grid<DateValue>>
|
|
||||||
|
|
||||||
// Function to update months independently
|
|
||||||
function updateMonth(reference: 'first' | 'second', months: number) {
|
|
||||||
if (reference === 'first') {
|
|
||||||
placeholder.value = placeholder.value.add({ months })
|
|
||||||
} else {
|
|
||||||
secondMonthPlaceholder.value = secondMonthPlaceholder.value.add({ months })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Watch first month placeholder
|
|
||||||
watch(placeholder, (_placeholder) => {
|
|
||||||
firstMonth.value = createMonth({
|
|
||||||
dateObj: _placeholder,
|
|
||||||
weekStartsOn: 0,
|
|
||||||
fixedWeeks: true,
|
|
||||||
locale: locale.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Watch second month placeholder
|
|
||||||
watch(secondMonthPlaceholder, (_secondMonthPlaceholder) => {
|
|
||||||
secondMonth.value = createMonth({
|
|
||||||
dateObj: _secondMonthPlaceholder,
|
|
||||||
weekStartsOn: 0,
|
|
||||||
fixedWeeks: true,
|
|
||||||
locale: locale.value,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="cn('w-full', props.class)">
|
<Popover>
|
||||||
<Popover>
|
<PopoverTrigger as-child>
|
||||||
<PopoverTrigger as-child>
|
<Button
|
||||||
<Button variant="outline" :class="cn(
|
variant="outline"
|
||||||
'w-full justify-start text-left font-normal',
|
:class="cn(
|
||||||
|
'w-[280px] justify-start text-left font-normal',
|
||||||
!value && 'text-muted-foreground',
|
!value && 'text-muted-foreground',
|
||||||
)">
|
)"
|
||||||
<CalendarIcon class="mr-2 h-4 w-4" />
|
>
|
||||||
<template v-if="value.start">
|
<CalendarIcon class="mr-2 h-4 w-4" />
|
||||||
<template v-if="value.end">
|
<template v-if="value.start">
|
||||||
{{
|
<template v-if="value.end">
|
||||||
formatter.custom(toDate(value.start), {
|
{{ df.format(value.start.toDate(getLocalTimeZone())) }} - {{ df.format(value.end.toDate(getLocalTimeZone())) }}
|
||||||
dateStyle: 'medium',
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
-
|
|
||||||
{{
|
|
||||||
formatter.custom(toDate(value.end), {
|
|
||||||
dateStyle: 'medium',
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else>
|
|
||||||
{{
|
|
||||||
formatter.custom(toDate(value.start), {
|
|
||||||
dateStyle: 'medium',
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ props.placeholder }}
|
{{ df.format(value.start.toDate(getLocalTimeZone())) }}
|
||||||
</template>
|
</template>
|
||||||
</Button>
|
</template>
|
||||||
</PopoverTrigger>
|
<template v-else>
|
||||||
<PopoverContent
|
Pick a date
|
||||||
class="w-auto p-0 rounded-xl shadow-lg border bg-white dark:bg-neutral-900 z-50 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
|
</template>
|
||||||
align="start">
|
</Button>
|
||||||
<RangeCalendarRoot v-slot="{ weekDays }" v-model="value" v-model:placeholder="placeholder" class="p-4">
|
</PopoverTrigger>
|
||||||
<div class="flex flex-col gap-6 sm:flex-row sm:gap-8">
|
<PopoverContent class="w-auto p-0">
|
||||||
<!-- First Month -->
|
<RangeCalendar v-model="value" initial-focus :number-of-months="2" @update:start-value="(startDate) => value.start = startDate" />
|
||||||
<div class="flex flex-col gap-4">
|
</PopoverContent>
|
||||||
<div class="flex items-center justify-between">
|
</Popover>
|
||||||
<Button :class="cn(
|
|
||||||
buttonVariants({ variant: 'outline' }),
|
|
||||||
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
|
||||||
)" @click="updateMonth('first', -1)">
|
|
||||||
<ChevronLeft class="h-4 w-4 text-primary" />
|
|
||||||
</Button>
|
|
||||||
<div class="text-sm font-medium">
|
|
||||||
{{
|
|
||||||
formatter.fullMonthAndYear(
|
|
||||||
toDate(firstMonth.value),
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
<Button :class="cn(
|
|
||||||
buttonVariants({ variant: 'outline' }),
|
|
||||||
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
|
||||||
)" @click="updateMonth('first', 1)">
|
|
||||||
<ChevronRight class="h-4 w-4 text-primary" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<RangeCalendarGrid>
|
|
||||||
<RangeCalendarGridHead>
|
|
||||||
<RangeCalendarGridRow>
|
|
||||||
<RangeCalendarHeadCell v-for="day in weekDays" :key="day" class="w-full">
|
|
||||||
{{ day }}
|
|
||||||
</RangeCalendarHeadCell>
|
|
||||||
</RangeCalendarGridRow>
|
|
||||||
</RangeCalendarGridHead>
|
|
||||||
<RangeCalendarGridBody class="mt-2">
|
|
||||||
<RangeCalendarGridRow v-for="(weekDates, index) in firstMonth.rows" :key="`weekDate-${index}`"
|
|
||||||
class="w-full">
|
|
||||||
<RangeCalendarCell v-for="weekDate in weekDates" :key="weekDate.toString()" :date="weekDate">
|
|
||||||
<RangeCalendarCellTrigger :day="weekDate" :month="firstMonth.value" :class="cn(
|
|
||||||
'h-9 w-9 p-0 text-sm rounded-md transition-colors flex items-center justify-center',
|
|
||||||
|
|
||||||
// tanggal bulan lain (past/next month)
|
|
||||||
'data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50',
|
|
||||||
|
|
||||||
// tanggal terpilih (start / end)
|
|
||||||
'data-[selected]:bg-green-600 data-[selected]:text-white',
|
|
||||||
|
|
||||||
// tanggal dalam rentang
|
|
||||||
'data-[in-range]:bg-green-500 data-[in-range]:text-white',
|
|
||||||
|
|
||||||
// rounded pill untuk range
|
|
||||||
'data-[selection-start]:rounded-l-full data-[selection-end]:rounded-r-full',
|
|
||||||
|
|
||||||
// hover
|
|
||||||
'hover:bg-accent hover:text-accent-foreground'
|
|
||||||
)" />
|
|
||||||
|
|
||||||
</RangeCalendarCell>
|
|
||||||
</RangeCalendarGridRow>
|
|
||||||
</RangeCalendarGridBody>
|
|
||||||
</RangeCalendarGrid>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Second Month -->
|
|
||||||
<div class="flex flex-col gap-4">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<Button :class="cn(
|
|
||||||
buttonVariants({ variant: 'outline' }),
|
|
||||||
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
|
||||||
)" @click="updateMonth('second', -1)">
|
|
||||||
<ChevronLeft class="h-4 w-4 text-primary" />
|
|
||||||
</Button>
|
|
||||||
<div class="text-sm font-medium">
|
|
||||||
{{
|
|
||||||
formatter.fullMonthAndYear(
|
|
||||||
toDate(secondMonth.value),
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</div>
|
|
||||||
<Button :class="cn(
|
|
||||||
buttonVariants({ variant: 'outline' }),
|
|
||||||
'h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100',
|
|
||||||
)" @click="updateMonth('second', 1)">
|
|
||||||
<ChevronRight class="h-4 w-4 text-primary" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<RangeCalendarGrid>
|
|
||||||
<RangeCalendarGridHead>
|
|
||||||
<RangeCalendarGridRow>
|
|
||||||
<RangeCalendarHeadCell v-for="day in weekDays" :key="day" class="w-full">
|
|
||||||
{{ day }}
|
|
||||||
</RangeCalendarHeadCell>
|
|
||||||
</RangeCalendarGridRow>
|
|
||||||
</RangeCalendarGridHead>
|
|
||||||
<RangeCalendarGridBody class="mt-2">
|
|
||||||
<RangeCalendarGridRow v-for="(weekDates, index) in secondMonth.rows" :key="`weekDate-${index}`"
|
|
||||||
class="w-full">
|
|
||||||
<RangeCalendarCell v-for="weekDate in weekDates" :key="weekDate.toString()" :date="weekDate">
|
|
||||||
<RangeCalendarCellTrigger :day="weekDate" :month="secondMonth.value" :class="cn(
|
|
||||||
'h-9 w-9 p-0 text-sm rounded-md transition-colors flex items-center justify-center',
|
|
||||||
|
|
||||||
// tanggal bulan lain (past/next month)
|
|
||||||
'data-[outside-month]:text-muted-foreground data-[outside-month]:opacity-50',
|
|
||||||
|
|
||||||
// tanggal terpilih (start / end)
|
|
||||||
'data-[selected]:bg-green-600 data-[selected]:text-white',
|
|
||||||
|
|
||||||
// tanggal dalam rentang
|
|
||||||
'data-[in-range]:bg-green-500 data-[in-range]:text-white',
|
|
||||||
|
|
||||||
// rounded pill untuk range
|
|
||||||
'data-[selection-start]:rounded-l-full data-[selection-end]:rounded-r-full',
|
|
||||||
|
|
||||||
// hover
|
|
||||||
'hover:bg-accent hover:text-accent-foreground'
|
|
||||||
)" />
|
|
||||||
|
|
||||||
</RangeCalendarCell>
|
|
||||||
</RangeCalendarGridRow>
|
|
||||||
</RangeCalendarGridBody>
|
|
||||||
</RangeCalendarGrid>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</RangeCalendarRoot>
|
|
||||||
</PopoverContent>
|
|
||||||
</Popover>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ const activeTabFilter = computed({
|
|||||||
|
|
||||||
<!-- Search Input -->
|
<!-- Search Input -->
|
||||||
|
|
||||||
|
<AppSatusehatPicker/>
|
||||||
<div class="relative w-full max-w-sm">
|
<div class="relative w-full max-w-sm">
|
||||||
|
|
||||||
<Dialog>
|
<Dialog>
|
||||||
|
|||||||
+1
-2
@@ -1,5 +1,4 @@
|
|||||||
import type { ClassValue } from 'clsx'
|
import { type ClassValue, clsx } from 'clsx'
|
||||||
import { clsx } from 'clsx'
|
|
||||||
import { twMerge } from 'tailwind-merge'
|
import { twMerge } from 'tailwind-merge'
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
|||||||
+6
-8
@@ -1,20 +1,18 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://shadcn-vue.com/schema.json",
|
"$schema": "https://radix.shadcn-vue.com/schema.json",
|
||||||
"style": "new-york",
|
"style": "new-york",
|
||||||
"typescript": true,
|
"typescript": true,
|
||||||
|
"tsConfigPath": ".nuxt/tsconfig.json",
|
||||||
"tailwind": {
|
"tailwind": {
|
||||||
"config": "",
|
"config": "tailwind.config.ts",
|
||||||
"css": "app/assets/css/main.css",
|
"css": "app/assets/css/main.css",
|
||||||
"baseColor": "neutral",
|
"baseColor": "neutral",
|
||||||
"cssVariables": true,
|
"cssVariables": true,
|
||||||
"prefix": ""
|
"prefix": ""
|
||||||
},
|
},
|
||||||
|
"framework": "nuxt",
|
||||||
"aliases": {
|
"aliases": {
|
||||||
"components": "~/components/pub",
|
"components": "~/components/pub",
|
||||||
"composables": "~/composables",
|
"utils": "~/lib/utils"
|
||||||
"utils": "~/lib/utils",
|
}
|
||||||
"ui": "~/components/pub/ui",
|
|
||||||
"lib": "~/lib"
|
|
||||||
},
|
|
||||||
"iconLibrary": "lucide"
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -1,17 +1,22 @@
|
|||||||
|
import process from 'node:process'
|
||||||
|
|
||||||
// https://nuxt.com/docs/api/configuration/nuxt-config
|
// https://nuxt.com/docs/api/configuration/nuxt-config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
devtools: { enabled: true },
|
devtools: { enabled: true },
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
API_ORIGIN: process.env.API_ORIGIN || 'https://main-api.dev-hopis.sabbi.id',
|
API_ORIGIN: process.env.API_ORIGIN || 'https://main-api.dev-hopis.sabbi.id',
|
||||||
},
|
},
|
||||||
|
ssr: false,
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
'@unocss/nuxt',
|
'@unocss/nuxt',
|
||||||
'shadcn-nuxt',
|
|
||||||
'@vueuse/nuxt',
|
'@vueuse/nuxt',
|
||||||
'@nuxt/eslint',
|
'@nuxt/eslint',
|
||||||
'@nuxt/icon',
|
'@nuxt/icon',
|
||||||
'@pinia/nuxt',
|
'@pinia/nuxt',
|
||||||
'@nuxtjs/color-mode',
|
'@nuxtjs/color-mode',
|
||||||
|
'@nuxtjs/tailwindcss',
|
||||||
|
'shadcn-nuxt',
|
||||||
],
|
],
|
||||||
|
|
||||||
css: ['@unocss/reset/tailwind.css', '~/assets/css/main.css'],
|
css: ['@unocss/reset/tailwind.css', '~/assets/css/main.css'],
|
||||||
|
|||||||
+4
-2
@@ -17,6 +17,7 @@
|
|||||||
"@iconify-json/lucide": "^1.2.30",
|
"@iconify-json/lucide": "^1.2.30",
|
||||||
"@iconify-json/radix-icons": "^1.2.2",
|
"@iconify-json/radix-icons": "^1.2.2",
|
||||||
"@internationalized/date": "^3.7.0",
|
"@internationalized/date": "^3.7.0",
|
||||||
|
"@radix-icons/vue": "^1.0.0",
|
||||||
"@unovis/ts": "^1.5.1",
|
"@unovis/ts": "^1.5.1",
|
||||||
"@unovis/vue": "^1.5.1",
|
"@unovis/vue": "^1.5.1",
|
||||||
"embla-carousel": "^8.5.2",
|
"embla-carousel": "^8.5.2",
|
||||||
@@ -24,7 +25,7 @@
|
|||||||
"h3": "^1.15.4",
|
"h3": "^1.15.4",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"pinia-plugin-persistedstate": "^4.4.1",
|
"pinia-plugin-persistedstate": "^4.4.1",
|
||||||
"reka-ui": "^2.4.1"
|
"tailwindcss-animate": "^1.0.7"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^4.10.1",
|
"@antfu/eslint-config": "^4.10.1",
|
||||||
@@ -32,12 +33,13 @@
|
|||||||
"@nuxt/icon": "^1.15.0",
|
"@nuxt/icon": "^1.15.0",
|
||||||
"@nuxt/test-utils": "^3.19.2",
|
"@nuxt/test-utils": "^3.19.2",
|
||||||
"@nuxtjs/color-mode": "^3.5.2",
|
"@nuxtjs/color-mode": "^3.5.2",
|
||||||
|
"@nuxtjs/tailwindcss": "6.14.0",
|
||||||
"@pinia/nuxt": "^0.11.2",
|
"@pinia/nuxt": "^0.11.2",
|
||||||
"@unocss/eslint-plugin": "^66.0.0",
|
"@unocss/eslint-plugin": "^66.0.0",
|
||||||
"@unocss/nuxt": "^66.0.0",
|
"@unocss/nuxt": "^66.0.0",
|
||||||
"@vee-validate/zod": "^4.15.0",
|
"@vee-validate/zod": "^4.15.0",
|
||||||
"@vue/test-utils": "^2.4.6",
|
"@vue/test-utils": "^2.4.6",
|
||||||
"@vueuse/core": "^12.2.0",
|
"@vueuse/core": "^12.8.2",
|
||||||
"@vueuse/math": "^12.2.0",
|
"@vueuse/math": "^12.2.0",
|
||||||
"@vueuse/nuxt": "^12.2.0",
|
"@vueuse/nuxt": "^12.2.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
|
|||||||
Generated
+654
-88
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,86 @@
|
|||||||
|
import animate from 'tailwindcss-animate'
|
||||||
|
|
||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
export default {
|
||||||
|
darkMode: ['class'],
|
||||||
|
safelist: ['dark'],
|
||||||
|
prefix: '',
|
||||||
|
|
||||||
|
theme: {
|
||||||
|
container: {
|
||||||
|
center: true,
|
||||||
|
padding: '2rem',
|
||||||
|
screens: {
|
||||||
|
'2xl': '1400px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
border: 'hsl(var(--border))',
|
||||||
|
input: 'hsl(var(--input))',
|
||||||
|
ring: 'hsl(var(--ring))',
|
||||||
|
background: 'hsl(var(--background))',
|
||||||
|
foreground: 'hsl(var(--foreground))',
|
||||||
|
primary: {
|
||||||
|
DEFAULT: 'hsl(var(--primary))',
|
||||||
|
foreground: 'hsl(var(--primary-foreground))',
|
||||||
|
},
|
||||||
|
secondary: {
|
||||||
|
DEFAULT: 'hsl(var(--secondary))',
|
||||||
|
foreground: 'hsl(var(--secondary-foreground))',
|
||||||
|
},
|
||||||
|
destructive: {
|
||||||
|
DEFAULT: 'hsl(var(--destructive))',
|
||||||
|
foreground: 'hsl(var(--destructive-foreground))',
|
||||||
|
},
|
||||||
|
muted: {
|
||||||
|
DEFAULT: 'hsl(var(--muted))',
|
||||||
|
foreground: 'hsl(var(--muted-foreground))',
|
||||||
|
},
|
||||||
|
accent: {
|
||||||
|
DEFAULT: 'hsl(var(--accent))',
|
||||||
|
foreground: 'hsl(var(--accent-foreground))',
|
||||||
|
},
|
||||||
|
popover: {
|
||||||
|
DEFAULT: 'hsl(var(--popover))',
|
||||||
|
foreground: 'hsl(var(--popover-foreground))',
|
||||||
|
},
|
||||||
|
card: {
|
||||||
|
DEFAULT: 'hsl(var(--card))',
|
||||||
|
foreground: 'hsl(var(--card-foreground))',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
borderRadius: {
|
||||||
|
xl: 'calc(var(--radius) + 4px)',
|
||||||
|
lg: 'var(--radius)',
|
||||||
|
md: 'calc(var(--radius) - 2px)',
|
||||||
|
sm: 'calc(var(--radius) - 4px)',
|
||||||
|
},
|
||||||
|
keyframes: {
|
||||||
|
'accordion-down': {
|
||||||
|
from: { height: 0 },
|
||||||
|
to: { height: 'var(--radix-accordion-content-height)' },
|
||||||
|
},
|
||||||
|
'accordion-up': {
|
||||||
|
from: { height: 'var(--radix-accordion-content-height)' },
|
||||||
|
to: { height: 0 },
|
||||||
|
},
|
||||||
|
'collapsible-down': {
|
||||||
|
from: { height: 0 },
|
||||||
|
to: { height: 'var(--radix-collapsible-content-height)' },
|
||||||
|
},
|
||||||
|
'collapsible-up': {
|
||||||
|
from: { height: 'var(--radix-collapsible-content-height)' },
|
||||||
|
to: { height: 0 },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
animation: {
|
||||||
|
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||||
|
'accordion-up': 'accordion-up 0.2s ease-out',
|
||||||
|
'collapsible-down': 'collapsible-down 0.2s ease-in-out',
|
||||||
|
'collapsible-up': 'collapsible-up 0.2s ease-in-out',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [animate],
|
||||||
|
}
|
||||||
@@ -29,4 +29,5 @@ export default defineConfig({
|
|||||||
rules: [
|
rules: [
|
||||||
// Custom rules if needed
|
// Custom rules if needed
|
||||||
],
|
],
|
||||||
|
inspector: true,
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user