-
- {{ props.options.find(option => option.value === inputValue)?.label || 'Select an option' }}
-
-
-
-
- -
- {{ option.label }}
-
-
+
+
+ {{ props.options.find((option) => option.value === inputValue)?.label || 'Select an option' }}
+
+
+
+
+ -
+ {{ option.label }}
+
+
+
-
diff --git a/frontend/src/components/client/ui/TextForms/TextArea.vue b/frontend/src/components/client/ui/TextForms/TextArea.vue
index ba19f08..9cceeb4 100755
--- a/frontend/src/components/client/ui/TextForms/TextArea.vue
+++ b/frontend/src/components/client/ui/TextForms/TextArea.vue
@@ -1,27 +1,27 @@
-
+
diff --git a/frontend/src/locale/en.yml b/frontend/src/locale/en.yml
index c2a902d..d9262bc 100755
--- a/frontend/src/locale/en.yml
+++ b/frontend/src/locale/en.yml
@@ -1,5 +1,4 @@
---
-
#-------------------------------------------------------------#
#
# Global Components
@@ -8,34 +7,35 @@
#
#-------------------------------------------------------------#
Components:
- ErrorsPage:
- Buttons:
- GoBack: "Go Back"
- GoHome: "Go Home"
- Global:
- Navigation:
- Loading: "Loading..."
- Copy:
- Title: "Copied"
- Success: "Copied to clipboard just like a boss."
- Footer: "Yay it worked ;)"
- Error: "An error occurred. Please try again later."
- Announcements:
- Title: "Announcements"
- Card:
- ReadMore: "Read More"
- SupportPin:
- title: "Support PIN"
- copy: "Copy"
- alerts:
- success:
- title: "Success"
- pin_success: "Support PIN generated"
- footer: "Your support PIN has been generated"
- error:
- title: "Error"
- generic: "An error occurred. Please try again later"
- footer: "Please contact support for assistance"
+ ErrorsPage:
+ Buttons:
+ GoBack: 'Go Back'
+ GoHome: 'Go Home'
+ Global:
+ Navigation:
+ Loading: 'Loading...'
+ Copy:
+ Title: 'Copied'
+ Success: 'Copied to clipboard just like a boss.'
+ Footer: 'Yay it worked ;)'
+ Error: 'An error occurred. Please try again later.'
+ Announcements:
+ Title: 'Announcements'
+ Card:
+ ReadMore: 'Read More'
+ SupportPin:
+ title: 'Support PIN'
+ copy: 'Copy'
+ alerts:
+ success:
+ title: 'Success'
+ pin_success: 'Support PIN generated'
+ footer: 'Your support PIN has been generated'
+ error:
+ title: 'Error'
+ generic: 'An error occurred. Please try again later'
+ footer: 'Please contact support for assistance'
+
#-------------------------------------------------------------#
#
# Auth Pages (/auth/*)
@@ -43,9 +43,8 @@ Components:
# @public
#
#-------------------------------------------------------------#
-dashboard:
- title: Dashboard
-
+dashboard:
+ title: Dashboard
auth:
logic:
@@ -282,6 +281,57 @@ errors:
#-------------------------------------------------------------#
account:
pages:
+ tickets:
+ title: Tickets
+ actions:
+ newTicket: 'Tickets'
+ view: 'View'
+ alerts:
+ error:
+ generic: 'An error occurred. Please try again later'
+ table:
+ title: 'Tickets'
+ subject: 'Subject'
+ status: 'Status'
+ priority: 'Priority'
+ department: 'Department'
+ created: 'Created'
+ actions: 'Actions'
+ noTickets: 'No tickets found'
+ create_ticket:
+ title: 'New Ticket'
+ subTitle: 'Create a new ticket'
+ form:
+ service: 'Related Service (if any)'
+ subject: 'Subject'
+ department: 'Department'
+ priority: 'Priority'
+ message: 'Message'
+ submit: 'Submit'
+ loading: 'Submitting...'
+ reset: 'Reset'
+ back: 'Back'
+ types:
+ priority:
+ low: 'Low'
+ medium: 'Medium'
+ high: 'High'
+ urgent: 'Urgent'
+ alerts:
+ success:
+ title: 'Success'
+ ticket_success: 'Ticket created'
+ footer: 'Your ticket has been created'
+ error:
+ title: 'Error'
+ generic: 'An error occurred. Please try again later'
+ footer: 'Please contact support for assistance'
+ department_not_found: 'Department not found'
+ department_id_missing: 'Department ID is missing'
+ message_missing: 'Message is missing'
+ subject_missing: 'Subject is missing'
+ limit_reached: 'You have reached the limit of tickets you can create'
+ failed_to_create_ticket: 'Cluster is down, try again later'
settings:
alerts:
success:
diff --git a/frontend/src/mythicalclient/Auth.ts b/frontend/src/mythicalclient/Auth.ts
index b20390f..640d628 100755
--- a/frontend/src/mythicalclient/Auth.ts
+++ b/frontend/src/mythicalclient/Auth.ts
@@ -23,243 +23,243 @@
*
* ---------------------------*/
class Auth {
- /**
- * Logs the user in
- *
- * @param email The email to log in with
- * @param turnstileResponse The turnstile response
- *
- * @returns The response from the server
- */
- static async forgotPassword(email: string, turnstileResponse: string) {
- const response = await fetch('/api/user/auth/forgot', {
- method: 'POST',
- body: new URLSearchParams({
- email: email,
- turnstileResponse: turnstileResponse,
- }),
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Logs the user in
+ *
+ * @param email The email to log in with
+ * @param turnstileResponse The turnstile response
+ *
+ * @returns The response from the server
+ */
+ static async forgotPassword(email: string, turnstileResponse: string) {
+ const response = await fetch('/api/user/auth/forgot', {
+ method: 'POST',
+ body: new URLSearchParams({
+ email: email,
+ turnstileResponse: turnstileResponse,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- * Resets the password
- *
- * @param confirmPassword The password to confirm
- * @param password The new password
- * @param resetCode The reset code
- * @param turnstileResponse The turnstile response
- *
- * @returns The response from the server
- */
- static async resetPassword(
- confirmPassword: string,
- password: string,
- resetCode: string,
- turnstileResponse: string,
- ) {
- const response = await fetch('/api/user/auth/reset', {
- method: 'POST',
- body: new URLSearchParams({
- password: password,
- confirmPassword: confirmPassword,
- email_code: resetCode || '',
- turnstileResponse: turnstileResponse,
- }),
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Resets the password
+ *
+ * @param confirmPassword The password to confirm
+ * @param password The new password
+ * @param resetCode The reset code
+ * @param turnstileResponse The turnstile response
+ *
+ * @returns The response from the server
+ */
+ static async resetPassword(
+ confirmPassword: string,
+ password: string,
+ resetCode: string,
+ turnstileResponse: string,
+ ) {
+ const response = await fetch('/api/user/auth/reset', {
+ method: 'POST',
+ body: new URLSearchParams({
+ password: password,
+ confirmPassword: confirmPassword,
+ email_code: resetCode || '',
+ turnstileResponse: turnstileResponse,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- * Verifies the login token
- *
- * @param code The code to verify
- *
- * @returns The response from the server
- */
- static async isLoginVerifyTokenValid(code: string) {
- const response = await fetch(`/api/user/auth/reset?code=${code}`, {
- method: 'GET',
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Verifies the login token
+ *
+ * @param code The code to verify
+ *
+ * @returns The response from the server
+ */
+ static async isLoginVerifyTokenValid(code: string) {
+ const response = await fetch(`/api/user/auth/reset?code=${code}`, {
+ method: 'GET',
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- * Registers the user
- *
- * @param firstName The first name
- * @param lastName The last name
- * @param email The email
- * @param username The username
- * @param password The password
- * @param turnstileResponse The turnstile response
- *
- * @returns The response from the server
- */
- static async register(
- firstName: string,
- lastName: string,
- email: string,
- username: string,
- password: string,
- turnstileResponse: string,
- ) {
- const response = await fetch('/api/user/auth/register', {
- method: 'POST',
- body: new URLSearchParams({
- firstName: firstName,
- lastName: lastName,
- email: email,
- username: username,
- password: password,
- turnstileResponse: turnstileResponse,
- }),
- });
- const data = await response.json();
- return data;
- }
- /**
- * Logs the user in
- *
- * @param login The users email or username
- * @param password The users password
- * @param turnstileResponse The turnstile response
- *
- * @returns
- */
- static async login(login: string, password: string, turnstileResponse: string) {
- const response = await fetch('/api/user/auth/login', {
- method: 'POST',
- body: new URLSearchParams({
- login: login,
- password: password,
- turnstileResponse: turnstileResponse,
- }),
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Registers the user
+ *
+ * @param firstName The first name
+ * @param lastName The last name
+ * @param email The email
+ * @param username The username
+ * @param password The password
+ * @param turnstileResponse The turnstile response
+ *
+ * @returns The response from the server
+ */
+ static async register(
+ firstName: string,
+ lastName: string,
+ email: string,
+ username: string,
+ password: string,
+ turnstileResponse: string,
+ ) {
+ const response = await fetch('/api/user/auth/register', {
+ method: 'POST',
+ body: new URLSearchParams({
+ firstName: firstName,
+ lastName: lastName,
+ email: email,
+ username: username,
+ password: password,
+ turnstileResponse: turnstileResponse,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
+ /**
+ * Logs the user in
+ *
+ * @param login The users email or username
+ * @param password The users password
+ * @param turnstileResponse The turnstile response
+ *
+ * @returns
+ */
+ static async login(login: string, password: string, turnstileResponse: string) {
+ const response = await fetch('/api/user/auth/login', {
+ method: 'POST',
+ body: new URLSearchParams({
+ login: login,
+ password: password,
+ turnstileResponse: turnstileResponse,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- * Update the users billing information
- *
- * @param company_name The company name
- * @param vat_number The vat number
- * @param address1 The address line 1
- * @param address2 The address line 2
- * @param city The city
- * @param country The country
- * @param state The state
- * @param postcode The postcode
- *
- * @returns
- */
- static async updateBilling(
- company_name: string,
- vat_number: string,
- address1: string,
- address2: string,
- city: string,
- country: string,
- state: string,
- postcode: string,
- ) {
- const response = await fetch('/api/user/session/billing/update', {
- method: 'POST',
- body: new URLSearchParams({
- company_name: company_name,
- vat_number: vat_number,
- address1: address1,
- address2: address2,
- city: city,
- country: country,
- state: state,
- postcode: postcode,
- }),
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Update the users billing information
+ *
+ * @param company_name The company name
+ * @param vat_number The vat number
+ * @param address1 The address line 1
+ * @param address2 The address line 2
+ * @param city The city
+ * @param country The country
+ * @param state The state
+ * @param postcode The postcode
+ *
+ * @returns
+ */
+ static async updateBilling(
+ company_name: string,
+ vat_number: string,
+ address1: string,
+ address2: string,
+ city: string,
+ country: string,
+ state: string,
+ postcode: string,
+ ) {
+ const response = await fetch('/api/user/session/billing/update', {
+ method: 'POST',
+ body: new URLSearchParams({
+ company_name: company_name,
+ vat_number: vat_number,
+ address1: address1,
+ address2: address2,
+ city: city,
+ country: country,
+ state: state,
+ postcode: postcode,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- * Update the users info
- *
- * @param first_name The first name
- * @param last_name The last name
- * @param email The email
- * @param avatar The avatar
- * @param background The background
- *
- * @returns
- */
- static async updateUserInfo(
- first_name: string,
- last_name: string,
- email: string,
- avatar: string,
- background: string,
- ) {
- const response = await fetch('/api/user/session/info/update', {
- method: 'POST',
- body: new URLSearchParams({
- first_name: first_name,
- last_name: last_name,
- email: email,
- avatar: avatar,
- background: background,
- }),
- });
- const data = await response.json();
- return data;
- }
- /**
- * Setup 2fa
- *
- * @returns
- */
- static async getTwoFactorSecret() {
- const response = await fetch('/api/user/auth/2fa/setup', {
- method: 'GET',
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Update the users info
+ *
+ * @param first_name The first name
+ * @param last_name The last name
+ * @param email The email
+ * @param avatar The avatar
+ * @param background The background
+ *
+ * @returns
+ */
+ static async updateUserInfo(
+ first_name: string,
+ last_name: string,
+ email: string,
+ avatar: string,
+ background: string,
+ ) {
+ const response = await fetch('/api/user/session/info/update', {
+ method: 'POST',
+ body: new URLSearchParams({
+ first_name: first_name,
+ last_name: last_name,
+ email: email,
+ avatar: avatar,
+ background: background,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
+ /**
+ * Setup 2fa
+ *
+ * @returns
+ */
+ static async getTwoFactorSecret() {
+ const response = await fetch('/api/user/auth/2fa/setup', {
+ method: 'GET',
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- * Verify 2fa
- *
- * @param code The code
- *
- * @returns
- */
- static async verifyTwoFactor(code: string, turnstileResponse: string) {
- const response = await fetch('/api/user/auth/2fa/setup', {
- method: 'POST',
- body: new URLSearchParams({
- code: code,
- turnstileResponse: turnstileResponse,
- }),
- });
- const data = await response.json();
- return data;
- }
+ /**
+ * Verify 2fa
+ *
+ * @param code The code
+ *
+ * @returns
+ */
+ static async verifyTwoFactor(code: string, turnstileResponse: string) {
+ const response = await fetch('/api/user/auth/2fa/setup', {
+ method: 'POST',
+ body: new URLSearchParams({
+ code: code,
+ turnstileResponse: turnstileResponse,
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
- /**
- *
- * Reset the support pin!
- *
- * @returns The new pin
- */
- static async resetPin(): Promise
{
- const response = await fetch('/api/user/session/newPin', {
- method: 'POST',
- });
- const data = await response.json();
- return parseInt(data.pin, 10);
- }
+ /**
+ *
+ * Reset the support pin!
+ *
+ * @returns The new pin
+ */
+ static async resetPin(): Promise {
+ const response = await fetch('/api/user/session/newPin', {
+ method: 'POST',
+ });
+ const data = await response.json();
+ return parseInt(data.pin, 10);
+ }
}
export default Auth;
diff --git a/frontend/src/mythicalclient/Tickets.ts b/frontend/src/mythicalclient/Tickets.ts
index d3641cb..321d9fc 100755
--- a/frontend/src/mythicalclient/Tickets.ts
+++ b/frontend/src/mythicalclient/Tickets.ts
@@ -1,31 +1,38 @@
class Tickets {
- public static async getTicketCreateInfo() {
- const response = await fetch('/api/user/ticket/create', {
- method: 'GET',
- });
- const data = await response.json();
- return data;
- }
- static async createTicket(
- department_id: number,
- subject: string,
- message: string,
- priority: string,
- service: number,
- ) {
- const response = await fetch('/api/user/ticket/create', {
- method: 'POST',
- body: new URLSearchParams({
- department_id: department_id.toString(),
- subject: subject,
- message: message,
- priority: priority,
- service: service.toString() || '',
- }),
- });
- const data = await response.json();
- return data;
- }
+ public static async getTicketCreateInfo() {
+ const response = await fetch('/api/user/ticket/create', {
+ method: 'GET',
+ });
+ const data = await response.json();
+ return data;
+ }
+ static async createTicket(
+ department_id: number,
+ subject: string,
+ message: string,
+ priority: string,
+ service: number,
+ ) {
+ const response = await fetch('/api/user/ticket/create', {
+ method: 'POST',
+ body: new URLSearchParams({
+ department_id: department_id.toString(),
+ subject: subject,
+ message: message,
+ priority: priority,
+ service: service.toString() || '',
+ }),
+ });
+ const data = await response.json();
+ return data;
+ }
+ static async getTickets() {
+ const response = await fetch('/api/user/ticket/list', {
+ method: 'GET',
+ });
+ const data = await response.json();
+ return data;
+ }
}
export default Tickets;
diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts
index 4c7821c..0da1fb9 100755
--- a/frontend/src/router/index.ts
+++ b/frontend/src/router/index.ts
@@ -1,110 +1,110 @@
import { createRouter, createWebHistory } from 'vue-router';
const routes = [
- {
- path: '/auth/login',
- name: 'Login',
- component: () => import('@/views/client/auth/Login.vue'),
- },
- {
- path: '/auth/register',
- name: 'Register',
- component: () => import('@/views/client/auth/Register.vue'),
- },
- {
- path: '/auth/forgot-password',
- name: 'Forgot Password',
- component: () => import('@/views/client/auth/ForgotPassword.vue'),
- },
- {
- path: '/auth/reset-password',
- name: 'Reset Password',
- component: () => import('@/views/client/auth/ResetPassword.vue'),
- },
- {
- path: '/auth/2fa/setup',
- name: 'Two Factor Setup',
- component: () => import('@/views/client/auth/TwoFactorSetup.vue'),
- },
- {
- path: '/errors/403',
- name: 'Forbidden',
- component: () => import('@/views/client/errors/Forbidden.vue'),
- },
- {
- path: '/errors/500',
- name: 'ServerError',
- component: () => import('@/views/client/errors/ServerError.vue'),
- },
- {
- path: '/dashboard',
- name: 'Dashboard',
- component: () => import('@/views/client/Home.vue'),
- },
- {
- path: '/account',
- name: 'Account',
- component: () => import('@/views/client/Account.vue'),
- },
- {
- path: '/ticket',
- name: 'Ticket',
- component: () => import('@/views/client/ticket/List.vue'),
- },
- {
- path: '/ticket/create',
- name: 'Create Ticket',
- component: () => import('@/views/client/ticket/Create.vue'),
- },
- {
- path: '/ticket/:id',
- name: 'Ticket Detail',
- component: () => import('@/views/client/ticket/[id].vue'),
- },
- {
- path: '/auth/sso',
- name: 'SSO',
- component: () => import('@/views/client/auth/sso.vue'),
- },
- {
- path: '/auth/2fa/setup/disband',
- redirect: () => {
- window.location.href = '/api/auth/2fa/setup/kill';
- return '/api/auth/2fa/setup/kill';
- },
- },
- {
- path: '/auth/logout',
- redirect: () => {
- window.location.href = '/api/user/auth/logout';
- return '/api/user/auth/logout';
- },
- },
- {
- path: '/auth/2fa/verify',
- name: 'Two Factor Verify',
- component: () => import('@/views/client/auth/TwoFactorVerify.vue'),
- },
- {
- path: '/',
- redirect: '/dashboard',
- },
- {
- path: '/mc-admin',
- name: 'Admin Home',
- component: () => import('@/views/admin/Home.vue'),
- },
+ {
+ path: '/auth/login',
+ name: 'Login',
+ component: () => import('@/views/client/auth/Login.vue'),
+ },
+ {
+ path: '/auth/register',
+ name: 'Register',
+ component: () => import('@/views/client/auth/Register.vue'),
+ },
+ {
+ path: '/auth/forgot-password',
+ name: 'Forgot Password',
+ component: () => import('@/views/client/auth/ForgotPassword.vue'),
+ },
+ {
+ path: '/auth/reset-password',
+ name: 'Reset Password',
+ component: () => import('@/views/client/auth/ResetPassword.vue'),
+ },
+ {
+ path: '/auth/2fa/setup',
+ name: 'Two Factor Setup',
+ component: () => import('@/views/client/auth/TwoFactorSetup.vue'),
+ },
+ {
+ path: '/errors/403',
+ name: 'Forbidden',
+ component: () => import('@/views/client/errors/Forbidden.vue'),
+ },
+ {
+ path: '/errors/500',
+ name: 'ServerError',
+ component: () => import('@/views/client/errors/ServerError.vue'),
+ },
+ {
+ path: '/dashboard',
+ name: 'Dashboard',
+ component: () => import('@/views/client/Home.vue'),
+ },
+ {
+ path: '/account',
+ name: 'Account',
+ component: () => import('@/views/client/Account.vue'),
+ },
+ {
+ path: '/ticket',
+ name: 'Ticket',
+ component: () => import('@/views/client/ticket/List.vue'),
+ },
+ {
+ path: '/ticket/create',
+ name: 'Create Ticket',
+ component: () => import('@/views/client/ticket/Create.vue'),
+ },
+ {
+ path: '/ticket/:id',
+ name: 'Ticket Detail',
+ component: () => import('@/views/client/ticket/[id].vue'),
+ },
+ {
+ path: '/auth/sso',
+ name: 'SSO',
+ component: () => import('@/views/client/auth/sso.vue'),
+ },
+ {
+ path: '/auth/2fa/setup/disband',
+ redirect: () => {
+ window.location.href = '/api/auth/2fa/setup/kill';
+ return '/api/auth/2fa/setup/kill';
+ },
+ },
+ {
+ path: '/auth/logout',
+ redirect: () => {
+ window.location.href = '/api/user/auth/logout';
+ return '/api/user/auth/logout';
+ },
+ },
+ {
+ path: '/auth/2fa/verify',
+ name: 'Two Factor Verify',
+ component: () => import('@/views/client/auth/TwoFactorVerify.vue'),
+ },
+ {
+ path: '/',
+ redirect: '/dashboard',
+ },
+ {
+ path: '/mc-admin',
+ name: 'Admin Home',
+ component: () => import('@/views/admin/Home.vue'),
+ },
];
routes.push({
- path: '/:pathMatch(.*)*',
- name: 'NotFound',
- component: () => import('@/views/client/errors/NotFound.vue'),
+ path: '/:pathMatch(.*)*',
+ name: 'NotFound',
+ component: () => import('@/views/client/errors/NotFound.vue'),
});
const router = createRouter({
- history: createWebHistory(),
- routes,
+ history: createWebHistory(),
+ routes,
});
export default router;
diff --git a/frontend/src/views/client/Home.vue b/frontend/src/views/client/Home.vue
index 235ad87..1e970d1 100755
--- a/frontend/src/views/client/Home.vue
+++ b/frontend/src/views/client/Home.vue
@@ -1,33 +1,31 @@
-
-
-
+
+
-
+
diff --git a/frontend/src/views/client/ticket/Create.vue b/frontend/src/views/client/ticket/Create.vue
index f261d1a..c86771c 100755
--- a/frontend/src/views/client/ticket/Create.vue
+++ b/frontend/src/views/client/ticket/Create.vue
@@ -18,202 +18,232 @@ const { play: playError } = useSound(failedAlertSfx);
const { play: playSuccess } = useSound(successAlertSfx);
const router = useRouter();
+document.title = t('account.pages.create_ticket.title');
+
interface Department {
- id: number;
- name: string;
- description: string;
- time_open: string;
- time_close: string;
- enabled: string;
- deleted: string;
- locked: string;
- date: string;
+ id: number;
+ name: string;
+ description: string;
+ time_open: string;
+ time_close: string;
+ enabled: string;
+ deleted: string;
+ locked: string;
+ date: string;
}
interface Service {
- id: number;
- name: string;
- active: boolean;
+ id: number;
+ name: string;
+ active: boolean;
}
interface TicketCreateInfo {
- departments: Department[];
- services: Service[];
+ departments: Department[];
+ services: Service[];
}
const ticketCreateInfo = ref
(null);
const loading = ref(false);
const fetchTicketCreateInfo = async () => {
- try {
- const response = await Tickets.getTicketCreateInfo();
- if (response.success) {
- ticketCreateInfo.value = {
- departments: response.departments,
- services: response.services
- };
- } else {
- console.error('Failed to fetch ticket create info:', response.error);
+ try {
+ const response = await Tickets.getTicketCreateInfo();
+ if (response.success) {
+ ticketCreateInfo.value = {
+ departments: response.departments,
+ services: response.services,
+ };
+ } else {
+ console.error('Failed to fetch ticket create info:', response.error);
+ }
+ } catch (error) {
+ console.error('Error fetching ticket create info:', error);
}
- } catch (error) {
- console.error('Error fetching ticket create info:', error);
- }
};
onMounted(() => {
- fetchTicketCreateInfo();
+ fetchTicketCreateInfo();
});
const ticket = ref({
- service: '',
- department: '',
- priority: 'medium',
- subject: '',
- message: ''
+ service: '',
+ department: '',
+ priority: 'medium',
+ subject: '',
+ message: '',
});
const priorities = [
- { value: 'low', label: 'Low' },
- { value: 'medium', label: 'Medium' },
- { value: 'high', label: 'High' },
- { value: 'urgent', label: 'Urgent' }
+ { value: 'low', label: t('account.pages.create_ticket.types.priority.low') },
+ { value: 'medium', label: t('account.pages.create_ticket.types.priority.medium') },
+ { value: 'high', label: t('account.pages.create_ticket.types.priority.high') },
+ { value: 'urgent', label: t('account.pages.create_ticket.types.priority.urgent') },
];
const submitTicket = async () => {
- loading.value = true;
- try {
- // Handle ticket submission
- console.log('Submitting ticket:', ticket.value);
-
- const response = await Tickets.createTicket(Number(ticket.value.department), ticket.value.subject, ticket.value.message, ticket.value.priority, Number(ticket.value.service));
-
- if (!response.success) {
- const error_code = response.error_code as keyof typeof errorMessages;
-
- const errorMessages = {
-
- };
-
- if (errorMessages[error_code]) {
- playError();
- Swal.fire({
- icon: 'error',
- title: "Error while creating ticket!",
- text: errorMessages[error_code],
- footer: "Kinda funny since you tried to create a ticket",
- showConfirmButton: true,
- });
+ loading.value = true;
+ try {
+ // Handle ticket submission
+ console.log('Submitting ticket:', ticket.value);
+
+ const response = await Tickets.createTicket(
+ Number(ticket.value.department),
+ ticket.value.subject,
+ ticket.value.message,
+ ticket.value.priority,
+ Number(ticket.value.service),
+ );
+
+ if (!response.success) {
+ const error_code = response.error_code as keyof typeof errorMessages;
+
+ const errorMessages = {
+ LIMIT_REACHED: t('account.pages.create_ticket.alerts.error.limit_reached'),
+ FAILED_TO_CREATE_TICKET: t('account.pages.create_ticket.alerts.error.generic'),
+ DEPARTMENT_NOT_FOUND: t('account.pages.create_ticket.alerts.error.department_not_found'),
+ DEPARTMENT_ID_MISSING: t('account.pages.create_ticket.alerts.error.department_id_missing'),
+ MESSAGE_MISSING: t('account.pages.create_ticket.alerts.error.message_missing'),
+ SUBJECT_MISSING: t('account.pages.create_ticket.alerts.error.subject_missing'),
+ };
+
+ if (errorMessages[error_code]) {
+ playError();
+ Swal.fire({
+ icon: 'error',
+ title: t('account.pages.create_ticket.alerts.error.title'),
+ text: errorMessages[error_code],
+ footer: t('account.pages.create_ticket.alerts.error.footer'),
+ showConfirmButton: true,
+ });
+ loading.value = false;
+ throw new Error('Login failed');
+ } else {
+ playError();
+ Swal.fire({
+ icon: 'error',
+ title: t('account.pages.create_ticket.alerts.error.title'),
+ text: t('account.pages.create_ticket.alerts.error.generic'),
+ footer: t('account.pages.create_ticket.alerts.error.footer'),
+ showConfirmButton: true,
+ });
+ loading.value = false;
+ throw new Error('Ticket creation failed');
+ }
+ } else {
+ playSuccess();
+ Swal.fire({
+ icon: 'success',
+ title: t('account.pages.create_ticket.alerts.success.title'),
+ text: t('account.pages.create_ticket.alerts.success.ticket_success'),
+ footer: t('account.pages.create_ticket.alerts.success.footer'),
+ showConfirmButton: true,
+ });
+ loading.value = false;
+ setTimeout(() => {
+ router.push('/ticket');
+ }, 1500);
+ console.log('Ticket submitted successfully:', response.ticket);
+ }
+
+ await new Promise((resolve) => setTimeout(resolve, 2000));
+ } catch (error) {
+ console.error('Error submitting ticket:', error);
+ } finally {
loading.value = false;
- throw new Error('Login failed');
- } else {
- playError();
- Swal.fire({
- icon: 'error',
- title: "Error while creating ticket!",
- text: "We never expected this to happen",
- footer: "Kinda funny since you tried to create a ticket",
- showConfirmButton: true,
- });
- loading.value = false;
- throw new Error('Ticket creation failed');
- }
- } else {
- playSuccess();
- Swal.fire({
- icon: 'success',
- title: "Ticket submitted successfully!",
- text: "Your ticket has been submitted successfully",
- footer: "You will be redirected to the ticket page",
- showConfirmButton: true,
- });
- loading.value = false;
- setTimeout(() => {
- router.push('/ticket');
- }, 1500);
- console.log('Ticket submitted successfully:', response.ticket);
}
-
- await new Promise(resolve => setTimeout(resolve, 2000));
- } catch (error) {
- console.error('Error submitting ticket:', error);
- } finally {
- loading.value = false;
- }
};
-
-
-
-
Support Tickets
-
-
-
-
-
-
-
-
-
+
+
+
+
{{ t('account.pages.create_ticket.title') }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/views/client/ticket/List.vue b/frontend/src/views/client/ticket/List.vue
index bba8318..96df31e 100755
--- a/frontend/src/views/client/ticket/List.vue
+++ b/frontend/src/views/client/ticket/List.vue
@@ -1,99 +1,237 @@
-
+
-
Support Tickets
+
{{ t('account.pages.tickets.title') }}
-
+
+
+
+
+
+
+
+
+
{{ t('account.pages.tickets.noTickets') }}
+
{{ t('account.pages.tickets.createNewTicket') }}
+
+
+
+
+
+
+