Skip to content

Commit

Permalink
Merge pull request #16 from /issues/13
Browse files Browse the repository at this point in the history
Issues/13
  • Loading branch information
wilcorrea authored Apr 15, 2024
2 parents c8184e0 + 7033893 commit 0d75b7e
Show file tree
Hide file tree
Showing 113 changed files with 2,087 additions and 897 deletions.
2 changes: 1 addition & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ VITE_BASE_PATH=/quiz
VITE_IN_MEMORY_TIMEOUT=200
VITE_GAME_QUESTION_TIMEOUT=30

VITE_BACKEND_MODE=memory
VITE_DEVELOPMENT_MODE=false

VITE_SUPABASE_URL=https://<project>.supabase.co
VITE_SUPABASE_ANON_KEY=<your-anon-key>
Expand Down
File renamed without changes.
73 changes: 73 additions & 0 deletions config/dependencies.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import 'reflect-metadata'
import { container } from 'tsyringe'

import { Data, Driver, DriverResolver, DriverType } from '../src/Domain/Contracts.ts'

import { AuthService } from '../src/Application/Auth/AuthService.ts'

import HttpAuthRepository from '../src/Infrastructure/Http/HttpAuthRepository.ts'

import InMemoryAuthRepository from '../src/Infrastructure/Memory/InMemoryAuthRepository.ts'
import InMemoryGameRepository from '../src/Infrastructure/Memory/InMemoryGameRepository.ts'
import InMemoryUserConfigRepository from '../src/Infrastructure/Memory/InMemoryUserConfigRepository.ts'

import SupabaseAuthRepository from '../src/Infrastructure/Supabase/SupabaseAuthRepository.ts'
import SupabaseGameRepository from '../src/Infrastructure/Supabase/SupabaseGameRepository.ts'

import { getInheritDriver, getSessionDriver, isDevelopmentMode } from './env.ts'

const binds: DriverResolver = {
[DriverType.json]: {
GameRepository: () => new InMemoryGameRepository(),
},
[DriverType.http]: {
AuthRepository: () => HttpAuthRepository.build(),
GameRepository: () => new InMemoryGameRepository(),
},
[DriverType.memory]: {
AuthRepository: () => new InMemoryAuthRepository(),
GameRepository: () => new InMemoryGameRepository(),
UserConfigRepository: () => new InMemoryUserConfigRepository(),
},
[DriverType.supabase]: {
AuthRepository: (config: Data) => SupabaseAuthRepository.build(config),
GameRepository: (config: Data) => SupabaseGameRepository.build(config),
}
}

const factory = (token: string, driver?: Driver): [string, { useFactory: () => unknown }] => {
const useFactory = () => {
if (!driver) {
driver = getSessionDriver()
}
const bind = binds[driver.type]
const maker = bind[token]
if (!maker) {
throw new Error(
`No factory found for '${token}' in '${driver.type}' driver type. Review your dependencies.ts file`)
}
return maker(driver.config)
}
return [token, { useFactory }]
}

export default function () {
// [begin] structure stuff
container.register('AuthService', { useClass: AuthService })

let authDriver: Driver = getInheritDriver()
if (isDevelopmentMode()) {
authDriver = {
type: DriverType.memory,
config: {}
}
}
container.register(...factory('AuthRepository', authDriver))
container.register(...factory('UserConfigRepository', authDriver))
// [end] structure stuff

// game stuff
container.register(...factory('GameRepository'))

return container
}
8 changes: 8 additions & 0 deletions config/env.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { getInitialSession, sessionStore } from '../view/stores/session.ts'
import { Driver } from '../src/Domain/Contracts.ts'

export const getInheritDriver = (): Driver => getInitialSession().driver

export const getSessionDriver = (): Driver => sessionStore.state.driver

export const isDevelopmentMode = (): boolean => import.meta.env.VITE_DEVELOPMENT_MODE === 'true'
35 changes: 35 additions & 0 deletions config/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import i18n from 'i18next'
import { initReactI18next } from 'react-i18next'

import ptBR from './resources/ptBR/default.ts'

// the translations
// (tip move them in a JSON file and import them,
// or even better, manage them separated from your code: https://react.i18next.com/guides/multiple-translation-files)
export const name = '🎮 Super Quizz'

const resources = {
'ptBR': {
default: ptBR(name)
},
en: {
translation: {
// TODO: add translations to EN
}
}
}

i18n
.use(initReactI18next) // passes i18n down to react-i18next
.init({
resources,
lng: 'ptBR', // language to use, more information here: https://www.i18next.com/overview/configuration-options#languages-namespaces-resources
// you can use the i18n.changeLanguage function to change the language manually: https://www.i18next.com/overview/api#changelanguage
// if you're using a language detector, do not define the lng option

interpolation: {
escapeValue: false // react already safes from xss
}
})

