This commit is contained in:
Douglas Barone 2023-10-17 13:53:40 -04:00
parent 5d11027972
commit d3de6afa50
13 changed files with 123 additions and 139 deletions

View File

@ -3,7 +3,7 @@
"version": "0.0.0", "version": "0.0.0",
"scripts": { "scripts": {
"clean": "rimraf ./dist", "clean": "rimraf ./dist",
"dev:web": "vite", "dev:web": "vite --host",
"dev:server": "tsx --watch ./src/server/index.ts", "dev:server": "tsx --watch ./src/server/index.ts",
"dev": "concurrently --kill-others -n Server,Web -c bgGreen,bgBlue \"npm run dev:server\" \"npm run dev:web\"", "dev": "concurrently --kill-others -n Server,Web -c bgGreen,bgBlue \"npm run dev:server\" \"npm run dev:web\"",
"build:web": "vue-tsc --noEmit && vite build", "build:web": "vue-tsc --noEmit && vite build",

View File

@ -1,7 +0,0 @@
export function hello(name: string) {
if (name === 'test') throw new Error('Test error')
console.log(`Hello ${name}!`)
return { message: `Hello ${name}!` }
}

4
src/server/lib/login.ts Normal file
View File

@ -0,0 +1,4 @@
export function login(username: string, password: string) {
console.log('Login', username, password)
return 'ok'
}

View File

@ -2,11 +2,11 @@ import { initTRPC, inferAsyncReturnType } from '@trpc/server'
import * as trpcExpress from '@trpc/server/adapters/express' import * as trpcExpress from '@trpc/server/adapters/express'
import { z } from 'zod' import { z } from 'zod'
import { hello } from './lib/hello' import { login } from './lib/login'
// Created for each request // Created for each request
function createContext({ req, res }: trpcExpress.CreateExpressContextOptions) { function createContext({ req, res }: trpcExpress.CreateExpressContextOptions) {
return { ip: req.ip } return { ip: req.ip, hostname: req.hostname }
} }
type Context = inferAsyncReturnType<typeof createContext> type Context = inferAsyncReturnType<typeof createContext>
@ -14,14 +14,17 @@ type Context = inferAsyncReturnType<typeof createContext>
export const t = initTRPC.context<Context>().create() export const t = initTRPC.context<Context>().create()
export const appRouter = t.router({ export const appRouter = t.router({
hello: t.procedure.input(z.string()).query(({ input }) => {
return hello(input)
}),
myIp: t.procedure.query(({ ctx }) => { myIp: t.procedure.query(({ ctx }) => {
const ip = ctx.ip.split(':').slice(-1)[0] const ip = ctx.ip.split(':').slice(-1)[0]
return ip console.log(`IP: ${ip}, Hostname: ${ctx.hostname}`)
})
return { ip, hostname: ctx.hostname }
}),
login: t.procedure
.input(z.object({ username: z.string(), password: z.string() }))
.mutation(async ({ input }) => {
return login(input.username, input.password)
})
}) })
// export type definition of API // export type definition of API

View File

@ -1,29 +1,7 @@
<template> <template>
<v-app> <v-app>
<v-main> <v-main> <router-view /></v-main>
{{ message }}
<v-btn @click="fetchHello('Doug')">Doug</v-btn>
<v-btn @click="fetchHello('test')">test</v-btn>
</v-main>
</v-app> </v-app>
</template> </template>
<script setup lang="ts"> <script setup lang="ts"></script>
import { ref } from 'vue'
import { trpc } from './trpc'
import { TRPCClientError } from '@trpc/client'
const message = ref('Hello World!')
async function fetchHello(name: string) {
try {
message.value = (await trpc.hello.query(name)).message
} catch (error: any) {
if (error instanceof TRPCClientError) {
console.dir(error)
message.value = error.message
}
}
}
</script>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -1,6 +0,0 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M261.126 140.65L164.624 307.732L256.001 466L377.028 256.5L498.001 47H315.192L261.126 140.65Z" fill="#1697F6"/>
<path d="M135.027 256.5L141.365 267.518L231.64 111.178L268.731 47H256H14L135.027 256.5Z" fill="#AEDDFF"/>
<path d="M315.191 47C360.935 197.446 256 466 256 466L164.624 307.732L315.191 47Z" fill="#1867C0"/>
<path d="M268.731 47C76.0026 47 141.366 267.518 141.366 267.518L268.731 47Z" fill="#7BC6FF"/>
</svg>

Before

Width:  |  Height:  |  Size: 526 B

View File

@ -1,75 +0,0 @@
<template>
<v-container class="fill-height">
<v-responsive class="align-center text-center fill-height">
<v-img height="300" src="@/assets/logo.svg" />
<div class="text-body-2 font-weight-light mb-n1">Welcome to</div>
<h1 class="text-h2 font-weight-bold">Vuetify</h1>
<div class="py-14" />
<v-row class="d-flex align-center justify-center">
<v-col cols="auto">
<v-btn
href="https://vuetifyjs.com/components/all/"
min-width="164"
rel="noopener noreferrer"
target="_blank"
variant="text"
>
<v-icon
icon="mdi-view-dashboard"
size="large"
start
/>
Components
</v-btn>
</v-col>
<v-col cols="auto">
<v-btn
color="primary"
href="https://vuetifyjs.com/introduction/why-vuetify/#feature-guides"
min-width="228"
rel="noopener noreferrer"
size="x-large"
target="_blank"
variant="flat"
>
<v-icon
icon="mdi-speedometer"
size="large"
start
/>
Get Started
</v-btn>
</v-col>
<v-col cols="auto">
<v-btn
href="https://community.vuetifyjs.com/"
min-width="164"
rel="noopener noreferrer"
target="_blank"
variant="text"
>
<v-icon
icon="mdi-account-group"
size="large"
start
/>
Community
</v-btn>
</v-col>
</v-row>
</v-responsive>
</v-container>
</template>
<script setup lang="ts">
//
</script>

View File

@ -0,0 +1,76 @@
<template>
<v-form @submit.prevent="doLogin">
<v-card class="pa-5" title="Fazer login na rede">
<v-card-text class="mt-3">
<v-text-field
class="mb-3"
v-model="username"
label="Usuário"
:variant="'outlined'"
autocomplete="username"
hint="SIAPE ou CPF"
prepend-icon="mdi-account"
required
/>
<v-text-field
v-model="password"
label="Senha"
:type="showPassword ? 'text' : 'password'"
hint="Sua senha"
:variant="'outlined'"
autocomplete="current-password"
prepend-icon="mdi-key"
:append-inner-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
@click:append-inner="showPassword = !showPassword"
required
/>
<v-switch
v-model="autoLogin"
color="primary"
label="Logar automaticamente neste dispositivo"
/>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn size="x-large" color="primary" :variant="'flat'" type="submit">
Login
</v-btn>
</v-card-actions>
</v-card>
<v-alert class="mt-3 text-center" color="info">
Seu endereço IP:
<code>
{{ ipAddress }}
</code>
</v-alert>
</v-form>
</template>
<script lang="ts" setup>
import { ref, onMounted } from 'vue'
import { trpc } from '../trpc'
import { hostname } from 'os'
const username = ref('')
const password = ref('')
const autoLogin = ref(false)
const showPassword = ref(false)
const ipAddress = ref('')
const loadingIpAddress = ref(false)
onMounted(async () => {
loadingIpAddress.value = true
const { ip, hostname } = await trpc.myIp.query()
ipAddress.value = ip == '127.0.0.1' ? hostname : ip
loadingIpAddress.value = false
})
function doLogin() {
trpc.login.mutate({ username: username.value, password: password.value })
}
</script>

View File

@ -13,14 +13,22 @@ import { createVuetify } from 'vuetify'
// https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides // https://vuetifyjs.com/en/introduction/why-vuetify/#feature-guides
export default createVuetify({ export default createVuetify({
defaults: {
VCard: {
elevation: 20
}
// VBtn: {
// color: 'primary'
// }
},
theme: { theme: {
themes: { themes: {
light: { light: {
colors: { colors: {
primary: '#1867C0', primary: '#1867C0',
secondary: '#5CBBF6', secondary: '#5CBBF6'
}, }
}, }
}, }
}, }
}) })

View File

@ -8,19 +8,20 @@ const routes = [
children: [ children: [
{ {
path: '', path: '',
name: 'Home', name: 'Login',
// route level code-splitting // route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route // this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited. // which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "home" */ '@/views/Home.vue'), component: () =>
}, import(/* webpackChunkName: "home" */ '@/views/Login.vue')
], }
}, ]
}
] ]
const router = createRouter({ const router = createRouter({
history: createWebHistory(process.env.BASE_URL), history: createWebHistory(process.env.BASE_URL),
routes, routes
}) })
export default router export default router

View File

@ -1,7 +0,0 @@
<template>
<HelloWorld />
</template>
<script lang="ts" setup>
import HelloWorld from '@/components/HelloWorld.vue'
</script>

9
src/web/views/Login.vue Normal file
View File

@ -0,0 +1,9 @@
<template>
<v-container class="align-center justify-center fill-height">
<login-form />
</v-container>
</template>
<script lang="ts" setup>
import LoginForm from '../components/LoginForm.vue'
</script>