dsg
Copy This
//------------------------------------------ CORE ------------------------------------------//
import {
  getSessionUser,
  handleSignUp,
  updateAboutUserIds,
  updateContentIds,
  updateUsername,
  verifyUser
} from './api/auth.js'
import store from './store.js'
import routes from './routes.js'

import {
  displayProfile
} from './profile.js'
import {
  getIDFromQrCode
} from './api/scanner.js'
import {
  openModal,
  openQRModal
} from './qr.js'
import {
  sendRNMessage
} from './api/consts.js'


var $ = Dom7
var userStore = store.getters.user
var notificationCountStore = store.getters.getNotifCount
var networkErrors = store.getters.checkPoorNetworkError

var toolbarEl = $('.footer')[0]

var app = new Framework7({
  initOnDeviceReady: true,
  view: {
    pushState: false,
    stackPages: true,
    xhrCache: true,
    preloadPreviousPage: true,
    // browserHistory: true,
  },
  notification: {
    title: 'OrganikFlok',
    closeTimeout: 10000,
    closeOnClick: true,
    icon: '<img src="assets/icons/favicon.png"/>',
  },
  toast: {
    closeTimeout: 3000,
    closeButton: true,
  },
  name: 'OrganikFlok',
  theme: 'ios',
  smartSelect: {
    closeOnSelect: true,
  },
  cache: true,
  el: '#app', // App root element
  on: {
    init: async function () {
      // toolbarEl.style.display = 'none'

      await store.dispatch('checkAuth')

      const isAuthenticated = store.getters.isAuthenticated.value

      if (!isAuthenticated) {
        this.views.main.router.navigate('/auth/')
      } else {
        $('.init-loader').hide()
        $('.start-link').click();
        // toolbarEl.style.display = 'block'
      }

      const deeplink = getQueryParameter('deeplink')
      if (deeplink) {
        // check if deeplink has ?qr= query parameter
        // if it does, get the value of the qr parameter and redirect to the profile
        // ex; http://localhost:3000/?qr=123456
        const maybeQr = deeplink.split('?qr=')[1]
        const deepqrCode = maybeQr ? maybeQr : null

        if (deepqrCode) {
          maybeRedirectToProfile(deepqrCode)
          return;
        }

        // check if url looks like https://mydrivelife.com/qr/8700279E
        // if it does, get the qr code and redirect to the profile
        const isDriveLifeUrl = deeplink.includes('mydrivelife.com/qr/')
        if (isDriveLifeUrl) {
          const qrCode = deeplink.split('/').slice(-1)[0]
          maybeRedirectToProfile(qrCode)
          return;
        }

        // get the page from the deeplink and navigate to it
        // ex; http://localhost:3000/post-view/308
        // get the /post-view/308 and navigate to it
        let path = deeplink.split('/').slice(3).join('/')

        if (!path.startsWith('/')) {
          path = `/${path}`
        }

        this.views.main.router.navigate(path)
        // remove the query parameter from the URL
        window.history.pushState({}, document.title, window.location.pathname)
      }

      const qrCode = getQueryParameter('qr')
      if (qrCode) {
        maybeRedirectToProfile(qrCode)
      }
    },
    pageInit: function (page) {
      if (page.name === 'profile') {
        userStore.onUpdated((data) => {
          if (data && data.id && !data.external_refresh) {
            displayProfile(data, 'profile')
            store.dispatch('getMyGarage')
          }

          if (data && data.id && !data.refreshed) {
            store.dispatch('getMyPosts', {
              page: 1,
              clear: true
            })
            store.dispatch('getMyWastes', {
              page: 1,
              clear: true
            })
          }
        })
      }

      if (page.name === 'discover') {
        userStore.onUpdated((data) => {
          if (data && data.id && !data.refreshed) {
            store.dispatch('getTrendingEvents')
            store.dispatch('getTrendingVenues')
            store.dispatch('filterTrendingUsers')
            store.dispatch('fetchEventCategories')
          }
        })
      }

      if (page.name === 'signup-step2') {
        const registerData = store.getters.getRegisterData.value

        const userNameEl = document.getElementsByName('username')[0]
        userNameEl.value = registerData.username
      }
    },
  },
  store: store,
  routes: routes,
})

$(document).on('mousedown', '.toolbar-bottom a', function (e) {
  var targetHref = $(this).attr('href');
  var validTabs = ['#view-social', '#view-discover', '#view-store', '#view-profile'];

  if ($(this).hasClass('tab-link-active') && validTabs.includes(targetHref)) {
    var view = app.views.current;
    if (view.history.length > 1) {
      view.router.back(view.history[0], {
        force: true
      });
    }
  }
});

export function showToast(message, type = 'Message', position = 'bottom') {
  app.toast.create({
    text: message,
    position: position,
    closeTimeout: 3000,
  }).open()
}

