diff --git a/docker-compose.yml b/docker-compose.yml
index e736949c..864869a5 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -109,7 +109,7 @@ services:
- sail
- reverse-proxy
playwright:
- image: mcr.microsoft.com/playwright:v1.50.0-jammy
+ image: mcr.microsoft.com/playwright:v1.51.1-jammy
command: ['npx', 'playwright', 'test', '--ui-port=8080', '--ui-host=0.0.0.0']
working_dir: /src
extra_hosts:
diff --git a/e2e/auth.spec.ts b/e2e/auth.spec.ts
index 34e942d2..634e71ea 100644
--- a/e2e/auth.spec.ts
+++ b/e2e/auth.spec.ts
@@ -36,7 +36,7 @@ test('can register and delete account', async ({ page }) => {
await page.goto(PLAYWRIGHT_BASE_URL + '/user/profile');
await page.getByRole('button', { name: 'Delete Account' }).click();
await page.getByPlaceholder('Password').fill(password);
- await page.getByRole('button', { name: 'Delete Account' }).nth(1).click();
+ await page.getByRole('button', { name: 'Delete Account' }).click();
await page.waitForURL(PLAYWRIGHT_BASE_URL + '/login');
await page.goto(PLAYWRIGHT_BASE_URL + '/login');
await page.getByLabel('Email').fill(email);
diff --git a/e2e/clients.spec.ts b/e2e/clients.spec.ts
index 733b9d26..9ca98d5d 100644
--- a/e2e/clients.spec.ts
+++ b/e2e/clients.spec.ts
@@ -16,7 +16,7 @@ test('test that creating and deleting a new client via the modal works', async (
await page.getByRole('button', { name: 'Create Client' }).click();
await page.getByPlaceholder('Client Name').fill(newClientName);
await Promise.all([
- page.getByRole('button', { name: 'Create Client' }).nth(1).click(),
+ page.getByRole('button', { name: 'Create Client' }).click(),
page.waitForResponse(
async (response) =>
response.url().includes('/clients') &&
@@ -56,12 +56,12 @@ test('test that archiving and unarchiving clients works', async ({ page }) => {
await page.getByRole('button', { name: 'Create Client' }).click();
await page.getByLabel('Client Name').fill(newClientName);
- await page.getByRole('button', { name: 'Create Client' }).nth(1).click();
+ await page.getByRole('button', { name: 'Create Client' }).click();
await expect(page.getByText(newClientName)).toBeVisible();
await page.getByRole('row').first().getByRole('button').click();
await Promise.all([
- page.getByRole('button').getByText('Archive').first().click(),
+ page.getByRole('menuitem').getByText('Archive').click(),
expect(page.getByText(newClientName)).not.toBeVisible(),
]);
await Promise.all([
@@ -71,7 +71,7 @@ test('test that archiving and unarchiving clients works', async ({ page }) => {
await page.getByRole('row').first().getByRole('button').click();
await Promise.all([
- page.getByRole('button').getByText('Unarchive').first().click(),
+ page.getByRole('menuitem').getByText('Unarchive').click(),
expect(page.getByText(newClientName)).not.toBeVisible(),
]);
await Promise.all([
diff --git a/e2e/members.spec.ts b/e2e/members.spec.ts
index dac09fea..253acf79 100644
--- a/e2e/members.spec.ts
+++ b/e2e/members.spec.ts
@@ -82,7 +82,7 @@ test('test that organization billable rate can be updated with all existing time
await goToMembersPage(page);
const newBillableRate = Math.round(Math.random() * 10000);
await page.getByRole('row').first().getByRole('button').click();
- await page.getByRole('button').getByText('Edit').first().click();
+ await page.getByRole('menuitem').getByText('Edit').click();
await page.getByText('Organization Default Rate').click();
await page.getByText('Custom Rate').click();
await page
diff --git a/e2e/project-members.spec.ts b/e2e/project-members.spec.ts
index 656f5781..7302a350 100644
--- a/e2e/project-members.spec.ts
+++ b/e2e/project-members.spec.ts
@@ -17,7 +17,7 @@ test('test that updating project member billable rate works for existing time en
await page.getByRole('button', { name: 'Create Project' }).click();
await page.getByLabel('Project Name').fill(newProjectName);
- await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
+ await page.getByRole('button', { name: 'Create Project' }).click();
await expect(page.getByText(newProjectName)).toBeVisible();
await page.getByText(newProjectName).click();
@@ -35,8 +35,7 @@ test('test that updating project member billable rate works for existing time en
.getByRole('button')
.click();
await page
- .getByRole('button', { name: 'Edit Project Member' })
- .first()
+ .getByRole('menuitem', { name: 'Edit Project Member' })
.click();
await page.getByLabel('Billable Rate').fill(newBillableRate.toString());
await page.getByRole('button', { name: 'Update Project Member' }).click();
diff --git a/e2e/projects.spec.ts b/e2e/projects.spec.ts
index 113a9a6d..d989630f 100644
--- a/e2e/projects.spec.ts
+++ b/e2e/projects.spec.ts
@@ -17,7 +17,7 @@ test('test that creating and deleting a new project via the modal works', async
await page.getByRole('button', { name: 'Create Project' }).click();
await page.getByLabel('Project Name').fill(newProjectName);
await Promise.all([
- page.getByRole('button', { name: 'Create Project' }).nth(1).click(),
+ page.getByRole('button', { name: 'Create Project' }).click(),
page.waitForResponse(
async (response) =>
response.url().includes('/projects') &&
@@ -62,12 +62,12 @@ test('test that archiving and unarchiving projects works', async ({ page }) => {
await page.getByRole('button', { name: 'Create Project' }).click();
await page.getByLabel('Project Name').fill(newProjectName);
- await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
+ await page.getByRole('button', { name: 'Create Project' }).click();
await expect(page.getByText(newProjectName)).toBeVisible();
await page.getByRole('row').first().getByRole('button').click();
await Promise.all([
- page.getByRole('button').getByText('Archive').first().click(),
+ page.getByRole('menuitem').getByText('Archive').first().click(),
expect(page.getByText(newProjectName)).not.toBeVisible(),
]);
await Promise.all([
@@ -77,7 +77,7 @@ test('test that archiving and unarchiving projects works', async ({ page }) => {
await page.getByRole('row').first().getByRole('button').click();
await Promise.all([
- page.getByRole('button').getByText('Unarchive').first().click(),
+ page.getByRole('menuitem').getByText('Unarchive').first().click(),
expect(page.getByText(newProjectName)).not.toBeVisible(),
]);
await Promise.all([
@@ -96,11 +96,11 @@ test('test that updating billable rate works with existing time entries', async
await page.getByRole('button', { name: 'Create Project' }).click();
await page.getByLabel('Project Name').fill(newProjectName);
- await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
+ await page.getByRole('button', { name: 'Create Project' }).click();
await expect(page.getByText(newProjectName)).toBeVisible();
await page.getByRole('row').first().getByRole('button').click();
- await page.getByRole('button').getByText('Edit').first().click(),
+ await page.getByRole('menuitem').getByText('Edit').first().click();
await page.getByText('Non-Billable').click();
await page.getByText('Custom Rate').click();
await page
diff --git a/e2e/tags.spec.ts b/e2e/tags.spec.ts
index 8074e1c1..4a29c3db 100644
--- a/e2e/tags.spec.ts
+++ b/e2e/tags.spec.ts
@@ -15,7 +15,7 @@ test('test that creating and deleting a new client via the modal works', async (
await page.getByRole('button', { name: 'Create Tag' }).click();
await page.getByPlaceholder('Tag Name').fill(newTagName);
await Promise.all([
- page.getByRole('button', { name: 'Create Tag' }).nth(1).click(),
+ page.getByRole('button', { name: 'Create Tag' }).click(),
page.waitForResponse(
async (response) =>
response.url().includes('/tags') &&
diff --git a/e2e/tasks.spec.ts b/e2e/tasks.spec.ts
index c8806eb8..d5165993 100644
--- a/e2e/tasks.spec.ts
+++ b/e2e/tasks.spec.ts
@@ -16,7 +16,7 @@ test('test that creating and deleting a new tag in a new project works', async (
await page.getByRole('button', { name: 'Create Project' }).click();
await page.getByLabel('Project Name').fill(newProjectName);
await Promise.all([
- page.getByRole('button', { name: 'Create Project' }).nth(1).click(),
+ page.getByRole('button', { name: 'Create Project' }).click(),
page.waitForResponse(
async (response) =>
response.url().includes('/projects') &&
@@ -41,7 +41,7 @@ test('test that creating and deleting a new tag in a new project works', async (
await page.getByPlaceholder('Task Name').fill(newTaskName);
await Promise.all([
- page.getByRole('button', { name: 'Create Task' }).nth(1).click(),
+ page.getByRole('button', { name: 'Create Task' }).click(),
page.waitForResponse(
async (response) =>
response.url().includes('/tasks') &&
@@ -107,20 +107,20 @@ test('test that archiving and unarchiving tasks works', async ({ page }) => {
await page.getByRole('button', { name: 'Create Project' }).click();
await page.getByLabel('Project Name').fill(newProjectName);
- await page.getByRole('button', { name: 'Create Project' }).nth(1).click();
+ await page.getByRole('button', { name: 'Create Project' }).click();
await expect(page.getByText(newProjectName)).toBeVisible();
await page.getByText(newProjectName).click();
await page.getByRole('button', { name: 'Create Task' }).click();
await page.getByPlaceholder('Task Name').fill(newTaskName);
- await page.getByRole('button', { name: 'Create Task' }).nth(1).click();
+ await page.getByRole('button', { name: 'Create Task' }).click();
await expect(page.getByRole('table')).toContainText(newTaskName);
await page.getByRole('row').first().getByRole('button').click();
await Promise.all([
- page.getByRole('button').getByText('Mark as done').first().click(),
+ page.getByRole('menuitem').getByText('Mark as done').first().click(),
expect(page.getByText(newTaskName)).not.toBeVisible(),
]);
await Promise.all([
@@ -130,7 +130,7 @@ test('test that archiving and unarchiving tasks works', async ({ page }) => {
await page.getByRole('row').first().getByRole('button').click();
await Promise.all([
- page.getByRole('button').getByText('Mark as active').first().click(),
+ page.getByRole('menuitem').getByText('Mark as active').first().click(),
expect(page.getByText(newTaskName)).not.toBeVisible(),
]);
await Promise.all([
diff --git a/resources/css/app.css b/resources/css/app.css
index dcd35e99..23809066 100644
--- a/resources/css/app.css
+++ b/resources/css/app.css
@@ -2,11 +2,11 @@
@tailwind components;
@tailwind utilities;
:root.dark {
- --color-bg-primary: #0f1011;
- --color-bg-secondary: #17181a;
+ --color-bg-primary: #101012;
+ --color-bg-secondary: #17181B;
--color-bg-tertiary: #2A2C32;
--color-bg-quaternary: #141518;
- --color-bg-background: #0B0B0B;
+ --color-bg-background: #090909;
--color-text-primary: #ffffff;
--color-text-secondary: #e3e4e6;
--color-text-tertiary: #969799;
@@ -22,7 +22,7 @@
--theme-color-menu-active: var(--color-bg-secondary);
--theme-color-card-background: var(--color-bg-secondary);
- --theme-shadow-card: 0 4px 7px 0px rgb(0 0 0 / 30%);
+ --theme-shadow-card: 0 4px 7px 0px rgb(0 0 0 / 15%);
--theme-shadow-dropdown: 0 4px 7px 0px rgb(0 0 0 / 40%);
--theme-color-card-background-active: var(--color-bg-tertiary);
diff --git a/resources/js/Layouts/AppLayout.vue b/resources/js/Layouts/AppLayout.vue
index ab32eda0..b0d571df 100644
--- a/resources/js/Layouts/AppLayout.vue
+++ b/resources/js/Layouts/AppLayout.vue
@@ -266,7 +266,7 @@ const page = usePage<{