+ {{ element.value }} +
++ Type: {{ element.type }} +
++ Relation: {{ element.relation }} +
+diff --git a/app/controllers/projects_controller.ts b/app/controllers/projects_controller.ts new file mode 100644 index 0000000..21e20df --- /dev/null +++ b/app/controllers/projects_controller.ts @@ -0,0 +1,54 @@ +// app/controllers/projects_controller.ts +import Project from '#models/project'; +import type { HttpContext } from '@adonisjs/core/http'; +import { createProjectValidator, updateProjectValidator } from '#validators/project'; + +export default class ProjectsController { + // GET /settings/projects + public async index({ inertia, auth }: HttpContext) { + const projects = await Project.all(); + // return inertia.render('Admin/Project/Index', { projects }); + return inertia.render('Admin/Project/Index', { + projects: projects, + can: { + edit: await auth.user?.can(['settings']), + create: await auth.user?.can(['settings']), + }, + }); + } + + // GET /settings/projects/create + public async create({ inertia }: HttpContext) { + return inertia.render('Admin/Project/Create'); + } + + // POST /settings/projects + public async store({ request, response, session }: HttpContext) { + // Validate the request data + const data = await request.validateUsing(createProjectValidator); + + await Project.create(data); + + session.flash('success', 'Project created successfully'); + return response.redirect().toRoute('settings.project.index'); + } + + // GET /settings/projects/:id/edit + public async edit({ params, inertia }: HttpContext) { + const project = await Project.findOrFail(params.id); + return inertia.render('Admin/Project/Edit', { project }); + } + + // PUT /settings/projects/:id + public async update({ params, request, response, session }: HttpContext) { + const project = await Project.findOrFail(params.id); + + // Validate the request data + const data = await request.validateUsing(updateProjectValidator); + + await project.merge(data).save(); + + session.flash('success', 'Project updated successfully'); + return response.redirect().toRoute('settings.project.index'); + } +} diff --git a/app/validators/project.ts b/app/validators/project.ts new file mode 100644 index 0000000..bad6c7c --- /dev/null +++ b/app/validators/project.ts @@ -0,0 +1,28 @@ +// app/validators/project.ts +import vine from '@vinejs/vine'; + +export const createProjectValidator = vine.compile( + vine.object({ + label: vine.string().trim().minLength(1).maxLength(50), + name: vine + .string() + .trim() + .minLength(3) + .maxLength(255) + .regex(/^[a-z0-9-]+$/), + description: vine.string().trim().maxLength(255).minLength(5).optional(), + }), +); + +export const updateProjectValidator = vine.compile( + vine.object({ + // label is NOT included since it's readonly + name: vine + .string() + .trim() + .minLength(3) + .maxLength(255) + .regex(/^[a-z0-9-]+$/), + description: vine.string().trim().maxLength(255).minLength(5).optional(), + }), +); diff --git a/resources/js/Layouts/LayoutAuthenticated.vue b/resources/js/Layouts/LayoutAuthenticated.vue index 15a117c..c077c7b 100644 --- a/resources/js/Layouts/LayoutAuthenticated.vue +++ b/resources/js/Layouts/LayoutAuthenticated.vue @@ -14,11 +14,11 @@ const props = defineProps({ showAsideMenu: { type: Boolean, default: true // Set default value to true + }, + hasProgressBar: { + type: Boolean, + default: false // New prop to indicate if progress bar is shown } - // user: { - // type: Object, - // default: () => ({}), - // } }); @@ -29,9 +29,18 @@ const props = defineProps({ }">
| - - Name - | -- - Sort Order - | +Name | +Sort Order | +Status | Actions | -
|---|---|---|---|---|---|
|
+
+
+ No licenses found +Licenses will appear here once configured + |
+ |||||
| - - {{ license.name }} + | -- {{ license.sort_order }} + | + + {{ license.sort_order }} + + | ++ + + Active + + + + Inactive + | -
|
|
+ {{ project.name }} +
+Are you sure you want to delete this project?
+This action cannot be undone.
+| Label | +Name | +Actions | +
|---|---|---|
|
+
+
+ No projects yet +Get started by creating your first project + |
+ ||
| + + + {{ truncate(project.label, 30) }} + + + | ++ + {{ truncate(project.name, 40) }} + + | +
+ |
+
Lorem ipsum dolor sit amet adipiscing elit
-This is sample modal
+Are you sure you want to delete this role?
+This action cannot be undone.
|
+
+
+ No roles yet +Get started by creating your first role + |
+ ||
| - - {{ role.name }} + + + {{ role.name }} + | - {{ role.description }} + + {{ truncate(role.description, 50) }} + |
|
Loading chart data...
+No chart data available
+No references added yet.
+Click the plus icon above to add a new reference.
+| Value | +Type | +Relation | +Label | ++ |
|---|---|---|---|---|
|
+
+
+ {{ form.errors[`references.${index}.value`].join(', ') }}
+
+ |
+
+
+ {{ form.errors[`references.${index}.type`].join(', ') }}
+
+ |
+
+
+
+ {{ form.errors[`references.${index}.relation`].join(', ') }}
+
+ |
+
+
+
+ {{ form.errors[`references.${index}.label`].join(', ') }}
+
+ |
+
+
+ |
+
+ Type: {{ element.type }} +
++ Relation: {{ element.relation }} +
+No references added yet.
-Click the plus icon above to add a new reference.
-| Value | -Type | -Relation | -Label | -- |
|---|---|---|---|---|
|
-
-
- {{ form.errors[`references.${index}.value`].join(', ') }}
-
- |
-
-
- {{ form.errors[`references.${index}.type`].join(', ') }}
-
- |
+
-
- {{ form.errors[`references.${index}.relation`].join(', ') }}
-
- |
-
-
-
- {{ form.errors[`references.${index}.label`].join(', ') }}
-
- |
-
-
- |
-
- Type: {{ element.type }} -
-- Relation: {{ element.relation }} -
-Saving changes...
+Please wait while we update your dataset
+