Skip to content

Commit

Permalink
dev: frontend draft
Browse files Browse the repository at this point in the history
  • Loading branch information
johnson86tw committed Jan 20, 2025
1 parent bd296a8 commit 8d71a8d
Show file tree
Hide file tree
Showing 35 changed files with 810 additions and 259 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ Reviewer
Submitter
- 領取稿費

## Frontend

- For icon, use [lucide-vue-next](https://lucide.dev/icons)
- For Component, use [shadcn-vue](https://www.shadcn-vue.com/docs/components/accordion.html)
- Vue 3 + Vite + TypeScript + TailwindCSS


## Reference

- https://github.com/consenlabs/ethtaipei2023-aa-workshop
Expand Down
8 changes: 0 additions & 8 deletions frontend/README.md

This file was deleted.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"preview": "vite preview"
},
"dependencies": {
"@vueuse/core": "^12.4.0",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"lucide-vue-next": "^0.473.0",
Expand Down
29 changes: 29 additions & 0 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 38 additions & 3 deletions frontend/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import { Button } from '@/components/ui/button'
import { ref } from 'vue'
import { Settings } from 'lucide-vue-next'
const isConnected = ref(false)
const handleConnect = () => {
// TODO: Implement connection logic
isConnected.value = !isConnected.value
}
</script>

<template>
<div>
<router-view />
<div class="min-h-screen flex flex-col">
<header class="fixed top-0 left-0 right-0 z-50 bg-background border-b px-4 lg:px-6 h-14 flex items-center">
<div class="flex w-full max-w-6xl mx-auto justify-between items-center">
<div class="flex items-center gap-6">
<router-link to="/" class="">
<h1 class="font-semibold text-lg">RoyaltyAutoClaim</h1>
</router-link>
</div>

<div class="flex items-center gap-6">
<Button @click="handleConnect" :variant="isConnected ? 'default' : 'outline'">
{{ isConnected ? 'Connected' : 'Connect' }}
</Button>

<router-link
to="/config"
class="inline-flex items-center gap-2 text-sm font-medium transition-colors hover:text-primary"
>
<Settings />
</router-link>
</div>
</div>
</header>

<main class="flex-1 pt-14">
<router-view />
</main>
</div>
</template>
16 changes: 16 additions & 0 deletions frontend/src/components/ui/badge/Badge.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
import { type BadgeVariants, badgeVariants } from '.'
const props = defineProps<{
variant?: BadgeVariants['variant']
class?: HTMLAttributes['class']
}>()
</script>

<template>
<div :class="cn(badgeVariants({ variant }), props.class)">
<slot />
</div>
</template>
25 changes: 25 additions & 0 deletions frontend/src/components/ui/badge/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { cva, type VariantProps } from 'class-variance-authority'

export { default as Badge } from './Badge.vue'

export const badgeVariants = cva(
'inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2',
{
variants: {
variant: {
default:
'border-transparent bg-primary text-primary-foreground hover:bg-primary/80',
secondary:
'border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80',
destructive:
'border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80',
outline: 'text-foreground',
},
},
defaultVariants: {
variant: 'default',
},
},
)

export type BadgeVariants = VariantProps<typeof badgeVariants>
26 changes: 26 additions & 0 deletions frontend/src/components/ui/button/Button.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
import { Primitive, type PrimitiveProps } from 'radix-vue'
import { type ButtonVariants, buttonVariants } from '.'
interface Props extends PrimitiveProps {
variant?: ButtonVariants['variant']
size?: ButtonVariants['size']
class?: HTMLAttributes['class']
}
const props = withDefaults(defineProps<Props>(), {
as: 'button',
})
</script>

<template>
<Primitive
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot />
</Primitive>
</template>
35 changes: 35 additions & 0 deletions frontend/src/components/ui/button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { cva, type VariantProps } from 'class-variance-authority'

export { default as Button } from './Button.vue'

export const buttonVariants = cva(
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
{
variants: {
variant: {
default:
'bg-primary text-primary-foreground shadow hover:bg-primary/90',
destructive:
'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90',
outline:
'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground',
secondary:
'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80',
ghost: 'hover:bg-accent hover:text-accent-foreground',
link: 'text-primary underline-offset-4 hover:underline',
},
size: {
default: 'h-9 px-4 py-2',
sm: 'h-8 rounded-md px-3 text-xs',
lg: 'h-10 rounded-md px-8',
icon: 'h-9 w-9',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
)

export type ButtonVariants = VariantProps<typeof buttonVariants>
21 changes: 21 additions & 0 deletions frontend/src/components/ui/card/Card.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<div
:class="
cn(
'rounded-lg border bg-card text-card-foreground shadow-sm',
props.class,
)
"
>
<slot />
</div>
</template>
14 changes: 14 additions & 0 deletions frontend/src/components/ui/card/CardContent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<div :class="cn('p-6 pt-0', props.class)">
<slot />
</div>
</template>
14 changes: 14 additions & 0 deletions frontend/src/components/ui/card/CardDescription.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<p :class="cn('text-sm text-muted-foreground', props.class)">
<slot />
</p>
</template>
14 changes: 14 additions & 0 deletions frontend/src/components/ui/card/CardFooter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<div :class="cn('flex items-center p-6 pt-0', props.class)">
<slot />
</div>
</template>
14 changes: 14 additions & 0 deletions frontend/src/components/ui/card/CardHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<div :class="cn('flex flex-col gap-y-1.5 p-6', props.class)">
<slot />
</div>
</template>
18 changes: 18 additions & 0 deletions frontend/src/components/ui/card/CardTitle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
const props = defineProps<{
class?: HTMLAttributes['class']
}>()
</script>

<template>
<h3
:class="
cn('text-2xl font-semibold leading-none tracking-tight', props.class)
"
>
<slot />
</h3>
</template>
6 changes: 6 additions & 0 deletions frontend/src/components/ui/card/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export { default as Card } from './Card.vue'
export { default as CardContent } from './CardContent.vue'
export { default as CardDescription } from './CardDescription.vue'
export { default as CardFooter } from './CardFooter.vue'
export { default as CardHeader } from './CardHeader.vue'
export { default as CardTitle } from './CardTitle.vue'
24 changes: 24 additions & 0 deletions frontend/src/components/ui/input/Input.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { cn } from '@/lib/utils'
import { useVModel } from '@vueuse/core'
const props = defineProps<{
defaultValue?: string | number
modelValue?: string | number
class?: HTMLAttributes['class']
}>()
const emits = defineEmits<{
(e: 'update:modelValue', payload: string | number): void
}>()
const modelValue = useVModel(props, 'modelValue', emits, {
passive: true,
defaultValue: props.defaultValue,
})
</script>

<template>
<input v-model="modelValue" :class="cn('flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', props.class)">
</template>
1 change: 1 addition & 0 deletions frontend/src/components/ui/input/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Input } from './Input.vue'
Loading

0 comments on commit 8d71a8d

Please sign in to comment.