front-end restructuring, chat shows message ownership
This commit is contained in:
@@ -22,11 +22,3 @@ const className = computed(() => props.class);
|
||||
<slot />
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.app-content {
|
||||
@apply mx-auto flex h-full w-full max-w-7xl flex-1 flex-col gap-4 rounded-xl;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -10,23 +10,3 @@ import AppLogoIcon from '@/components/AppLogoIcon.vue';
|
||||
<span class="app-logo__text">Laravel Starter Kit</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.app-logo__icon-container {
|
||||
@apply flex aspect-square size-8 items-center justify-center rounded-md bg-sidebar-primary text-sidebar-primary-foreground;
|
||||
}
|
||||
|
||||
.app-logo__icon {
|
||||
@apply size-5 fill-current text-white dark:text-black;
|
||||
}
|
||||
|
||||
.app-logo__text-container {
|
||||
@apply ml-1 grid flex-1 text-left text-sm;
|
||||
}
|
||||
|
||||
.app-logo__text {
|
||||
@apply mb-0.5 truncate leading-tight font-semibold;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,15 +23,3 @@ withDefaults(
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.sidebar-header {
|
||||
@apply flex h-16 shrink-0 items-center gap-2 border-b border-sidebar-border/70 px-6 transition-[width,height] ease-linear group-has-data-[collapsible=icon]/sidebar-wrapper:h-12 md:px-4;
|
||||
}
|
||||
|
||||
.sidebar-header__inner {
|
||||
@apply flex items-center gap-2;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -27,27 +27,3 @@ const tabs = [
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.appearance-tabs {
|
||||
@apply inline-flex gap-1 rounded-lg bg-neutral-100 p-1 dark:bg-neutral-800;
|
||||
}
|
||||
|
||||
.appearance-tabs__tab {
|
||||
@apply flex items-center rounded-md px-3.5 py-1.5 text-neutral-500 transition-colors hover:bg-neutral-200/60 hover:text-black dark:text-neutral-400 dark:hover:bg-neutral-700/60;
|
||||
}
|
||||
|
||||
.appearance-tabs__tab--active {
|
||||
@apply bg-white shadow-xs hover:bg-white dark:bg-neutral-700 dark:text-neutral-100 dark:hover:bg-neutral-700;
|
||||
}
|
||||
|
||||
.appearance-tabs__icon {
|
||||
@apply -ml-1 h-4 w-4;
|
||||
}
|
||||
|
||||
.appearance-tabs__label {
|
||||
@apply ml-1.5 text-sm;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useForm } from '@inertiajs/vue3';
|
||||
import { ref, computed } from 'vue';
|
||||
import { useForm, usePage } from '@inertiajs/vue3';
|
||||
import { useEcho, echoIsConfigured, configureEcho } from '@laravel/echo-vue';
|
||||
import { route } from 'ziggy-js';
|
||||
import { Paperclip, Info } from '@lucide/vue';
|
||||
@@ -10,7 +10,7 @@ const props = defineProps<{
|
||||
id: number;
|
||||
messages: Array<{
|
||||
id: number;
|
||||
user: { name: string };
|
||||
user: { id: number; name: string };
|
||||
content: string;
|
||||
created_at: string;
|
||||
media?: Array<{
|
||||
@@ -63,6 +63,12 @@ function removeFile(index: number) {
|
||||
form.media.splice(index, 1);
|
||||
}
|
||||
|
||||
const currentUser = computed(() => usePage().props.auth?.user);
|
||||
|
||||
function isOwnMessage(messageUserId: number): boolean {
|
||||
return currentUser.value && currentUser.value.id === messageUserId;
|
||||
}
|
||||
|
||||
function submit() {
|
||||
form.post(route('chats.messages.store', props.chat.id), {
|
||||
onSuccess: () => {
|
||||
@@ -103,6 +109,10 @@ function closeLightbox() {
|
||||
{
|
||||
'c-chat__message--system':
|
||||
message.content.startsWith('System:'),
|
||||
'c-chat__message--own': isOwnMessage(message.user.id),
|
||||
'c-chat__message--other': !isOwnMessage(
|
||||
message.user.id,
|
||||
),
|
||||
},
|
||||
]"
|
||||
>
|
||||
@@ -240,185 +250,22 @@ function closeLightbox() {
|
||||
</form>
|
||||
|
||||
<!-- Gorgeous Dark Lightbox Modal -->
|
||||
<div
|
||||
v-if="activeLightboxUrl"
|
||||
class="c-chat__lightbox"
|
||||
@click="closeLightbox"
|
||||
>
|
||||
<button @click="closeLightbox" class="c-chat__lightbox-close">
|
||||
✕
|
||||
</button>
|
||||
<div class="c-chat__lightbox-content" @click.stop>
|
||||
<div v-if="activeLightboxUrl" class="c-lightbox" @click="closeLightbox">
|
||||
<button @click="closeLightbox" class="c-lightbox__close">✕</button>
|
||||
<div class="c-lightbox__content" @click.stop>
|
||||
<img
|
||||
v-if="activeLightboxType === 'image'"
|
||||
:src="activeLightboxUrl"
|
||||
class="c-chat__lightbox-image"
|
||||
class="c-lightbox__image"
|
||||
/>
|
||||
<video
|
||||
v-else-if="activeLightboxType === 'video'"
|
||||
:src="activeLightboxUrl"
|
||||
controls
|
||||
autoplay
|
||||
class="c-chat__lightbox-video"
|
||||
class="c-lightbox__video"
|
||||
></video>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.c-chat {
|
||||
@apply mt-8;
|
||||
}
|
||||
|
||||
.c-chat__title {
|
||||
@apply text-lg font-medium text-gray-900 dark:text-gray-100;
|
||||
}
|
||||
|
||||
.c-chat__list {
|
||||
@apply mt-4 space-y-4;
|
||||
}
|
||||
|
||||
.c-chat__message {
|
||||
@apply overflow-hidden bg-white p-4 shadow-sm sm:rounded-lg dark:bg-gray-800;
|
||||
}
|
||||
|
||||
.c-chat__message--system {
|
||||
@apply border-0 bg-transparent p-0 shadow-none;
|
||||
}
|
||||
|
||||
.c-chat__system-inner {
|
||||
@apply flex items-center gap-2 rounded-md border border-neutral-200/60 bg-neutral-50 px-3 py-1.5 text-xs text-neutral-500 dark:border-neutral-800/40 dark:bg-neutral-900/10 dark:text-neutral-400;
|
||||
}
|
||||
|
||||
.c-chat__system-icon {
|
||||
@apply size-3.5 shrink-0 text-neutral-400;
|
||||
}
|
||||
|
||||
.c-chat__system-text {
|
||||
@apply flex-1 font-medium;
|
||||
}
|
||||
|
||||
.c-chat__system-time {
|
||||
@apply shrink-0 text-[10px] text-neutral-400;
|
||||
}
|
||||
|
||||
.c-chat__message-header {
|
||||
@apply flex justify-between;
|
||||
}
|
||||
|
||||
.c-chat__message-author {
|
||||
@apply font-semibold;
|
||||
}
|
||||
|
||||
.c-chat__message-time {
|
||||
@apply text-xs text-gray-500;
|
||||
}
|
||||
|
||||
.c-chat__message-text {
|
||||
@apply mt-2 text-sm text-gray-600 dark:text-gray-400;
|
||||
}
|
||||
|
||||
.c-chat__message-media {
|
||||
@apply mt-3 flex flex-wrap gap-2;
|
||||
}
|
||||
|
||||
.c-chat__media-item {
|
||||
@apply relative max-w-[240px] overflow-hidden rounded-md border border-neutral-200 bg-black dark:border-neutral-700;
|
||||
}
|
||||
|
||||
.c-chat__image {
|
||||
@apply h-auto max-h-[180px] w-full object-cover;
|
||||
}
|
||||
|
||||
.c-chat__video {
|
||||
@apply h-auto max-h-[180px] w-full;
|
||||
}
|
||||
|
||||
.c-chat__play-overlay {
|
||||
@apply absolute inset-0 flex items-center justify-center bg-black/40 text-2xl font-bold text-white;
|
||||
}
|
||||
|
||||
.c-chat__empty {
|
||||
@apply text-gray-500;
|
||||
}
|
||||
|
||||
.c-chat__form {
|
||||
@apply mt-6 space-y-6;
|
||||
}
|
||||
|
||||
.c-chat__form-group {
|
||||
@apply space-y-2;
|
||||
}
|
||||
|
||||
.c-chat__label {
|
||||
@apply block text-sm font-medium text-gray-700 dark:text-gray-300;
|
||||
}
|
||||
|
||||
.c-chat__textarea {
|
||||
@apply mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
}
|
||||
|
||||
.c-chat__error {
|
||||
@apply text-sm text-red-600;
|
||||
}
|
||||
|
||||
.c-chat__attachment-container {
|
||||
@apply mt-2 flex items-center;
|
||||
}
|
||||
|
||||
.c-chat__attach-btn {
|
||||
@apply inline-flex cursor-pointer items-center gap-1.5 text-xs text-neutral-500 transition-colors hover:text-foreground;
|
||||
}
|
||||
|
||||
.c-chat__attach-icon {
|
||||
@apply size-3.5;
|
||||
}
|
||||
|
||||
.c-chat__preview-list {
|
||||
@apply mt-2 flex flex-wrap gap-2;
|
||||
}
|
||||
|
||||
.c-chat__preview-item {
|
||||
@apply relative inline-flex items-center gap-2 rounded border border-neutral-200 bg-neutral-100 p-1.5 pr-8 text-xs dark:border-neutral-700 dark:bg-neutral-800;
|
||||
}
|
||||
|
||||
.c-chat__preview-name {
|
||||
@apply max-w-[150px] truncate;
|
||||
}
|
||||
|
||||
.c-chat__preview-remove {
|
||||
@apply absolute top-1.5 right-1.5 cursor-pointer text-[10px] text-neutral-400 hover:text-red-500;
|
||||
}
|
||||
|
||||
.c-chat__submit-box {
|
||||
@apply flex items-center gap-4;
|
||||
}
|
||||
|
||||
.c-chat__button {
|
||||
@apply inline-flex items-center rounded-md border border-transparent bg-gray-800 px-4 py-2 text-xs font-semibold tracking-widest text-white uppercase transition duration-150 ease-in-out hover:bg-gray-700 focus:bg-gray-700 focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 focus:outline-none active:bg-gray-900 dark:bg-gray-200 dark:text-gray-800 dark:hover:bg-white dark:focus:bg-white dark:focus:ring-offset-gray-800 dark:active:bg-gray-300;
|
||||
}
|
||||
|
||||
/* Lightbox Styling */
|
||||
.c-chat__lightbox {
|
||||
@apply fixed inset-0 z-50 flex items-center justify-center bg-black/95 p-4;
|
||||
}
|
||||
|
||||
.c-chat__lightbox-close {
|
||||
@apply absolute top-6 right-6 cursor-pointer text-3xl text-white transition-colors duration-200 hover:text-red-500;
|
||||
}
|
||||
|
||||
.c-chat__lightbox-content {
|
||||
@apply max-h-full max-w-full;
|
||||
}
|
||||
|
||||
.c-chat__lightbox-image {
|
||||
@apply max-h-[90vh] max-w-full rounded object-contain shadow-lg;
|
||||
}
|
||||
|
||||
.c-chat__lightbox-video {
|
||||
@apply max-h-[90vh] max-w-full rounded shadow-lg;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -168,11 +168,15 @@ function submit() {
|
||||
}
|
||||
|
||||
.c-create-ledger-form__card {
|
||||
@apply overflow-hidden bg-white shadow-sm sm:rounded-lg dark:bg-gray-800;
|
||||
@apply overflow-hidden;
|
||||
background-color: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.c-create-ledger-form__body {
|
||||
@apply p-6 text-gray-900 dark:text-gray-100;
|
||||
@apply p-6;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-create-ledger-form__title {
|
||||
@@ -188,19 +192,29 @@ function submit() {
|
||||
}
|
||||
|
||||
.c-create-ledger-form__label {
|
||||
@apply block text-sm font-medium text-gray-700 dark:text-gray-300;
|
||||
@apply block text-sm font-medium;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-create-ledger-form__input {
|
||||
@apply mt-1 block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
@apply mt-1 block w-full rounded-md border shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
border-color: var(--border);
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-create-ledger-form__textarea {
|
||||
@apply mt-1 block w-full rounded-md border border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
@apply mt-1 block w-full rounded-md border shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
border-color: var(--border);
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-create-ledger-form__select {
|
||||
@apply mt-1 block w-full rounded-md border border-gray-300 bg-white p-2 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-300 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
@apply mt-1 block w-full rounded-md border p-2 text-sm shadow-sm focus:border-indigo-500 focus:ring-indigo-500 dark:focus:border-indigo-600 dark:focus:ring-indigo-600;
|
||||
border-color: var(--border);
|
||||
background-color: var(--background);
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-create-ledger-form__file-input {
|
||||
|
||||
@@ -20,27 +20,3 @@ withDefaults(defineProps<Props>(), {
|
||||
</p>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.c-heading {
|
||||
@apply mb-8 space-y-0.5;
|
||||
}
|
||||
|
||||
.c-heading--small {
|
||||
@apply mb-0 space-y-0;
|
||||
}
|
||||
|
||||
.c-heading__title {
|
||||
@apply text-xl font-semibold tracking-tight;
|
||||
}
|
||||
|
||||
.c-heading--small .c-heading__title {
|
||||
@apply mb-0.5 text-base font-medium tracking-normal;
|
||||
}
|
||||
|
||||
.c-heading__description {
|
||||
@apply text-sm text-muted-foreground;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -11,11 +11,3 @@ defineProps<{
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.c-input-error__message {
|
||||
@apply text-sm text-red-600 dark:text-red-500;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -105,7 +105,8 @@ defineProps<{
|
||||
}
|
||||
|
||||
.c-ledger-list__title {
|
||||
@apply text-lg font-medium text-gray-900 dark:text-gray-100;
|
||||
@apply text-lg font-medium;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-ledger-list__grid {
|
||||
@@ -113,15 +114,20 @@ defineProps<{
|
||||
}
|
||||
|
||||
.c-ledger-list__item {
|
||||
@apply border-b border-gray-200 bg-white p-6 dark:border-gray-600 dark:bg-gray-700;
|
||||
@apply p-6;
|
||||
background-color: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
|
||||
.c-ledger-list__item-name {
|
||||
@apply text-lg font-semibold;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-ledger-list__item-score {
|
||||
@apply mt-2 text-sm text-gray-600 dark:text-gray-400;
|
||||
@apply mt-2 text-sm;
|
||||
color: var(--muted-foreground);
|
||||
}
|
||||
|
||||
.c-ledger-list__alignment-wrapper {
|
||||
|
||||
@@ -30,7 +30,8 @@ defineProps<{
|
||||
}
|
||||
|
||||
.c-participants-list__title {
|
||||
@apply text-lg font-medium text-gray-900 dark:text-gray-100;
|
||||
@apply text-lg font-medium;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.c-participants-list__grid {
|
||||
@@ -38,6 +39,10 @@ defineProps<{
|
||||
}
|
||||
|
||||
.c-participants-list__item {
|
||||
@apply overflow-hidden bg-white p-4 shadow-sm sm:rounded-lg dark:bg-gray-800;
|
||||
@apply overflow-hidden p-4;
|
||||
background-color: var(--card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
color: var(--foreground);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -40,23 +40,3 @@ defineExpose({
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.password-input {
|
||||
@apply relative;
|
||||
}
|
||||
|
||||
:deep(.password-input__field) {
|
||||
@apply pr-10;
|
||||
}
|
||||
|
||||
.password-input__toggle {
|
||||
@apply absolute inset-y-0 right-0 flex items-center rounded-r-md px-3 text-muted-foreground hover:text-foreground focus-visible:ring-[3px] focus-visible:ring-ring focus-visible:outline-none;
|
||||
}
|
||||
|
||||
.password-input__icon {
|
||||
@apply size-4;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -23,11 +23,3 @@ defineProps<Props>();
|
||||
<slot />
|
||||
</Link>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.c-text-link {
|
||||
@apply text-foreground underline decoration-neutral-300 underline-offset-4 transition-colors duration-300 ease-out hover:decoration-current! dark:decoration-neutral-500;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -34,23 +34,3 @@ const showAvatar = computed(
|
||||
<span v-if="showEmail" class="user-info__email">{{ user.email }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@reference "../../css/app.css";
|
||||
|
||||
.user-info__avatar {
|
||||
@apply h-8 w-8 overflow-hidden rounded-lg;
|
||||
}
|
||||
|
||||
.user-info__details {
|
||||
@apply grid flex-1 text-left text-sm leading-tight;
|
||||
}
|
||||
|
||||
.user-info__name {
|
||||
@apply truncate font-medium;
|
||||
}
|
||||
|
||||
.user-info__email {
|
||||
@apply truncate text-xs text-muted-foreground;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user