mock-settings.ts 7.78 KB
import type { Member } from '../../app/types'

export interface MockSettingsProfile {
  name: string
  email: string
  username: string
  avatar?: string
  bio?: string
}

export interface MockSettingsNotifications {
  email: boolean
  desktop: boolean
  product_updates: boolean
  weekly_digest: boolean
  important_updates: boolean
}

export interface MemberProfilePayload {
  name: string
  email: string
  username: string
  role: Member['role']
  avatar?: string
  bio?: string
}

interface MockSettingsState {
  profile: MockSettingsProfile
  notifications: MockSettingsNotifications
  password: string
  members: Member[]
  accountDeleted: boolean
}

function createAvatar(src: string, alt: string) {
  return {
    src,
    alt
  }
}

const mockSettingsState: MockSettingsState = {
  profile: {
    name: 'Benjamin Canac',
    email: 'ben@nuxtlabs.com',
    username: 'benjamincanac',
    avatar: undefined,
    bio: undefined
  },
  notifications: {
    email: true,
    desktop: false,
    product_updates: true,
    weekly_digest: false,
    important_updates: true
  },
  password: '12345678',
  members: [{
    name: 'Anthony Fu',
    email: 'antfu@robot.local',
    username: 'antfu',
    role: 'member',
    bio: 'Assembly line member',
    avatar: createAvatar('https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/antfu', 'Anthony Fu')
  }, {
    name: 'Baptiste Leproux',
    email: 'larbish@robot.local',
    username: 'larbish',
    role: 'member',
    bio: 'Quality check support',
    avatar: createAvatar('https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/larbish', 'Baptiste Leproux')
  }, {
    name: 'Benjamin Canac',
    email: 'ben@nuxtlabs.com',
    username: 'benjamincanac',
    role: 'admin',
    bio: 'System admin',
    avatar: createAvatar('https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/benjamincanac', 'Benjamin Canac')
  }, {
    name: 'Celine Dumerc',
    email: 'celinedumerc@robot.local',
    username: 'celinedumerc',
    role: 'customer',
    bio: 'Customer representative',
    avatar: createAvatar('https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/celinedumerc', 'Celine Dumerc')
  }, {
    name: 'Daniel Roe',
    email: 'danielroe@robot.local',
    username: 'danielroe',
    role: 'member',
    bio: 'Production operator',
    avatar: createAvatar('https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/danielroe', 'Daniel Roe')
  }, {
    name: 'Hugo Richard',
    email: 'hugorcd@robot.local',
    username: 'hugorcd',
    role: 'admin',
    bio: 'Operation supervisor',
    avatar: createAvatar('https://ipx.nuxt.com/f_auto,s_192x192/gh_avatar/hugorcd', 'Hugo Richard')
  }],
  accountDeleted: false
}

function cloneMember(member: Member): Member {
  return {
    ...member,
    avatar: {
      ...member.avatar
    }
  }
}

function normalizeAvatar(avatar: string | undefined, fallbackName: string) {
  if (avatar && avatar.trim().length > 0) {
    return createAvatar(avatar.trim(), fallbackName)
  }

  const encoded = encodeURIComponent(fallbackName || `member-${Date.now()}`)
  return createAvatar(`https://i.pravatar.cc/128?u=${encoded}`, fallbackName)
}

export function getMockSettingsProfile() {
  return { ...mockSettingsState.profile }
}

export function updateMockSettingsProfile(profile: MockSettingsProfile) {
  mockSettingsState.profile = {
    ...profile
  }

  return getMockSettingsProfile()
}

export function getMockSettingsNotifications() {
  return { ...mockSettingsState.notifications }
}

export function updateMockSettingsNotifications(notifications: MockSettingsNotifications) {
  mockSettingsState.notifications = {
    ...notifications
  }

  return getMockSettingsNotifications()
}

