Skip to content

Commit

Permalink
Feat/import and user settings (#260)
Browse files Browse the repository at this point in the history
* feat: pretty solid init

* feat: import, guide + delete of user

* fix: removed unused importer service

* feat: dockerfile

* fix: docker file improvement

* fix: missing env

* fix: added redirect

* fix: ofc i forgot a t

* fix: PR comments

* feat: 18n

* feat: make sure wishes have rarity too

* fix: installed

* fix: removal of microsoft in simple icons

* fix: microsoft removal here too

* fix: lint + quality gate

* fix: docker file creating sonnar issues
  • Loading branch information
LudovicMalot authored Jul 20, 2024
1 parent 348e12a commit 5d984c8
Show file tree
Hide file tree
Showing 48 changed files with 891 additions and 940 deletions.
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
node_modules
npm-debug.log
yarn-error.log
.git
.gitignore
.dockerignore
Dockerfile
*.md
.vscode
.idea
.env
.env.*
build
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ node_modules
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.idea
.vscode
/.npm-only-allow
3 changes: 2 additions & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ node_modules/
.env
.env.*
!.env.example

**/*.lockb
**/*ignore
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
Expand Down
4 changes: 4 additions & 0 deletions .sonarlint/connectedMode.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"sonarCloudOrganization": "dval-in",
"projectKey": "dval-in_dvalin-frontend"
}
29 changes: 29 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# sonarqube analysis should ignore this file
# sonarqube.analysis.skip=true
FROM node:20-alpine

# Install pnpm
RUN npm install -g pnpm

WORKDIR /app

COPY . .

# Install dependencies
RUN pnpm install --frozen-lockfile

# Copy the rest of the application code
COPY . .


ARG VITE_BACKEND_URL
ENV VITE_BACKEND_URL=$VITE_BACKEND_URL

# Build the application
RUN pnpm run build

# Expose the port the app runs on
EXPOSE 8080

# Command to run the application
CMD ["pnpm", "run", "preview"]
Binary file added bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"layerchart": "^0.43.7",
"lucide-svelte": "^0.408.0",
"mode-watcher": "^0.4.0",
"simple-icons": "^13.1.0",
"socket.io": "^4.7.5",
"socket.io-client": "^4.7.5",
"svelte-i18next": "^2.2.2",
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

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

