Modrinth/components/ui/ModalCreation.vue
Geometrically 740357d120
Migrate to Nuxt 3 (#933)
* Migrate to Nuxt 3

* Update vercel config

* remove tsconfig comment

* Changelog experiment + working proj pages

* Fix package json

* Prevent vercel complaining

* fix deploy (hopefully)

* Tag generator

* Switch to yarn

* Vercel pls 🙏

* Fix tag generation bug

* Make (most) non-logged in pages work

* fix base build

* Linting + state

* Eradicate axios, make most user pages work

* Fix checkbox state being set incorrectly

* Make most things work

* Final stretch

* Finish (most) things

* Move to update model value

* Fix modal text getting blurred from transforms (#964)

* Adjust nav-link border radius when focused (#961)

* Transition between animation states on TextLogo (#955)

* Transition between animation states on TextLogo

* Remove unused refs

* Fixes from review

* Disable tabbing to pagination arrows when disabled (#972)

* Make position of the "no results" text on grid/gallery views consistent (fixes #963) (#965)

* Fix position of the "no results" text on grid view

* fix padding

* Remove extra margin on main page, fixes #957 (#959)

* Fix layout shift and placeholder line height (#973)

* Fix a lot of issues

* Fix more nuxt 3 issues

* fix not all versions showing up (temp)

* inline inter css file

* More nuxt 3 fixes

* [skip ci] broken- backup changes

* Change modpack warnings to blue instead of red (#991)

* Fix some hydration issues

* Update nuxt

* Fix some images not showing

* Add pagination to versions page + fix lag

* Make changelog page consistent with versions page

* sync before merge

* Delete old file

* Fix actions failing

* update branch

* Fixes navbar transition animation. (#1012)

* Fixes navbar transition animation.

* Fixes Y-axis animation. Fixes mobile menu. Removes highlightjs prop.

* Changes xss call to renderString.

* Fixes renderString call.

* Removes unnecessary styling.

* Reverts mobile nav change.

* Nuxt 3 Lazy Loading Search (#1022)

* Uses lazyFetch for results. onSearchChange refreshes. Adds loading circle.

* Removes console.log

* Preserves old page when paging.

* Diagnosing filtering bugs.

* Fix single facet filtering

* Implements useAuth in settings/account.

* tiny ssr fix

* Updating nuxt.config checklist.

* Implements useAuth in revenue, moneitzation, and dashboard index pages.

* Fixes setups.

* Eliminates results when path changes. Adds animated logo.

* Ensures loading animation renders on search page.

---------

Co-authored-by: Jai A <jaiagr+gpg@pm.me>

* Fix navigation issues

* Square button fix (#1023)

* Removes checklist from nuxt.config.

* Modifies Nuxt CI to build after linting.

* Fixes prettierignore file.

* bug fixes

* Update whitelist domains

* Page improvements, fix CLS

* Fix a lot of things

* Fix project type redirect

* Fix 404 errors

* Fix user settings + hydration error

* Final fixes

* fix(creator-section): border radius on icons not aligning with bg (#1027)

Co-authored-by: MagnusHJensen <magnus.holm.jensen@lego.dk>

* Improvements to the mobile navbar (#984)

* Transition between animation states on TextLogo

* Remove unused refs

* Fixes from review

* Improvements to the mobile nav menu

* fix avatar alt text

* Nevermind, got confused for a moment

* Tab bar, menu layout improvements

* Highlight search icon when menu is open

* Update layouts/default.vue

Co-authored-by: Magnus Jensen <magnushjensen.mail@gmail.com>

* Fix some issues

* Use caret instead

* Run prettier

* Add create a project

---------

Co-authored-by: Magnus Jensen <magnushjensen.mail@gmail.com>
Co-authored-by: Geometrically <18202329+Geometrically@users.noreply.github.com>
Co-authored-by: Jai A <jaiagr+gpg@pm.me>

* Fix mobile menu issues

* More issues

* Fix lint

---------

Co-authored-by: Kaeden Murphy <kmurphy@kaedenmurphy.dev>
Co-authored-by: triphora <emmaffle@modrinth.com>
Co-authored-by: Zach Baird <30800863+ZachBaird@users.noreply.github.com>
Co-authored-by: stairman06 <36215135+stairman06@users.noreply.github.com>
Co-authored-by: Zachary Baird <zdb1994@yahoo.com>
Co-authored-by: Magnus Jensen <magnushjensen.mail@gmail.com>
Co-authored-by: MagnusHJensen <magnus.holm.jensen@lego.dk>
2023-03-09 10:05:32 -07:00

245 lines
5.8 KiB
Vue

<template>
<Modal ref="modal" header="Create a project">
<div class="modal-creation universal-labels">
<div class="markdown-body">
<p>New projects are created as drafts and can be found under your profile page.</p>
</div>
<label for="project-type">
<span class="label__title">Project type<span class="required">*</span></span>
</label>
<Chips
id="project-type"
v-model="projectType"
:items="$tag.projectTypes.map((x) => x.display)"
/>
<label for="name">
<span class="label__title">Name<span class="required">*</span></span>
</label>
<input
id="name"
v-model="name"
type="text"
maxlength="64"
placeholder="Enter project name..."
autocomplete="off"
@input="updatedName()"
/>
<label for="slug">
<span class="label__title">URL<span class="required">*</span></span>
</label>
<div class="text-input-wrapper">
<div class="text-input-wrapper__before">
https://modrinth.com/{{ getProjectType() ? getProjectType().id : '???' }}/
</div>
<input
id="slug"
v-model="slug"
type="text"
maxlength="64"
autocomplete="off"
@input="manualSlug = true"
/>
</div>
<label for="additional-information">
<span class="label__title">Summary<span class="required">*</span></span>
<span class="label__description"
>This appears in search and on the sidebar of your project's page.</span
>
</label>
<div class="textarea-wrapper">
<textarea id="additional-information" v-model="description" maxlength="256" />
</div>
<div class="push-right input-group">
<button class="iconified-button" @click="cancel">
<CrossIcon />
Cancel
</button>
<button class="iconified-button brand-button" @click="createProject">
<CheckIcon />
Continue
</button>
</div>
</div>
</Modal>
</template>
<script>
import CrossIcon from '~/assets/images/utils/x.svg'
import CheckIcon from '~/assets/images/utils/right-arrow.svg'
import Modal from '~/components/ui/Modal'
import Chips from '~/components/ui/Chips'
export default {
components: {
Chips,
CrossIcon,
CheckIcon,
Modal,
},
props: {
itemType: {
type: String,
default: '',
},
itemId: {
type: String,
default: '',
},
},
data() {
return {
projectType: this.$tag.projectTypes[0].display,
name: '',
slug: '',
description: '',
manualSlug: false,
}
},
methods: {
cancel() {
this.$refs.modal.hide()
},
getProjectType() {
return this.$tag.projectTypes.find((x) => this.projectType === x.display)
},
getClientSide() {
switch (this.getProjectType().id) {
case 'plugin':
return 'unsupported'
case 'resourcepack':
return 'required'
case 'shader':
return 'required'
case 'datapack':
return 'optional'
default:
return 'unknown'
}
},
getServerSide() {
switch (this.getProjectType().id) {
case 'plugin':
return 'required'
case 'resourcepack':
return 'unsupported'
case 'shader':
return 'unsupported'
case 'datapack':
return 'required'
default:
return 'unknown'
}
},
async createProject() {
startLoading()
const projectType = this.getProjectType()
const formData = new FormData()
formData.append(
'data',
JSON.stringify({
title: this.name.trim(),
project_type: projectType.actual,
slug: this.slug,
description: this.description.trim(),
body: '',
initial_versions: [],
team_members: [
{
user_id: this.$auth.user.id,
name: this.$auth.user.username,
role: 'Owner',
},
],
categories: [],
client_side: this.getClientSide(),
server_side: this.getServerSide(),
license_id: 'LicenseRef-Unknown',
is_draft: true,
})
)
try {
await useBaseFetch('project', {
method: 'POST',
body: formData,
headers: {
'Content-Disposition': formData,
Authorization: this.$auth.token,
},
})
this.$refs.modal.hide()
await this.$router.push({
name: 'type-id',
params: {
type: projectType.id,
id: this.slug,
},
state: {
overrideProjectType: projectType.id,
},
})
} catch (err) {
this.$notify({
group: 'main',
title: 'An error occurred',
text: err.data.description,
type: 'error',
})
}
stopLoading()
},
show() {
this.projectType = this.$tag.projectTypes[0].display
this.name = ''
this.slug = ''
this.description = ''
this.manualSlug = false
this.$refs.modal.show()
},
updatedName() {
if (!this.manualSlug) {
this.slug = this.name
.trim()
.toLowerCase()
.replaceAll(' ', '-')
.replaceAll(/[^a-zA-Z0-9!@$()`.+,_"-]/g, '')
.replaceAll(/--+/gm, '-')
}
},
},
}
</script>
<style scoped lang="scss">
.modal-creation {
padding: var(--spacing-card-bg);
display: flex;
flex-direction: column;
.markdown-body {
margin-bottom: 0.5rem;
}
input {
width: 20rem;
max-width: 100%;
}
.text-input-wrapper {
width: 100%;
}
textarea {
min-height: 5rem;
}
.input-group {
margin-top: var(--spacing-card-md);
}
}
</style>