Skip to content

Commit

Permalink
feat: event: edit list of profiles (#89)
Browse files Browse the repository at this point in the history
* feat: TInputProfile
* event: org, artists and reservation flow
  • Loading branch information
razbakov committed Feb 1, 2022
1 parent 512ff72 commit 44704fa
Show file tree
Hide file tree
Showing 17 changed files with 505 additions and 91 deletions.
3 changes: 2 additions & 1 deletion components/TButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ export default {
'bg-transparent text-primary font-semibold py-2 px-4 border border-primary rounded-full no-underline hover:bg-primary hover:text-white hover:border-transparent',
link: 'underline font-semibold hover:no-underline',
context:
'text-left w-full px-4 py-2 text-gray-800 hover:bg-indigo-500 hover:text-white',
'text-left w-full px-4 py-2 hover:bg-indigo-500 hover:text-white',
'context-active': 'text-left w-full px-4 py-2 bg-indigo-500 text-white',
nav:
'p-2 font-semibold items-center flex rounded-full hover:bg-red-100 hover:text-primary',
void: '',
Expand Down
6 changes: 5 additions & 1 deletion components/TCommentsInline.vue
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,15 @@ export default {
type: Object,
default: () => ({}),
},
autoload: {
type: Boolean,
default: false,
},
},
setup(props) {
const { username } = useAuth()
const newReply = ref('')
const showComments = ref(false)
const showComments = ref(props.autoload)
const { softUpdate } = useDoc('posts')
const { create } = useDoc('comments')
Expand Down
4 changes: 2 additions & 2 deletions components/TDropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<template v-slot:button>
<TButton :icon="icon" :type="type" :label="label" :title="title" />
</template>
<template v-slot:menu>
<template v-slot:menu="{ closeMenu }">
<div class="w-32 py-2 bg-white rounded-lg shadow-xl border">
<slot />
<slot :closeMenu="closeMenu" />
</div>
</template>
</TMenu>
Expand Down
14 changes: 14 additions & 0 deletions components/TDropdownSeparator.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<div class="font-bold p-2 text-xs text-gray-700 border-b">{{ label }}</div>
</template>

<script>
export default {
props: {
label: {
type: String,
default: '',
},
},
}
</script>
51 changes: 51 additions & 0 deletions components/TInput/TInputArray.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div>
<component
v-for="(item, index) in value"
:key="`${children.component}-${index}`"
:is="children.component"
v-model="internalValue[index]"
v-bind="children"
/>
<component
:is="children.component"
v-model="internalValue[value.length]"
v-bind="children"
/>
</div>
</template>

<script>
export default {
data: () => ({
internalValue: [],
}),
props: {
value: {
type: [Array, String],
default: () => [],
},
children: {
type: Object,
default: () => ({}),
},
},
watch: {
internalValue: {
deep: true,
handler(val) {
let filtered = []
if (val) {
filtered = val.filter((item) => item && item !== '' && item !== null)
}
this.$emit('input', filtered)
},
},
},
mounted() {
this.internalValue = this.value || []
},
}
</script>
186 changes: 186 additions & 0 deletions components/TInput/TInputProfile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<template>
<div>
<WProfile
v-if="value && value.username"
:username="value.username"
:fallback="value"
>
<template v-slot:right>
<TDropdown v-slot="{ closeMenu }">
<TDropdownSeparator :label="$t('TInputProfile.changeRole')" />
<TButton
v-for="role in eventRoleOptions"
:key="role.value"
allow-guests
:type="value.role === role.value ? 'context-active' : 'context'"
:label="role.label"
class="text-sm"
@click="
value.role = role.value
closeMenu()
"
/>
<TDropdownSeparator :label="$t('TInputProfile.actions')" />
<TButton
allow-guests
type="context"
:label="$t('TInputProfile.remove')"
color="red-500 text-sm"
@click="
$emit('input', null)
closeMenu()
"
/>
</TDropdown>
</template>
<div></div>
</WProfile>
<TInput
v-else
v-model="query"
:placeholder="placeholder"
@input="search"
autocomplete="off"
/>
<div v-if="query" class="divide-y border rounded shadow absolute bg-white">
<div
v-for="item in suggestions"
:key="item.id"
class="flex px-4 py-2 hover:bg-blue-100 items-center cursor-pointer space-x-1"
@click="add(item)"
>
<TProfilePhoto2 size="sm" :src="item.photo" />
<div class="flex-grow">
<div class="block text-sm">{{ item.username }}</div>
</div>
</div>
<template v-if="isUsernameAvailable">
<div
class="flex px-4 py-2 hover:bg-blue-100 items-center cursor-pointer space-x-1"
@click="create({ username: query, instagram: query })"
>
<div class="p-1">
<TIcon name="instagram" size="4" class="text-gray-700 " />
</div>
<div class="text-sm">
{{ query }} {{ $t('TInputProfile.addInstagram') }}
</div>
</div>
<div
class="flex px-4 py-2 hover:bg-blue-100 items-center cursor-pointer space-x-1"
@click="create({ username: query, facebook: query })"
>
<div class="p-1">
<TIcon name="facebook" size="4" class="text-gray-700 " />
</div>
<div class="text-sm">
{{ query }} {{ $t('TInputProfile.addFacebook') }}
</div>
</div>
</template>
</div>
</div>
</template>
<script>
import { computed, ref } from '@nuxtjs/composition-api'
import { useAlgolia } from '~/use/algolia'
import { useEvents } from '~/use/events'
import { useDoc } from '~/use/doc'
export default {
name: 'TInputProfile',
inheritAttrs: false,
props: {
value: {
type: [Object, String],
default: () => ({}),
},
placeholder: {
type: String,
default() {
return this.$t('TInputProfile.placeholder')
},
},
excludeUsernames: {
type: Array,
default: () => [],
},
},
setup(props, { emit }) {
const { search, response } = useAlgolia('profiles')
const query = ref('')
const selected = ref(props.value)
const { eventRoleOptions } = useEvents()
const { create: createProfile } = useDoc('profiles')
if (typeof props.value === 'string') {
emit('input', { username: props.value })
}
const add = (data) => {
query.value = ''
emit('input', data)
}
const suggestions = computed(() => {
const { hits } = response.value
return hits
?.filter(
(p) =>
!props.excludeUsernames.some((username) => username === p.username)
)
.map((p) => {
return {
id: p.id,
username: p.username,
name: p.name || p.username || '',
photo: p.photo || '',
bio: p.bio || '',
instagram: p.instagram || '',
facebook: p.facebook || '',
tiktok: p.tiktok || '',
youtube: p.youtube || '',
}
})
})
const isUsernameAvailable = computed(() => {
let result = true
if (
suggestions.value &&
suggestions.value.some((p) => p.username === query.value)
) {
result = false
}
if (props.excludeUsernames.some((username) => username === query.value)) {
result = false
}
return result
})
const create = async (data) => {
await createProfile({
type: 'FanPage',
...data,
})
add(data)
}
return {
query,
selected,
suggestions,
add,
search,
eventRoleOptions,
create,
isUsernameAvailable,
}
},
}
</script>
6 changes: 5 additions & 1 deletion components/TItemCreator.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
:content="creator.story"
class="mt-4"
/>
<TProfileContacts v-if="full" :profile="creator" class="mt-4 p-2" />
<TProfileContacts
v-if="full"
:profile="creator"
class="mt-4 p-2 bg-gray-100"
/>
</div>
</template>

Expand Down
2 changes: 1 addition & 1 deletion components/TProfile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@
</div>
</template>

<TProfileContacts :profile="profile" class="p-2 mb-4" />
<TProfileContacts :profile="profile" class="p-2 mb-4 bg-gray-100" />

<div v-if="uid === profile.id" class="flex justify-center space-x-2">
<TButton label="Edit Profile" to="/settings?tab=profile" />
Expand Down
20 changes: 11 additions & 9 deletions components/TProfileContacts.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
<template>
<div
class="md:flex items-center justify-center space-x-2 space-y-2 bg-gray-100"
>
<div class="md:flex items-center justify-center space-x-2 space-y-2">
<div v-if="title" class="pl-2 font-bold">{{ title }}</div>
<div class="p-4 flex flex-wrap gap-2 items-center justify-center">
<TButton
v-if="profile.website"
v-if="!short && profile.website"
:href="profile.website"
icon="house"
type="round"
icon-size="6"
/>
<TButton
v-if="profile.whatsapp"
v-if="!short && profile.whatsapp"
icon="whatsapp"
type="round"
icon-size="6"
:href="`https://chat.whatsapp.com/${profile.whatsapp}`"
/>
<TButton
v-if="profile.telegram"
v-if="!short && profile.telegram"
icon="telegram"
type="round"
icon-size="6"
Expand All @@ -33,21 +31,21 @@
:href="`https://instagram.com/${profile.instagram}`"
/>
<TButton
v-if="profile.tiktok"
v-if="!short && profile.tiktok"
icon="tiktok"
type="round"
icon-size="6"
:href="`https://tiktok.com/${profile.tiktok}`"
/>
<TButton
v-if="profile.youtube"
v-if="!short && profile.youtube"
icon="youtube"
type="round"
icon-size="6"
:href="`https://youtube.com/${profile.youtube}`"
/>
<TButton
v-if="profile.twitter"
v-if="!short && profile.twitter"
icon="twitter"
type="round"
icon-size="6"
Expand Down Expand Up @@ -75,6 +73,10 @@ export default {
type: Object,
default: () => ({}),
},
short: {
type: Boolean,
default: false,
},
},
}
</script>
Loading

0 comments on commit 44704fa

Please sign in to comment.