async function maybeRedirectToProfile(qrCode) {
  var view = app.views.current

  try {
    $('.init-loader').show()
    const response = await getIDFromQrCode(qrCode)

    if (response && response.status === 'error') {
      throw new Error(response.message || 'Oops, Unable to find the profile linked to this QR code.')
    }

    const user = store.getters.user.value
    const id = response?.data?.linked_to;

    if (id) {
      if (user && user.id == id) {
        $('.view-profile-link').click()
      } else {
        view.router.navigate(`/profile-view/${id}`)
      }
    } else {
      openModal()
      setTimeout(() => {
        store.dispatch('setScannedData', {
          status: 'success',
          qr_code: qrCode,
          message: 'QR Code is not linked to any profile',
          available: true
        })
      }, 1000)
    }

    // remove the query parameter from the URL
    window.history.pushState({}, document.title, window.location.pathname)
    $('.init-loader').hide()
  } catch (error) {
    console.log(error);
    window.history.pushState({}, document.title, window.location.pathname)
    app.dialog.alert(error.message || 'Oops, Unable to find the profile linked to this QR code.')
    $('.init-loader').hide()
  }
}

// Function to parse query parameters from the URL
function getQueryParameter(name, url) {

  const urlParams = new URLSearchParams(url || window.location.search)
  return urlParams.get(name)
}

function isAndroid() {
  const toMatch = [
    /Android/i,
    // /webOS/i,
    // /iPhone/i,
    // /iPad/i,
    // /iPod/i,
    /BlackBerry/i,
    /Windows Phone/i,
  ];

  return toMatch.some((toMatchItem) => {
    return navigator.userAgent.match(toMatchItem);
  });
}

export function onBackKeyDown() {
  // check if the device is an android device
  if (!isAndroid()) {
    return
  }

  var view = app.views.current

  var leftp = app.panel.left && app.panel.left.opened
  var rightp = app.panel.right && app.panel.right.opened

  window.ReactNativeWebView.postMessage(JSON.stringify({
    his: view.history,
    url: app.views.main.router.url,
    leftp,
    rightp
  }))

  if (leftp || rightp) {
    app.panel.close()
    return false
  } else if ($('.modal-in').length > 0) {
    app.dialog.close()
    app.popup.close()
    return false
  } else if (view.history[0] == '/') {
    window.ReactNativeWebView.postMessage('exit_app')
    return true
  } else {
    if (view.history.length < 2) {
      $('.tab-link[href="#view-home"]').click()
      return
    }

    view.router.back()
    return false
  }
}

window.onAppBackKey = onBackKeyDown

userStore.onUpdated((data) => {
  if (data && data.id && !data.external_refresh && !data.refreshed) {
    store.dispatch('getPosts')
    store.dispatch('getFollowingPosts')
    store.dispatch('notificationCount')
    store.dispatch('fetchNotifications')
  }
})

notificationCountStore.onUpdated((data) => {
  document.querySelectorAll('.notification-count').forEach((el) => {
    el.innerHTML = data
    el.style.display = data > 0 ? 'flex' : 'none'
  })
})

networkErrors.onUpdated((data) => {
  if (data) {
    app.dialog.alert('Poor network connection. Please check your internet connection and try again.')
  }
})

// Action Sheet with Grid Layout
var actionSheet = app.actions.create({
  grid: true,
  buttons: [
    [{
        text: '<div class="actions-grid-item">Add Post</div>',
        icon: '<img src="assets/img/icon-add-post.svg" width="48" style="max-width: 100%"/>',
        onClick: async function () {
          const user = await getSessionUser()
          if (user) {
            sendRNMessage({
              type: "createPost",
              user_id: user.id,
              page: 'create-post',
            })
          }
        }
      },
      {
        text: '<div class="actions-grid-item">Scan QR Code</div>',
        icon: '<img src="assets/img/icon-qr-code.svg" width="48" style="max-width: 100%;"/>',
        onClick: function () {
          openQRModal()
        }
      },
      {
        text: '<div class="actions-grid-item">Add Vehicle</div>',
        icon: '<img src="assets/img/icon-vehicle-add.svg" width="48" style="max-width: 100%;"/>',
        onClick: function () {
          app.views.main.router.navigate('/profile-garage-vehicle-add/');
        }
      }
    ],
  ]
});

// Init slider
new Swiper('.swiper-container', {
  pagination: {
    el: '.swiper-pagination',
    clickable: true,
  },
})

//Comments Popup
// app.popup.create({
//   el: '.comments-popup',
//   swipeToClose: 'to-bottom'
// })

//Share Popup
app.popup.create({
  el: '.share-popup',
  swipeToClose: 'to-bottom'
})

//Share Popup
app.popup.create({
  el: '.edit-post-popup',
  swipeToClose: 'to-bottom'
})


