feat(app): add WGRplane web UI and backend features

- Add Vue 3 frontend with glassmorphism design (Tailwind CSS)
- Add Go backend handlers: auth, webhooks, stats, scheduler, validation
- Add i18n support (EN, ID, ZH)
- Add Swagger docs and API handlers
- Add nftables integration and plugins support
- Remove deprecated go.mod (migrated to wgrplane)
This commit is contained in:
datadunia
2026-05-03 23:20:34 +07:00
parent 3eae539a56
commit 6d8899a078
54 changed files with 7395 additions and 434 deletions
@@ -0,0 +1,61 @@
<template>
<div class="space-y-2">
<label class="block text-sm font-medium text-white/70 mb-1">Subscribed Actions</label>
<div class="grid grid-cols-2 gap-2">
<label
v-for="action in availableActions"
:key="action.value"
class="flex items-center gap-2 p-2 bg-white/5 rounded-lg border border-white/10 hover:border-cyan-400/50 transition-colors cursor-pointer"
>
<input
type="checkbox"
:value="action.value"
:checked="modelValue.includes(action.value)"
@change="toggleAction(action.value)"
class="w-4 h-4 rounded border-white/20 bg-white/5 text-cyan-500 focus:ring-cyan-500 focus:ring-offset-0"
/>
<span class="text-sm text-white">{{ action.label }}</span>
</label>
</div>
</div>
</template>
<script setup lang="ts">
interface Action {
label: string
value: string
}
const props = defineProps<{
modelValue: string[]
availableActions?: Action[]
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: string[]): void
}>()
const defaultActions: Action[] = [
{ label: 'Peer Connected', value: 'peer.connected' },
{ label: 'Peer Disconnected', value: 'peer.disconnected' },
{ label: 'Peer Added', value: 'peer.added' },
{ label: 'Peer Removed', value: 'peer.removed' },
{ label: 'Policy Updated', value: 'policy.updated' },
{ label: 'Server Started', value: 'server.started' },
{ label: 'Server Stopped', value: 'server.stopped' },
{ label: 'Login Failed', value: 'auth.failed' }
]
const availableActions = props.availableActions || defaultActions
const toggleAction = (value: string) => {
const current = [...props.modelValue]
const index = current.indexOf(value)
if (index === -1) {
current.push(value)
} else {
current.splice(index, 1)
}
emit('update:modelValue', current)
}
</script>