mirror of
https://github.com/abhinavxd/libredesk.git
synced 2025-10-23 05:11:57 +00:00
Fix: Contact form displays countries with the same calling code incorrectly.
For example, when a user selects the USA, the form also shows Canada, as both share the +1 calling code. Rename column from `phone_number_calling_code` to `phone_number_country_code`. Feat: Show the calling code alongside the country flag in the contact form for the selected country. Previously, only the flag was displayed.
This commit is contained in:
@@ -103,9 +103,9 @@ func handleUpdateContact(r *fastglue.Request) error {
|
||||
if v, ok := form.Value["phone_number"]; ok && len(v) > 0 {
|
||||
phoneNumber = string(v[0])
|
||||
}
|
||||
phoneNumberCallingCode := ""
|
||||
if v, ok := form.Value["phone_number_calling_code"]; ok && len(v) > 0 {
|
||||
phoneNumberCallingCode = string(v[0])
|
||||
phoneNumberCountryCode := ""
|
||||
if v, ok := form.Value["phone_number_country_code"]; ok && len(v) > 0 {
|
||||
phoneNumberCountryCode = string(v[0])
|
||||
}
|
||||
avatarURL := ""
|
||||
if v, ok := form.Value["avatar_url"]; ok && len(v) > 0 {
|
||||
@@ -116,8 +116,8 @@ func handleUpdateContact(r *fastglue.Request) error {
|
||||
if avatarURL == "null" {
|
||||
avatarURL = ""
|
||||
}
|
||||
if phoneNumberCallingCode == "null" {
|
||||
phoneNumberCallingCode = ""
|
||||
if phoneNumberCountryCode == "null" {
|
||||
phoneNumberCountryCode = ""
|
||||
}
|
||||
if phoneNumber == "null" {
|
||||
phoneNumber = ""
|
||||
@@ -146,7 +146,7 @@ func handleUpdateContact(r *fastglue.Request) error {
|
||||
Email: null.StringFrom(email),
|
||||
AvatarURL: null.NewString(avatarURL, avatarURL != ""),
|
||||
PhoneNumber: null.NewString(phoneNumber, phoneNumber != ""),
|
||||
PhoneNumberCallingCode: null.NewString(phoneNumberCallingCode, phoneNumberCallingCode != ""),
|
||||
PhoneNumberCountryCode: null.NewString(phoneNumberCountryCode, phoneNumberCountryCode != ""),
|
||||
}
|
||||
|
||||
if err := app.user.UpdateContact(id, contactToUpdate); err != nil {
|
||||
|
@@ -35,6 +35,7 @@ var migList = []migFunc{
|
||||
{"v0.5.0", migrations.V0_5_0},
|
||||
{"v0.6.0", migrations.V0_6_0},
|
||||
{"v0.7.0", migrations.V0_7_0},
|
||||
{"v0.7.4", migrations.V0_7_4},
|
||||
}
|
||||
|
||||
// upgrade upgrades the database to the current version by running SQL migration files
|
||||
|
@@ -8,7 +8,7 @@
|
||||
:class="['w-full justify-between', buttonClass]"
|
||||
>
|
||||
<slot name="selected" :selected="selectedItem">{{ selectedLabel }}</slot>
|
||||
<CaretSortIcon class="ml-2 h-4 w-4 shrink-0 opacity-50" />
|
||||
<CaretSortIcon class="h-4 w-4 shrink-0 opacity-50" />
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent class="p-0">
|
||||
|
@@ -41,8 +41,8 @@
|
||||
|
||||
<div class="flex flex-col flex-1">
|
||||
<div class="flex items-end">
|
||||
<FormField v-slot="{ componentField }" name="phone_number_calling_code">
|
||||
<FormItem class="w-20">
|
||||
<FormField v-slot="{ componentField }" name="phone_number_country_code">
|
||||
<FormItem class="w-max-content">
|
||||
<FormLabel class="flex items-center whitespace-nowrap">
|
||||
{{ t('globals.terms.phoneNumber') }}
|
||||
</FormLabel>
|
||||
@@ -58,13 +58,18 @@
|
||||
<div class="w-7 h-7 flex items-center justify-center">
|
||||
<span v-if="item.emoji">{{ item.emoji }}</span>
|
||||
</div>
|
||||
<span class="text-sm">{{ item.label }} ({{ item.value }})</span>
|
||||
<span class="text-sm">{{ item.label }} ({{ item.calling_code }})</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #selected="{ selected }">
|
||||
<div class="flex items-center mb-1">
|
||||
<span v-if="selected" class="text-xl leading-none">{{ selected.emoji }}</span>
|
||||
<div class="flex items-center gap-1">
|
||||
<span v-if="selected" class="text-lg">{{ selected.emoji }}</span>
|
||||
<span
|
||||
v-if="selected && selected.calling_code"
|
||||
class="text-xs text-muted-foreground"
|
||||
>({{ selected.calling_code }})</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
</ComboBox>
|
||||
@@ -116,7 +121,8 @@ const userStore = useUserStore()
|
||||
|
||||
const allCountries = countries.map((country) => ({
|
||||
label: country.name,
|
||||
value: country.calling_code,
|
||||
emoji: country.emoji
|
||||
value: country.iso_2,
|
||||
emoji: country.emoji,
|
||||
calling_code: country.calling_code
|
||||
}))
|
||||
</script>
|
||||
|
@@ -29,7 +29,7 @@ export const createFormSchema = (t) => z.object({
|
||||
})
|
||||
})
|
||||
.nullable(),
|
||||
phone_number_calling_code: z.string().optional().nullable(),
|
||||
phone_number_country_code: z.string().optional().nullable(),
|
||||
avatar_url: z.string().optional().nullable(),
|
||||
email: z
|
||||
.string({
|
||||
|
@@ -58,6 +58,7 @@ import { ViewVerticalIcon } from '@radix-icons/vue'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
||||
import { Mail, Phone, ExternalLink } from 'lucide-vue-next'
|
||||
import countries from '@/constants/countries.js'
|
||||
import { useEmitter } from '@/composables/useEmitter'
|
||||
import { EMITTER_EVENTS } from '@/constants/emitterEvents.js'
|
||||
import { useConversationStore } from '@/stores/conversation'
|
||||
@@ -72,8 +73,13 @@ const { t } = useI18n()
|
||||
const userStore = useUserStore()
|
||||
|
||||
const phoneNumber = computed(() => {
|
||||
const callingCode = conversation.value?.contact?.phone_number_calling_code || ''
|
||||
const countryCodeValue = conversation.value?.contact?.phone_number_country_code || ''
|
||||
const number = conversation.value?.contact?.phone_number || t('conversation.sidebar.notAvailable')
|
||||
return callingCode ? `${callingCode} ${number}` : number
|
||||
if (!countryCodeValue) return number
|
||||
|
||||
// Lookup calling code
|
||||
const country = countries.find((c) => c.iso_2 === countryCodeValue)
|
||||
const callingCode = country ? country.calling_code : countryCodeValue
|
||||
return `${callingCode} ${number}`
|
||||
})
|
||||
</script>
|
||||
|
@@ -189,7 +189,7 @@ async function onUpload(file) {
|
||||
formData.append('last_name', form.values.last_name)
|
||||
formData.append('email', form.values.email)
|
||||
formData.append('phone_number', form.values.phone_number)
|
||||
formData.append('phone_number_calling_code', form.values.phone_number_calling_code)
|
||||
formData.append('phone_number_country_code', form.values.phone_number_country_code)
|
||||
formData.append('enabled', form.values.enabled)
|
||||
const { data } = await api.updateContact(contact.value.id, formData)
|
||||
contact.value.avatar_url = data.avatar_url
|
||||
|
@@ -145,7 +145,7 @@ type ConversationContact struct {
|
||||
AvailabilityStatus string `db:"availability_status" json:"availability_status"`
|
||||
AvatarURL null.String `db:"avatar_url" json:"avatar_url"`
|
||||
PhoneNumber null.String `db:"phone_number" json:"phone_number"`
|
||||
PhoneNumberCallingCode null.String `db:"phone_number_calling_code" json:"phone_number_calling_code"`
|
||||
PhoneNumberCountryCode null.String `db:"phone_number_country_code" json:"phone_number_country_code"`
|
||||
CustomAttributes json.RawMessage `db:"custom_attributes" json:"custom_attributes"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
LastActiveAt null.Time `db:"last_active_at" json:"last_active_at"`
|
||||
|
@@ -140,7 +140,7 @@ SELECT
|
||||
ct.availability_status as "contact.availability_status",
|
||||
ct.avatar_url as "contact.avatar_url",
|
||||
ct.phone_number as "contact.phone_number",
|
||||
ct.phone_number_calling_code as "contact.phone_number_calling_code",
|
||||
ct.phone_number_country_code as "contact.phone_number_country_code",
|
||||
ct.custom_attributes as "contact.custom_attributes",
|
||||
ct.enabled as "contact.enabled",
|
||||
ct.last_active_at as "contact.last_active_at",
|
||||
|
53
internal/migrations/v0.7.4.go
Normal file
53
internal/migrations/v0.7.4.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/knadh/koanf/v2"
|
||||
"github.com/knadh/stuffbin"
|
||||
)
|
||||
|
||||
// V0_7_4 updates the database schema to v0.7.4.
|
||||
func V0_7_4(db *sqlx.DB, fs stuffbin.FileSystem, ko *koanf.Koanf) error {
|
||||
// Rename phone_number_calling_code to phone_number_country_code
|
||||
// This column will now store country codes (US, CA, GB) instead of calling codes (+1, +44)
|
||||
_, err := db.Exec(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'users' AND column_name = 'phone_number_country_code'
|
||||
) AND EXISTS (
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_name = 'users' AND column_name = 'phone_number_calling_code'
|
||||
) THEN
|
||||
ALTER TABLE users
|
||||
RENAME COLUMN phone_number_calling_code TO phone_number_country_code;
|
||||
END IF;
|
||||
END $$;
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Rename the constraint to match the new column name
|
||||
_, err = db.Exec(`
|
||||
DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (
|
||||
SELECT 1 FROM information_schema.constraint_column_usage
|
||||
WHERE constraint_name = 'constraint_users_on_phone_number_country_code'
|
||||
) AND EXISTS (
|
||||
SELECT 1 FROM information_schema.constraint_column_usage
|
||||
WHERE constraint_name = 'constraint_users_on_phone_number_calling_code'
|
||||
) THEN
|
||||
ALTER TABLE users
|
||||
RENAME CONSTRAINT constraint_users_on_phone_number_calling_code TO constraint_users_on_phone_number_country_code;
|
||||
END IF;
|
||||
END $$;
|
||||
`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@@ -29,7 +29,7 @@ func (u *Manager) CreateContact(user *models.User) error {
|
||||
|
||||
// UpdateContact updates a contact in the database.
|
||||
func (u *Manager) UpdateContact(id int, user models.User) error {
|
||||
if _, err := u.q.UpdateContact.Exec(id, user.FirstName, user.LastName, user.Email, user.AvatarURL, user.PhoneNumber, user.PhoneNumberCallingCode); err != nil {
|
||||
if _, err := u.q.UpdateContact.Exec(id, user.FirstName, user.LastName, user.Email, user.AvatarURL, user.PhoneNumber, user.PhoneNumberCountryCode); err != nil {
|
||||
u.lo.Error("error updating user", "error", err)
|
||||
return envelope.NewError(envelope.GeneralError, u.i18n.Ts("globals.messages.errorUpdating", "name", "{globals.terms.contact}"), nil)
|
||||
}
|
||||
|
@@ -53,7 +53,7 @@ type User struct {
|
||||
Email null.String `db:"email" json:"email"`
|
||||
Type string `db:"type" json:"type"`
|
||||
AvailabilityStatus string `db:"availability_status" json:"availability_status"`
|
||||
PhoneNumberCallingCode null.String `db:"phone_number_calling_code" json:"phone_number_calling_code"`
|
||||
PhoneNumberCountryCode null.String `db:"phone_number_country_code" json:"phone_number_country_code"`
|
||||
PhoneNumber null.String `db:"phone_number" json:"phone_number"`
|
||||
AvatarURL null.String `db:"avatar_url" json:"avatar_url"`
|
||||
Enabled bool `db:"enabled" json:"enabled"`
|
||||
|
@@ -39,7 +39,7 @@ SELECT
|
||||
u.availability_status,
|
||||
u.last_active_at,
|
||||
u.last_login_at,
|
||||
u.phone_number_calling_code,
|
||||
u.phone_number_country_code,
|
||||
u.phone_number,
|
||||
u.api_key,
|
||||
u.api_key_last_used_at,
|
||||
@@ -174,7 +174,7 @@ SET first_name = COALESCE($2, first_name),
|
||||
email = COALESCE($4, email),
|
||||
avatar_url = $5,
|
||||
phone_number = $6,
|
||||
phone_number_calling_code = $7,
|
||||
phone_number_country_code = $7,
|
||||
updated_at = now()
|
||||
WHERE id = $1 and type = 'contact';
|
||||
|
||||
@@ -233,7 +233,7 @@ SELECT
|
||||
u.availability_status,
|
||||
u.last_active_at,
|
||||
u.last_login_at,
|
||||
u.phone_number_calling_code,
|
||||
u.phone_number_country_code,
|
||||
u.phone_number,
|
||||
u.api_key,
|
||||
u.api_key_last_used_at,
|
||||
|
@@ -129,7 +129,7 @@ CREATE TABLE users (
|
||||
email TEXT NULL,
|
||||
first_name TEXT NOT NULL,
|
||||
last_name TEXT NULL,
|
||||
phone_number_calling_code TEXT NULL,
|
||||
phone_number_country_code TEXT NULL,
|
||||
phone_number TEXT NULL,
|
||||
country TEXT NULL,
|
||||
"password" VARCHAR(150) NULL,
|
||||
@@ -146,7 +146,7 @@ CREATE TABLE users (
|
||||
api_key_last_used_at TIMESTAMPTZ NULL,
|
||||
CONSTRAINT constraint_users_on_country CHECK (LENGTH(country) <= 140),
|
||||
CONSTRAINT constraint_users_on_phone_number CHECK (LENGTH(phone_number) <= 20),
|
||||
CONSTRAINT constraint_users_on_phone_number_calling_code CHECK (LENGTH(phone_number_calling_code) <= 10),
|
||||
CONSTRAINT constraint_users_on_phone_number_country_code CHECK (LENGTH(phone_number_country_code) <= 10),
|
||||
CONSTRAINT constraint_users_on_email_length CHECK (LENGTH(email) <= 320),
|
||||
CONSTRAINT constraint_users_on_first_name CHECK (LENGTH(first_name) <= 140),
|
||||
CONSTRAINT constraint_users_on_last_name CHECK (LENGTH(last_name) <= 140)
|
||||
|
Reference in New Issue
Block a user