mirror of
https://github.com/modrinth/code.git
synced 2026-08-31 12:05:53 +00:00
* add account switcher, migrate context menus to overflow menu system, update version filter controls, only pad instance icons * app account switcher, improve some context menus, theme stuff * prepr * handle reauthentication * fix a couple sign in issues, admin page cleanup, fix org status badges, fix official account badge, open in local keybind, publish plus icons * rename generic menus to ButtonMenu (& types) * fix hydration issue w/ dropdowns + middleware error
221 lines
6.2 KiB
Vue
221 lines
6.2 KiB
Vue
<template>
|
|
<div
|
|
class="universal-card flex w-full max-w-[27rem] flex-col gap-6 border border-solid border-surface-5 !p-6"
|
|
>
|
|
<div class="mx-auto text-center text-2xl font-semibold text-contrast">
|
|
{{ formatMessage(messages.signUpWithTitle) }}
|
|
</div>
|
|
<section class="flex flex-col gap-2.5">
|
|
<ButtonLink
|
|
:href="getAuthUrl('google', redirectTarget)"
|
|
@click="onOAuthProviderClick('google')"
|
|
>
|
|
<GoogleColorIcon />
|
|
<span>{{ formatMessage(messages.continueWithProvider, { provider: 'Google' }) }}</span>
|
|
</ButtonLink>
|
|
<ButtonLink
|
|
:href="getAuthUrl('microsoft', redirectTarget)"
|
|
@click="onOAuthProviderClick('microsoft')"
|
|
>
|
|
<MicrosoftColorIcon />
|
|
<span>{{ formatMessage(messages.continueWithProvider, { provider: 'Microsoft' }) }}</span>
|
|
</ButtonLink>
|
|
<ButtonLink
|
|
:href="getAuthUrl('discord', redirectTarget)"
|
|
@click="onOAuthProviderClick('discord')"
|
|
>
|
|
<DiscordColorIcon />
|
|
<span>{{ formatMessage(messages.continueWithProvider, { provider: 'Discord' }) }}</span>
|
|
</ButtonLink>
|
|
<template v-if="showOtherOptions">
|
|
<ButtonLink
|
|
:href="getAuthUrl('github', redirectTarget)"
|
|
@click="onOAuthProviderClick('github')"
|
|
>
|
|
<GitHubColorIcon />
|
|
<span>{{ formatMessage(messages.continueWithProvider, { provider: 'GitHub' }) }}</span>
|
|
</ButtonLink>
|
|
<ButtonLink
|
|
:href="getAuthUrl('gitlab', redirectTarget)"
|
|
@click="onOAuthProviderClick('gitlab')"
|
|
>
|
|
<GitLabColorIcon />
|
|
<span>{{ formatMessage(messages.continueWithProvider, { provider: 'GitLab' }) }}</span>
|
|
</ButtonLink>
|
|
<ButtonLink
|
|
:href="getAuthUrl('steam', redirectTarget)"
|
|
@click="onOAuthProviderClick('steam')"
|
|
>
|
|
<SteamColorIcon />
|
|
<span>{{ formatMessage(messages.continueWithProvider, { provider: 'Steam' }) }}</span>
|
|
</ButtonLink>
|
|
</template>
|
|
<button
|
|
class="mx-auto -mb-3 bg-transparent pt-1 text-center text-base font-semibold text-secondary transition-all hover:text-primary"
|
|
@click="onToggleOtherOptions()"
|
|
>
|
|
{{
|
|
showOtherOptions
|
|
? formatMessage(messages.showFewerOptions)
|
|
: formatMessage(messages.showOtherOptions)
|
|
}}
|
|
</button>
|
|
</section>
|
|
|
|
<div class="h-px w-full bg-surface-5"></div>
|
|
|
|
<section class="flex flex-col gap-2.5">
|
|
<label for="email" hidden>{{ formatMessage(commonMessages.emailLabel) }}</label>
|
|
<Input
|
|
id="email"
|
|
v-model="emailModel"
|
|
:icon="MailIcon"
|
|
type="email"
|
|
autocomplete="email"
|
|
:placeholder="formatMessage(commonMessages.emailLabel)"
|
|
wrapper-class="w-full"
|
|
/>
|
|
|
|
<label for="password" hidden>{{ formatMessage(commonMessages.passwordLabel) }}</label>
|
|
<Input
|
|
id="password"
|
|
v-model="passwordModel"
|
|
:icon="KeyIcon"
|
|
type="password"
|
|
autocomplete="new-password"
|
|
:placeholder="formatMessage(commonMessages.passwordLabel)"
|
|
wrapper-class="w-full"
|
|
/>
|
|
|
|
<Button
|
|
type="colored"
|
|
color="brand"
|
|
class="!w-full"
|
|
:disabled="!emailModel || !passwordModel"
|
|
@click="onContinueWithEmail()"
|
|
>
|
|
{{ formatMessage(messages.continueWithEmail) }} <RightArrowIcon />
|
|
</Button>
|
|
|
|
<p v-if="!routeQuery.launcher" class="m-0 text-center">
|
|
<IntlFormatted :message-id="messages.legalDisclaimer">
|
|
<template #terms-link="{ children }">
|
|
<NuxtLink to="/legal/terms" class="text-link">
|
|
<component :is="() => children" />
|
|
</NuxtLink>
|
|
</template>
|
|
<template #privacy-policy-link="{ children }">
|
|
<NuxtLink to="/legal/privacy" class="text-link">
|
|
<component :is="() => children" />
|
|
</NuxtLink>
|
|
</template>
|
|
</IntlFormatted>
|
|
</p>
|
|
|
|
<div class="mx-auto flex flex-wrap items-center justify-start gap-2 text-center">
|
|
{{ formatMessage(messages.alreadyHaveAccountLabel) }}
|
|
<NuxtLink
|
|
class="mr-1 text-link"
|
|
:to="{
|
|
path: '/auth/sign-in',
|
|
query: routeQuery,
|
|
}"
|
|
>
|
|
{{ formatMessage(commonMessages.signInButton) }}
|
|
</NuxtLink>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {
|
|
DiscordColorIcon,
|
|
GitHubColorIcon,
|
|
GitLabColorIcon,
|
|
GoogleColorIcon,
|
|
KeyIcon,
|
|
MailIcon,
|
|
MicrosoftColorIcon,
|
|
RightArrowIcon,
|
|
SteamColorIcon,
|
|
} from '@modrinth/assets'
|
|
import {
|
|
Button,
|
|
ButtonLink,
|
|
commonMessages,
|
|
defineMessages,
|
|
Input,
|
|
IntlFormatted,
|
|
useVIntl,
|
|
} from '@modrinth/ui'
|
|
import { useStorage } from '@vueuse/core'
|
|
import type { LocationQuery } from 'vue-router'
|
|
|
|
import { PENDING_SIGN_IN_OAUTH_PROVIDER_STORAGE_KEY } from '@/composables/accounts.ts'
|
|
import { getAuthUrl } from '@/composables/auth.ts'
|
|
|
|
type AuthProvider = 'discord' | 'google' | 'github' | 'gitlab' | 'steam' | 'microsoft'
|
|
|
|
interface Props {
|
|
redirectTarget?: string
|
|
showOtherOptions?: boolean
|
|
routeQuery?: LocationQuery
|
|
onToggleOtherOptions?: () => void
|
|
onContinueWithEmail?: () => void
|
|
}
|
|
|
|
const {
|
|
redirectTarget = '',
|
|
showOtherOptions = false,
|
|
routeQuery = {},
|
|
onToggleOtherOptions = () => {},
|
|
onContinueWithEmail = () => {},
|
|
} = defineProps<Props>()
|
|
|
|
const emailModel = defineModel<string>('email', { default: '' })
|
|
const passwordModel = defineModel<string>('password', { default: '' })
|
|
|
|
const pendingSignInOAuthProvider = useStorage<AuthProvider | null>(
|
|
PENDING_SIGN_IN_OAUTH_PROVIDER_STORAGE_KEY,
|
|
null,
|
|
)
|
|
const onOAuthProviderClick = (provider: AuthProvider) => {
|
|
pendingSignInOAuthProvider.value = provider
|
|
}
|
|
|
|
const { formatMessage } = useVIntl()
|
|
|
|
const messages = defineMessages({
|
|
signUpWithTitle: {
|
|
id: 'auth.sign-up.title.sign-up-with',
|
|
defaultMessage: 'Create an Account',
|
|
},
|
|
continueWithProvider: {
|
|
id: 'auth.continue-with-provider',
|
|
defaultMessage: 'Continue with {provider}',
|
|
},
|
|
legalDisclaimer: {
|
|
id: 'auth.sign-up.legal-dislaimer',
|
|
defaultMessage:
|
|
"By creating an account, you agree to Modrinth's <terms-link>Terms</terms-link> and <privacy-policy-link>Privacy Policy</privacy-policy-link>.",
|
|
},
|
|
alreadyHaveAccountLabel: {
|
|
id: 'auth.sign-up.sign-in-option.title',
|
|
defaultMessage: 'Already have an account?',
|
|
},
|
|
continueWithEmail: {
|
|
id: 'auth.sign-up.continue-with-email',
|
|
defaultMessage: 'Continue with Email',
|
|
},
|
|
showFewerOptions: {
|
|
id: 'auth.sign-up.show-fewer-options',
|
|
defaultMessage: 'Show fewer options',
|
|
},
|
|
showOtherOptions: {
|
|
id: 'auth.sign-up.show-other-options',
|
|
defaultMessage: 'Show other options',
|
|
},
|
|
})
|
|
</script>
|