$(document).on('click', '#open-action-sheet', function () {
  actionSheet.open()
})

// Handle login form submission
$(document).on('submit', '.login-screen-content form', async function (e) {
  e.preventDefault()

  var username = $(this).find('input[name="username"]').val()
  var password = $(this).find('input[name="password"]').val()

  if (!username) {
    showToast('Username is required')
    return
  }

  if (!password) {
    showToast('Password is required')
    return
  }


  try {
    app.preloader.show()
    const response = await verifyUser({
      email: username,
      password
    })

    app.preloader.hide()

    if (!response || response.error) {
      app.dialog.alert(response.error || 'Login failed, please try again')
      return
    }

    if (response.success) {
      showToast('Login successful')
      await store.dispatch('login', {
        token: response.token
      })

      app.views.main.router.navigate('/')
      $('.start-link').click();

      toolbarEl.style.display = 'block'
      return
    }
  } catch (error) {
    app.dialog.alert('Login failed, please try again')
  }
})

$(document).on('click', '.toggle-password', function () {
  var input = $(this).prev('input')
  if (input.attr('type') === 'password') {
    input.attr('type', 'text')
    $(this).html('<i class="fa fa-eye-slash"></i>')
  } else {
    input.attr('type', 'password')
    $(this).html('<i class="fa fa-eye"></i>')
  }
})

// Register forms
// Step 1
$(document).on('submit', 'form#sign-up-step1', async function (e) {
  e.preventDefault()

  var firstName = $(this).find('input[name="first_name"]').val().trim()
  var lastName = $(this).find('input[name="last_name"]').val().trim()
  var email = $(this).find('input[name="email"]').val().trim()
  var password = $(this).find('input[name="password"]').val().trim()
  var confirmPassword = $(this).find('input[name="confirm_password"]').val().trim()
  var agreeTerms = $(this).find('input[name="agree_terms"]').is(':checked')
  var agreePrivacy = $(this).find('input[name="agree_privacy"]').is(':checked')

  if (!firstName) {
    showToast('First name is required')
    return
  }

  if (!lastName) {
    showToast('Last name is required')
    return
  }

  if (!email) {
    showToast('Email is required')
    return
  }

  var emailPattern = /^[^s@]+@[^s@]+.[^s@]+$/
  if (!emailPattern.test(email)) {
    showToast('Please enter a valid email address')
    return
  }

  if (!password) {
    showToast('Password is required')
    return
  }

  // Check if password has at least 8 characters
  if (password.length < 8) {
    showToast('Password must be at least 8 characters long.')
    return
  }

  // Check if password contains at least one lowercase letter
  if (!/[a-z]/.test(password)) {
    showToast('Password must contain at least one lowercase letter.')
    return
  }

  // Check if password contains at least one uppercase letter
  if (!/[A-Z]/.test(password)) {
    showToast('Password must contain at least one uppercase letter.')
    return
  }

  // Check if password contains at least one number
  if (!/d/.test(password)) {
    showToast('Password must contain at least one number.')
    return
  }

  if (password.length < 8) {
    showToast('Password must be at least 8 characters long')
    return
  }

  if (!confirmPassword) {
    showToast('Please confirm your password')
    return
  }

  if (password !== confirmPassword) {
    showToast('Passwords do not match')
    return
  }

  if (!agreeTerms) {
    showToast('You must agree to the Terms & Conditions')
    return
  }

  if (!agreePrivacy) {
    showToast('You must agree to the Privacy Policy')
    return
  }

  // add a loader to the login button
  var loginButton = $(this).find('button[type="submit"]')[0]
  loginButton.innerHTML = '<div class="preloader color-white"></div>'

  try {
    app.preloader.show()

    const response = await handleSignUp({
      full_name: `${firstName} ${lastName}`,
      email,
      password
    })

    app.preloader.hide()

    if (!response || !response.success) {
      app.dialog.alert(response.message || 'An error occurred, please try again')
      loginButton.innerHTML = 'Next'
      return
    }

    store.dispatch('setRegisterData', {
      email,
      password,
      user_id: response.user_id,
      username: response.username
    })
    app.views.main.router.navigate('/signup-step2/')
  } catch (error) {
    console.log(error)
    app.dialog.alert(error.message || 'An error occurred, please try again')
    loginButton.innerHTML = 'Next'
    return
  }
})