4 changes: 3 additions & 1 deletion src/lib/components/navigator/Sidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,9 @@
icon={mdiLogout}
{isSidebarOpen}
link=""
on:click={() => backend.auth.logout()}
on:click={() => {
backend.auth.logout();
}}
title={$i18n.t('navigation.logout')}
/>
{:else}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,11 @@
import { AlertDescription, AlertTitle } from '$lib/components/ui/alert/index.js';
import Icon from '$lib/components/ui/icon/icon.svelte';
import { mdiTranslate } from '@mdi/js';
import BackendService from '$lib/services/backend';
let selectedLanguage = get(i18n).language;
const backend = BackendService.getInstance();
$: createConfigMutation = backend.user.updateConfig();
let isDialogOpen = false;
const languages = Object.keys(get(i18n).options.resources ?? {});
Expand Down Expand Up @@ -68,6 +70,9 @@
const saveLanguage = () => {
$i18n.changeLanguage(selectedLanguage);
isDialogOpen = false;
$createConfigMutation.mutate({
config: { preferedLanguage: selectedLanguage.toLowerCase() }
});
};
const openDialog = () => {
Expand Down
File renamed without changes.
10 changes: 5 additions & 5 deletions src/lib/components/ui/card/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import Root from './card.svelte';
import Content from './card-content.svelte';
import Description from './card-description.svelte';
import Footer from './card-footer.svelte';
import Header from './card-header.svelte';
import Title from './card-title.svelte';
import Content from './CardContent.svelte';
import Description from './CardDescription.svelte';
import Footer from './CardFooter.svelte';
import Header from './CardHeader.svelte';
import Title from './CardTitle.svelte';

export {
Root,
Expand Down
3 changes: 2 additions & 1 deletion src/lib/components/ui/icon-button/IconButton.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
<script lang="ts">
import Icon from '$lib/components/ui/icon/icon.svelte';
import { Button } from '$lib/components/ui/button/index.js';
import type { SimpleIcon } from 'simple-icons';
export let icon: string = '';
export let icon: SimpleIcon | string;
export let contentClass = '';
</script>
Expand Down
137 changes: 137 additions & 0 deletions src/lib/components/user/NewAccountForm.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<script lang="ts">
import { Button } from '$lib/components/ui/button';
import { Input } from '$lib/components/ui/input';
import { Label } from '$lib/components/ui/label';
import { AlertCircle } from 'lucide-svelte';
import { Alert, AlertDescription, AlertTitle } from '$lib/components/ui/alert';
import { Checkbox } from '$lib/components/ui/checkbox';
import H3 from '$lib/components/typography/H3.svelte';
import langFlagDE from '$lib/assets/languages/DE.svg';
import langFlagEN from '$lib/assets/languages/EN.svg';
import langFlagES from '$lib/assets/languages/ES.svg';
import langFlagFR from '$lib/assets/languages/FR.svg';
import langFlagIT from '$lib/assets/languages/IT.svg';
import langFlagPT from '$lib/assets/languages/PT.svg';
import langFlagPL from '$lib/assets/languages/PL.svg';
import langFlagRU from '$lib/assets/languages/RU.svg';
import langFlagTH from '$lib/assets/languages/TH.svg';
import langFlagZHS from '$lib/assets/languages/ZHS.svg';
import langFlagZHT from '$lib/assets/languages/ZHT.svg';
// Props
export let onSubmit: (data: { user: UserData; config: ConfigData }) => void;
const languages = [
{ code: 'en', name: 'English', flag: langFlagEN },
{ code: 'de', name: 'Deutsch', flag: langFlagDE },
{ code: 'es', name: 'Español', flag: langFlagES },
{ code: 'fr', name: 'Français', flag: langFlagFR },
{ code: 'it', name: 'Italiano', flag: langFlagIT },
{ code: 'pt', name: 'Português', flag: langFlagPT },
{ code: 'pl', name: 'Polski', flag: langFlagPL },
{ code: 'ru', name: 'Русский', flag: langFlagRU },
{ code: 'th', name: 'ไทย', flag: langFlagTH },
{ code: 'zh-CN', name: '简体中文', flag: langFlagZHS },
{ code: 'zh-TW', name: '繁體中文', flag: langFlagZHT }
];
interface UserData {
uid: number;
}
interface ConfigData {
autoRefine3: boolean;
autoRefine4: boolean;
autoRefine5: boolean;
preferedLanguage: string;
}
let user: UserData = {
uid: 1
};
let config: ConfigData = {
autoRefine3: false,
autoRefine4: false,
autoRefine5: false,
preferedLanguage: 'en'
};
let errors: Partial<{ uid: string }> = {};
function validateForm(): boolean {
errors = {};
if (!user.uid || user.uid < 100000000 || user.uid > 999999999) {
errors.uid = 'UID must be a 9-digit number';
}
return Object.keys(errors).length === 0;
}
function handleSubmit() {
if (!validateForm()) {
return;
}
onSubmit({ user, config });
}
</script>

<form on:submit|preventDefault={handleSubmit} class="space-y-4 col-span-2 p-5">
{#if Object.keys(errors).length > 0}
<Alert variant="destructive" class="mt-4">
<AlertCircle class="h-4 w-4" />
<AlertTitle>Error</AlertTitle>
<AlertDescription>
Please correct the errors in the form before submitting.
</AlertDescription>
</Alert>
{/if}
<div>
<Label for="uid">UID</Label>
<Input type="number" id="uid" bind:value={user.uid} />
{#if errors.uid}
<p class="text-red-500 text-sm mt-1">{errors.uid}</p>
{/if}
</div>
<H3>Add configuration information (optional)</H3>
<div>
<Label>Auto Refine Settings</Label>
<div class="space-y-2">
<div class="flex items-center space-x-2">
<Checkbox bind:checked={config.autoRefine3} id="autoRefine3" />
<label for="autoRefine3">Auto Refine 3-star weapons</label>
</div>
<div class="flex items-center space-x-2">
<Checkbox bind:checked={config.autoRefine4} id="autoRefine4" />
<label for="autoRefine4">Auto Refine 4-star weapons</label>
</div>
<div class="flex items-center space-x-2">
<Checkbox bind:checked={config.autoRefine5} id="autoRefine5" />
<label for="autoRefine5">Auto Refine 5-star weapons</label>
</div>
</div>
</div>

<div>
<Label for="language">Preferred Language</Label>
<div class="grid grid-cols-2 gap-2 mt-2">
{#each languages as lang}
<Button
type="button"
variant={config.preferedLanguage === lang.code ? 'default' : 'outline'}
class="flex items-center justify-start space-x-2"
on:click={() => (config.preferedLanguage = lang.code)}
>
<img src={lang.flag} alt={lang.name} class="w-6 h-4" />
<span>{lang.name}</span>
</Button>
{/each}
</div>
</div>

<div class="flex space-x-4">
<Button type="submit" class="flex-1 bg-primary text-primary-foreground">
Complete Profile
</Button>
</div>
</form>
27 changes: 27 additions & 0 deletions src/lib/locales/EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,28 @@
"characters.detailed.category.builds.artifacts.main_stats.title": "Main Stats",
"characters.detailed.category.builds.artifacts.sub_stats.title": "Sub stats",
"characters.detailed.category.builds.talents.title": "Talents",
"welcome.title": "Welcome, Traveler!",
"profile.complete.title": "Complete Your Profile to Unlock Full Features",
"profile.complete.description": "By completing your profile, you'll gain access to enhanced features and personalized experiences. Once logged in, you'll be able to import data from various sources and export your information securely.",
"profile.create.success": "Profile created successfully!",
"profile.create.error": "Error creating profile: {error}",
"profile.create.pending.title": "Creating Your Profile",
"profile.create.pending.description": "Please wait while we set up your personalized experience...",
"profile.create.error.title": "Profile Creation Error",
"settings.overview.title": "Settings",
"settings.category.theming.title": "Theming",
"settings.category.data.title": "Data",
"settings.category.data.import_data_button": "Import data",
"settings.category.data.export_data_button": "Export data",
"settings.login_providers": "Login providers",
"settings.auto_refine_settings": "Auto Refine Settings",
"settings.auto_refine_3_star": "Auto Refine 3-star weapons",
"settings.auto_refine_4_star": "Auto Refine 4-star weapons",
"settings.auto_refine_5_star": "Auto Refine 5-star weapons",
"settings.save_settings": "Save Settings",
"settings.delete_account": "Delete account",
"settings.delete_account_confirmation": "Are you sure you want to delete your account? This action is irreversible and all data will be lost.",
"settings.delete_account_confirm": "Delete account",
"settings.import.title": "Import account data",
"settings.import.no_file_selected": "No file selected",
"settings.import.warning.title": "Watch out!",
Expand All @@ -76,6 +93,8 @@
"settings.import.confirmation_dialog.title": "Are you sure?",
"settings.import.confirmation_dialog.description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae deserunt velit autem veniam doloribus nulla. Culpa fugiat nemo accusantium cumque soluta tenetur tempora veritatis magnam nulla aliquid. Similique, perspiciatis unde?",
"login.title": "Be able to do more with an account!",
"login.alert.title": "Important: Local Data Notice",
"login.alert.description": "Logging in will overwrite your local data. Please ensure you've backed up any important information before proceeding.",
"login.perk.cross_device_sync.title": "Cross-device synchronization",
"login.perk.cross_device_sync.description": "Lorem ipsum dolor sit amet consectetur adipisicing elit. Vitae deserunt velit autem veniam doloribus nulla. Culpa fugiat nemo accusantium cumque soluta tenetur tempora veritatis magnam nulla aliquid. Similique, perspiciatis unde?",
"login.perk.server_access.title": "Access to server side functions",
Expand All @@ -98,6 +117,14 @@
"server.wish_history.active": "Your wish history is now being processed",
"server.wish_history.success": "Your wish history was successfully imported",
"server.wish_history.error": "Your wish history failed to import",
"action.reset_filters": "Reset Filters",
"filter.element": "Element",
"filter.weapon": "Weapon",
"filter.rarity": "Rarity",
"filter.owned": "Owned",
"sort.name": "Name",
"sort.date": "Date",
"sort.constellation": "Constellation",
"language.DE": "Deutsch",
"language.EN": "English",
"language.ES": "Español",
Expand Down
4 changes: 4 additions & 0 deletions src/lib/services/backend/auth.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { applicationState } from '$lib/store/application_state';
import { userProfile, defaultValues } from '$lib/store/user_profile';

export class BackendAuthService {
private readonly baseUrl: string;
Expand All @@ -16,6 +17,9 @@ export class BackendAuthService {
state.isAuthenticated = false;
return state;
});
userProfile.update(() => {
return defaultValues;
});
window.location.href = `${this.baseUrl}/logout`;
}

Expand Down
6 changes: 3 additions & 3 deletions src/lib/services/backend/hoyo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class BackendHoyoService {
{
mutationFn: (authkey: string) =>
backendFetch<FetchHoyoWishHistoryResponse>(
`${this.baseUrl}/wishhistory?authkey=${authkey}`
`${this.baseUrl}/wish?authkey=${authkey}`
)
},
this.queryClient
Expand All @@ -46,7 +46,7 @@ export class BackendHoyoService {
fetchHoyoWishHistoryStatus() {
return createQuery<BackendStateResponse | FetchHoyoWishHistoryStatusResponse>(
derived(applicationState, (appState) => ({
queryKey: ['fetchHoyoWishhistoryStatus', appState.isAuthenticated],
queryKey: ['fetchHoyoWishStatus', appState.isAuthenticated],
staleTime: 60 * 60 * 1000, //1h
queryFn: async () =>
await backendFetch<FetchHoyoWishHistoryStatusResponse>(
Expand All @@ -59,6 +59,6 @@ export class BackendHoyoService {
}

getHoyoWishHistoryStatusUrl() {
return `${this.baseUrl}/wishhistory/status`;
return `${this.baseUrl}/wish/status`;
}
}
Loading

0 comments on commit 5d984c8

Please sign in to comment.