export function updateMockSettingsPassword(current: string, next: string) {
  if (mockSettingsState.password !== current) {
    return {
      success: false as const,
      errorCode: 'CURRENT_PASSWORD_INCORRECT' as const,
      message: '当前密码不正确。'
    }
  }

  mockSettingsState.password = next

  return {
    success: true as const,
    errorCode: null,
    message: '密码已更新。'
  }
}

export function markMockAccountDeleted() {
  mockSettingsState.accountDeleted = true

  return {
    success: true as const,
    message: '账号已标记删除(Mock)。'
  }
}

export function getMockSettingsMembers() {
  return mockSettingsState.members.map(member => cloneMember(member))
}

export function updateMockMemberRole(username: string, role: Member['role']) {
  const index = mockSettingsState.members.findIndex(member => member.username === username)

  if (index === -1) {
    return {
      success: false as const,
      errorCode: 'MEMBER_NOT_FOUND' as const,
      message: '成员不存在。'
    }
  }

  const targetMember = mockSettingsState.members[index]!

  mockSettingsState.members[index] = {
    ...targetMember,
    role
  }

  return {
    success: true as const,
    errorCode: null,
    message: '成员角色已更新。',
    member: cloneMember(mockSettingsState.members[index]!)
  }
}

export function createMockMember(payload: MemberProfilePayload) {
  const usernameExists = mockSettingsState.members.some(member => member.username === payload.username)
  if (usernameExists) {
    return {
      success: false as const,
      errorCode: 'USERNAME_EXISTS' as const,
      message: '用户名已存在。'
    }
  }

  const emailExists = mockSettingsState.members.some(member => member.email === payload.email)
  if (emailExists) {
    return {
      success: false as const,
      errorCode: 'EMAIL_EXISTS' as const,
      message: '邮箱已存在。'
    }
  }

  const newMember: Member = {
    name: payload.name,
    email: payload.email,
    username: payload.username,
    role: payload.role,
    bio: payload.bio,
    avatar: normalizeAvatar(payload.avatar, payload.name)
  }

  mockSettingsState.members.unshift(newMember)

  return {
    success: true as const,
    errorCode: null,
    message: '成员邀请已发送。',
    member: cloneMember(newMember)
  }
}

export function updateMockMemberProfile(username: string, payload: MemberProfilePayload) {
  const index = mockSettingsState.members.findIndex(member => member.username === username)

  if (index === -1) {
    return {
      success: false as const,
      errorCode: 'MEMBER_NOT_FOUND' as const,
      message: '成员不存在。'
    }
  }

  const usernameConflict = mockSettingsState.members.some((member, currentIndex) => currentIndex !== index && member.username === payload.username)
  if (usernameConflict) {
    return {
      success: false as const,
      errorCode: 'USERNAME_EXISTS' as const,
      message: '用户名已存在。'
    }
  }

  const emailConflict = mockSettingsState.members.some((member, currentIndex) => currentIndex !== index && member.email === payload.email)
  if (emailConflict) {
    return {
      success: false as const,
      errorCode: 'EMAIL_EXISTS' as const,
      message: '邮箱已存在。'
    }
  }

  const currentMember = mockSettingsState.members[index]!

  const updatedMember: Member = {
    name: payload.name,
    email: payload.email,
    username: payload.username,
    role: payload.role,
    bio: payload.bio,
    avatar: normalizeAvatar(payload.avatar, payload.name || currentMember.name)
  }

  mockSettingsState.members[index] = updatedMember

  return {
    success: true as const,
    errorCode: null,
    message: '成员资料已更新。',
    member: cloneMember(updatedMember)
  }
}

export function removeMockMember(username: string) {
  const index = mockSettingsState.members.findIndex(member => member.username === username)

  if (index === -1) {
    return {
      success: false as const,
      errorCode: 'MEMBER_NOT_FOUND' as const,
      message: '成员不存在。'
    }
  }

  const [removed] = mockSettingsState.members.splice(index, 1)

  return {
    success: true as const,
    errorCode: null,
    message: '成员已移除。',
    member: removed ? cloneMember(removed) : undefined
  }
}