// Step 2
$(document).on('submit', 'form#sign-up-step2', async function (e) {
  e.preventDefault()

  var username = $(this).find('input[name="username"]').val().trim()

  if (!username) {
    showToast('Username is required')
    return
  }

  // username can only have letters, numbers, and underscores
  var usernamePattern = /^[a-zA-Z0-9_]+$/
  if (!usernamePattern.test(username)) {
    showToast('Username can only contain letters, numbers, and underscores')
    return
  }

  // username must be at least 3 characters long
  if (username.length < 3) {
    showToast('Username must be at least 3 characters long')
    return
  }

  let registerData = store.getters.getRegisterData.value
  try {
    if (registerData.username !== username) {
      app.preloader.show()

      const response = await updateUsername(username, registerData.user_id)

      app.preloader.hide()

      if (!response || !response.success) {
        app.notification.create({
          titleRightText: 'now',
          subtitle: 'Oops, something went wrong',
          text: error.message || 'Failed to update username',
        }).open()
        // app.dialog.alert(response.message || 'An error occurred, please try again')
        return
      }

      store.dispatch('setRegisterData', {
        ...registerData,
        username
      })
    }

    app.views.main.router.navigate('/signup-step3/')
  } catch (error) {
    console.log(error);
    app.notification.create({
      titleRightText: 'now',
      subtitle: 'Oops, something went wrong',
      text: error.message || 'Failed to update username',
    }).open()
    return
  }
})

// Step 3
$(document).on('submit', '#car-selection-form', async function (e) {
  e.preventDefault()

  // Get all checked checkboxes' values
  var selectedCarTypes = []
  $(this).find('input[name="car_type"]:checked').each(function () {
    selectedCarTypes.push($(this).val())
  })

  // Check if at least one checkbox is selected
  if (selectedCarTypes.length === 0) {
    showToast('Please select at least one car type')
    return
  }

  // For demonstration, log the selected values to the console
  let registerData = store.getters.getRegisterData.value

  try {
    app.preloader.show()
    const response = await updateContentIds(selectedCarTypes, registerData.user_id)

    if (!response || !response.success) {
      app.dialog.alert(response.message || 'Oops, Unable to save your selection.')
    }

    app.preloader.hide()
    app.views.main.router.navigate('/signup-step4/')
  } catch (error) {
    console.log(error)
    app.dialog.alert('An error occurred, please try again')
    return
  }

  // Redirect to the next step (this can be customized as needed)
  app.views.main.router.navigate('/signup-step4/')
})

// Step 4
$(document).on('submit', '#interest-selection-form', async function (e) {
  e.preventDefault()

  // Get all checked checkboxes' values
  var selectedInterests = []
  $(this).find('input[name="interest"]:checked').each(function () {
    selectedInterests.push($(this).val())
  })

  // Check if at least one checkbox is selected
  if (selectedInterests.length === 0) {
    showToast('Please select at least one interest')
    return
  }

  let registerData = store.getters.getRegisterData.value

  try {
    app.preloader.show()
    const response = await updateAboutUserIds(selectedInterests, registerData.user_id)

    if (!response || !response.success) {
      app.dialog.alert(response.message || 'Oops, Unable to save your selection.')
    }

    app.preloader.hide()

    app.views.main.router.navigate('/signup-complete/')
  } catch (error) {
    console.log(error)
    app.dialog.alert('An error occurred, please try again')
    return
  }
})

// Signup complete
$(document).on('click', '#signup-complete', async function (e) {
  const registerData = store.getters.getRegisterData.value

  if (!registerData || !registerData.user_id || !registerData.email || !registerData.password) {
    app.dialog.alert('An error occurred, please try again')
    return
  }

  try {
    app.preloader.show()

    const response = await verifyUser({
      email: registerData.email,
      password: registerData.password
    })

    app.preloader.hide()

    if (!response || response.error) {
      app.dialog.alert(response.error || 'Login failed, please try again')
      app.views.main.router.navigate('/auth/')
      loginButton.innerHTML = 'Next'
      return
    }

    if (response.success) {
      await store.dispatch('login', {
        token: response.token
      })
      app.views.main.router.navigate('/')
      $('.start-link').click();

      toolbarEl.style.display = 'block'
      return
    }
  } catch (error) {
    app.dialog.alert('Login failed, please try again')
  }
})

$(document).on('page:afterin', '.page[data-name="auth"]', function (e) {
  toolbarEl.style.display = 'none'

  setTimeout(() => {
    $('.init-loader').hide()
  }, 300)
});

$(document).on('page:afterin', '.page[data-name="signup-step1"]', function (e) {
  app.popup.create({
    el: '.privacy-popup',
    swipeToClose: 'to-bottom'
  })
});

// logout-button
$(document).on('click', '.logout-button', async function (e) {
  app.dialog.close()
  app.popup.close()
  app.panel.close()

  await store.dispatch('logout')

  // reload page
  window.location.reload()
  // app.views.current.router.navigate('/auth/')
})

$(document).on('click', '.view-profile', function (e) {
  $('.view-profile-link').click()
})

$(document).on('click', '#forgot-password', function (e) {
  // open the url in a new tab
  window.open($(this).attr('href'), '_blank')
})

export default app
Add JS Function Name