export default i18n
188 changes: 188 additions & 0 deletions config/resources/ptBR/default.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
export default function (name: string) {
return {
layouts: {
public: {
brand: name,
play: 'Jogar',
signIn: 'Entrar',
myAccount: 'Minha Conta',
copyright: '© PHP com Rapadura',
pending: 'Carregando ...',
},
dashboard: {
brand: name,
play: 'Jogar',
signOut: 'Sair',
myAccount: 'Minha Conta',
pending: 'Carregando ...',
navigation: {
index: 'Meus Jogos',
games: 'Meus Jogos',
account: 'Minha Conta',
settings: 'Configurações'
}
}
},
pages: {
home: {
title: name,
description: 'O melhor jogo de perguntas e respostas para jogar com os amigos!\n' +
'Reúna sua galera e divirta-se com moderação! 🍻',
contributing: 'Não se esqueça de contribuir com o projeto no link abaixo! 😉',
callToAction: 'Jogar agora »'
},
auth: {
signIn: {
title: 'Entrar',
error: 'Usuário e/ou senha inválidos',
action: 'Entrar',
fields: {
username: {
label: 'Usuário',
placeholder: 'Informe seu usuário',
description: 'Utilize seu nome de usuário ou email'
},
password: {
label: 'Senha',
placeholder: 'Informe sua senha',
description: 'Utilize sua senha de acesso'
},
otp: {
label: 'Código de Verificação',
placeholder: 'Informe o código de verificação',
description: 'Utilize o código de verificação enviado para seu email'
}
},
}
},
game: {
play: {
pending: 'Carregando Jogo ...',
rejected: 'Não foi possível carregar o jogo',
error: 'Oh snap!',
instructions: {
title: 'O jogo já vai começar!',
selected: 'Jogo Selecionado: ',
description: 'Certifique-se de que todos estão prontos e clique em Começar!\n' +
'Lembrando que este jogo tem um tempo limite de {{timeout}} segundos para responder ' +
'cada pergunta e {{total}} perguntas ao todo',
greetings: 'Boa sorte!',
start: 'Começar'
},
session: {
correct: {
title: 'Certa a resposta! Acerto Mizeravi!',
description: 'Você acertou! Escolha alguém para beber e passe a vez para a pessoa à sua esquerda.'
},
wrong: {
title: 'Você errou! Bebe!',
description: 'Errou feio, errou Rude! Agora tem de beber e passar a vez para a pessoa à sua esquerda.'
},
expired: {
title: 'Acabou o tempo!',
description: 'Você demorou demais para responder! Agora tem de beber e passar a vez para a pessoa à sua esquerda.'
},
unanswered: {
timer: 'Tempo restante: {{time}} segundos',
},
next: 'Próximo',
answer: 'Responder',
}
},
welcome: {
title: 'Escolha um Jogo',
description: 'Depois de selecionar um jogo cada um na mesa deve responder a uma pergunta.\n' +
'Caso acerte, pode escolher uma pessoa para beber, caso erre tem de beber.\n' +
'Ao terminar, passa-se para o jogador da esquerda.',
pending: 'Carregando jogos ...',
rejected: 'Não foi possível carregar os jogos',
error: 'Oh snap!'
},
end: {
title: 'O jogo acabou!',
description: 'Não está bêbado suficiente? Clique em "Começar de novo"!',
waiting: 'Recomeçar em {{timer}} segundos',
restart: 'Começar de novo'
}
},
dashboard: {
soon: 'Em breve!',
settings: {
title: 'Configurações',
description: 'Aqui você pode configurar as fontes de dados e outras preferências dos jogos. Esta ' +
'configuração não afeta a experiência de outros jogadores.',
fields: {
type: {
label: 'Tipo de Driver',
drivers: {
memory: 'Nenhuma configuração adicional é necessária',
json: 'Usa um JSON estático fornecido por uma URL HTTP',
http: 'Utiliza uma API HTTP devidamente compartível com a aplicação',
supabase: 'Realiza a Conexão com o backend do Supabase'
},
details: 'Configuração que define de onde os dados dos jogos serão carregados',
},
config: {
label: 'Configuração',
drivers: {
memory: 'Usa os dados inclusos no aplicativo e os manipula em memória',
json: {
url: {
label: 'URL',
placeholder: 'Informe a URL do JSON que contém os jogos',
details: 'A URL do JSON é o endereço de um arquivo JSON que contém os dados dos jogos ' +
'disponíveis para jogar. Geralmente é um arquivo hospedado em um servidor HTTP'
},
},
http: {
url: {
label: 'URL',
placeholder: 'Informe a URL base do backend HTTP',
details: 'A URL base do backend HTTP é o endereço da API HTTP que contém os dados dos jogos ' +
'disponíveis para jogar. Geralmente é um endereço de um servidor HTTP'
},
authorization: {
label: 'Cabeçalho de autorização',
placeholder: 'Informe o cabeçalho de autorização do backend HTTP',
details: 'O cabeçalho de autorização do backend HTTP é um token de acesso que permite ' +
'consultar os dados protegidos. Geralmente chama-se Authorization e recebe um token JWT'
},
},
supabase: {
url: {
label: 'URL',
placeholder: 'Informe a URL do backend do Supabase',
details: 'A URL do backend do Supabase é o endereço da API HTTP do Supabase, geralmente ' +
'assemelha-se a "https://<project>.supabase.co"'
},
anonKey: {
label: 'Chave Anônima',
placeholder: 'Informe a chave anônima do backend do Supabase',
details: 'A chave anônima do backend do Supabase é um token de acesso que permite ' +
'consultar os dados sem autenticação. Geralmente é um token JWT'
}
}
},
},
language: {
title: 'Idioma',
description: 'Escolha o idioma do jogo'
}
},
save: 'Salvar',
reset: 'Redefinir',
success: 'Configurações salvas com sucesso',
error: 'Não foi possível salvar as configurações',
}
}
},
components: {
game: {
list: {
title: 'Jogos Disponíveis',
empty: 'Não há nenhum jogo disponível no momento'
}
}
}
}
}
File renamed without changes.
Loading

0 comments on commit 0d75b7e

Please sign in to comment.