fix build
This commit is contained in:
@@ -104,8 +104,9 @@ export function PropertyGrid({
|
|||||||
|
|
||||||
if (result.success && result.data) {
|
if (result.success && result.data) {
|
||||||
// Update with actual values from server
|
// Update with actual values from server
|
||||||
setUserLikes((prev) => ({ ...prev, [propertyId]: result.data.liked }))
|
const data = result.data
|
||||||
setLikeCounts((prev) => ({ ...prev, [propertyId]: result.data.likes }))
|
setUserLikes((prev) => ({ ...prev, [propertyId]: data.liked }))
|
||||||
|
setLikeCounts((prev) => ({ ...prev, [propertyId]: data.likes }))
|
||||||
} else {
|
} else {
|
||||||
// Revert on error
|
// Revert on error
|
||||||
setUserLikes((prev) => ({ ...prev, [propertyId]: wasLiked }))
|
setUserLikes((prev) => ({ ...prev, [propertyId]: wasLiked }))
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { initSpatialGridSync, useScene } from '@pascal-app/core'
|
import { type AnyNodeId, initSpatialGridSync, useScene } from '@pascal-app/core'
|
||||||
import { useViewer } from '@pascal-app/viewer'
|
import { useViewer } from '@pascal-app/viewer'
|
||||||
import { useEffect, useRef } from 'react'
|
import { useEffect, useRef } from 'react'
|
||||||
import useEditor from '@/store/use-editor'
|
import useEditor from '@/store/use-editor'
|
||||||
@@ -32,7 +32,7 @@ export function useLocalPropertyScene(propertyId?: string) {
|
|||||||
|
|
||||||
if (property?.scene_graph) {
|
if (property?.scene_graph) {
|
||||||
const { nodes, rootNodeIds } = property.scene_graph
|
const { nodes, rootNodeIds } = property.scene_graph
|
||||||
useScene.getState().setScene(nodes, rootNodeIds)
|
useScene.getState().setScene(nodes, rootNodeIds as AnyNodeId[])
|
||||||
initSpatialGridSync()
|
initSpatialGridSync()
|
||||||
} else {
|
} else {
|
||||||
useScene.getState().clearScene()
|
useScene.getState().clearScene()
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
import { createServerSupabaseClient } from '../database/server'
|
import { createServerSupabaseClient } from '../database/server'
|
||||||
import { getSession } from '../auth/server'
|
import { getSession } from '../auth/server'
|
||||||
import { createId } from '../utils/id-generator'
|
import { createId } from '../utils/id-generator'
|
||||||
import type { CreatePropertyParams, Property } from './types'
|
import type { CreatePropertyParams, Property, Database } from './types'
|
||||||
|
|
||||||
export type ActionResult<T = unknown> = {
|
export type ActionResult<T = unknown> = {
|
||||||
success: boolean
|
success: boolean
|
||||||
@@ -249,7 +249,7 @@ export async function createProperty(params: CreatePropertyParams): Promise<Acti
|
|||||||
property_id: propertyId,
|
property_id: propertyId,
|
||||||
version: 1,
|
version: 1,
|
||||||
scene_graph: params.sceneGraph,
|
scene_graph: params.sceneGraph,
|
||||||
})
|
} as any)
|
||||||
|
|
||||||
if (modelError) {
|
if (modelError) {
|
||||||
console.error('Failed to create model:', modelError)
|
console.error('Failed to create model:', modelError)
|
||||||
@@ -408,20 +408,21 @@ export async function getPropertyModelPublic(propertyId: string): Promise<
|
|||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Property not found',
|
error: 'Property not found',
|
||||||
data: null,
|
data: undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if user can view this property
|
// Check if user can view this property
|
||||||
// Allow if: property is public OR user owns it
|
// Allow if: property is public OR user owns it
|
||||||
const isOwner = session?.user && property.owner_id === session.user.id
|
const propertyData = property as any
|
||||||
const isPublic = property.is_private === false
|
const isOwner = session?.user && propertyData.owner_id === session.user.id
|
||||||
|
const isPublic = propertyData.is_private === false
|
||||||
|
|
||||||
if (!isPublic && !isOwner) {
|
if (!isPublic && !isOwner) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Property is private',
|
error: 'Property is private',
|
||||||
data: null,
|
data: undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,7 +439,7 @@ export async function getPropertyModelPublic(propertyId: string): Promise<
|
|||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: {
|
data: {
|
||||||
property: property as Property,
|
property: propertyData as Property,
|
||||||
model: model || null,
|
model: model || null,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -446,7 +447,7 @@ export async function getPropertyModelPublic(propertyId: string): Promise<
|
|||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: error instanceof Error ? error.message : 'Failed to fetch property',
|
error: error instanceof Error ? error.message : 'Failed to fetch property',
|
||||||
data: null,
|
data: undefined,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -460,7 +461,7 @@ export async function incrementPropertyViews(propertyId: string): Promise<Action
|
|||||||
|
|
||||||
const { error } = await supabase.rpc('increment_property_views', {
|
const { error } = await supabase.rpc('increment_property_views', {
|
||||||
property_id: propertyId,
|
property_id: propertyId,
|
||||||
})
|
} as any)
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('Failed to increment views:', error)
|
console.error('Failed to increment views:', error)
|
||||||
@@ -500,7 +501,7 @@ export async function updatePropertyPrivacy(
|
|||||||
.eq('id', propertyId)
|
.eq('id', propertyId)
|
||||||
.single()
|
.single()
|
||||||
|
|
||||||
if (property?.owner_id !== session.user.id) {
|
if ((property as any)?.owner_id !== session.user.id) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
@@ -508,8 +509,8 @@ export async function updatePropertyPrivacy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update privacy
|
// Update privacy
|
||||||
const { error } = await supabase
|
const { error } = await (supabase
|
||||||
.from('properties')
|
.from('properties') as any)
|
||||||
.update({ is_private: isPrivate })
|
.update({ is_private: isPrivate })
|
||||||
.eq('id', propertyId)
|
.eq('id', propertyId)
|
||||||
|
|
||||||
@@ -572,7 +573,7 @@ export async function updatePropertyAddress(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.owner_id !== session.user.id) {
|
if ((property as any).owner_id !== session.user.id) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
@@ -580,10 +581,10 @@ export async function updatePropertyAddress(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update address
|
// Update address
|
||||||
const { error } = await supabase
|
const { error } = await (supabase
|
||||||
.from('properties_addresses')
|
.from('properties_addresses') as any)
|
||||||
.update(addressData)
|
.update(addressData)
|
||||||
.eq('id', property.address_id)
|
.eq('id', (property as any).address_id)
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return {
|
return {
|
||||||
@@ -628,7 +629,7 @@ export async function migrateLocalProperty(
|
|||||||
|
|
||||||
// Create a default address (user can edit later via settings)
|
// Create a default address (user can edit later via settings)
|
||||||
const addressId = createId('address')
|
const addressId = createId('address')
|
||||||
const { error: addressError } = await supabase.from('properties_addresses').insert({
|
const { error: addressError } = await (supabase.from('properties_addresses') as any).insert({
|
||||||
id: addressId,
|
id: addressId,
|
||||||
country: 'US',
|
country: 'US',
|
||||||
})
|
})
|
||||||
@@ -642,7 +643,7 @@ export async function migrateLocalProperty(
|
|||||||
|
|
||||||
// Create the property
|
// Create the property
|
||||||
const propertyId = createId('property')
|
const propertyId = createId('property')
|
||||||
const { error: propertyError } = await supabase.from('properties').insert({
|
const { error: propertyError } = await (supabase.from('properties') as any).insert({
|
||||||
id: propertyId,
|
id: propertyId,
|
||||||
name: localProperty.name,
|
name: localProperty.name,
|
||||||
owner_id: session.user.id,
|
owner_id: session.user.id,
|
||||||
@@ -660,7 +661,7 @@ export async function migrateLocalProperty(
|
|||||||
// Create the model with the scene graph
|
// Create the model with the scene graph
|
||||||
if (localProperty.scene_graph) {
|
if (localProperty.scene_graph) {
|
||||||
const modelId = createId('model')
|
const modelId = createId('model')
|
||||||
const { error: modelError } = await supabase.from('properties_models').insert({
|
const { error: modelError } = await (supabase.from('properties_models') as any).insert({
|
||||||
id: modelId,
|
id: modelId,
|
||||||
property_id: propertyId,
|
property_id: propertyId,
|
||||||
version: 1,
|
version: 1,
|
||||||
@@ -719,7 +720,7 @@ export async function deleteProperty(propertyId: string): Promise<ActionResult>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (property.owner_id !== session.user.id) {
|
if ((property as any).owner_id !== session.user.id) {
|
||||||
return {
|
return {
|
||||||
success: false,
|
success: false,
|
||||||
error: 'Unauthorized',
|
error: 'Unauthorized',
|
||||||
@@ -785,7 +786,7 @@ export async function getUserPropertyLikes(
|
|||||||
// Convert array to map
|
// Convert array to map
|
||||||
const likeMap: Record<string, boolean> = {}
|
const likeMap: Record<string, boolean> = {}
|
||||||
propertyIds.forEach((id) => {
|
propertyIds.forEach((id) => {
|
||||||
likeMap[id] = likes?.some((like) => like.property_id === id) || false
|
likeMap[id] = likes?.some((like) => (like as any).property_id === id) || false
|
||||||
})
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -833,10 +834,10 @@ export async function togglePropertyLike(
|
|||||||
|
|
||||||
if (existingLike) {
|
if (existingLike) {
|
||||||
// Unlike - remove the like
|
// Unlike - remove the like
|
||||||
const { error } = await supabase
|
const { error } = await (supabase
|
||||||
.from('property_likes')
|
.from('property_likes') as any)
|
||||||
.delete()
|
.delete()
|
||||||
.eq('id', existingLike.id)
|
.eq('id', (existingLike as any).id)
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return {
|
return {
|
||||||
@@ -849,7 +850,7 @@ export async function togglePropertyLike(
|
|||||||
} else {
|
} else {
|
||||||
// Like - add a new like
|
// Like - add a new like
|
||||||
const likeId = createId('like')
|
const likeId = createId('like')
|
||||||
const { error } = await supabase.from('property_likes').insert({
|
const { error } = await (supabase.from('property_likes') as any).insert({
|
||||||
id: likeId,
|
id: likeId,
|
||||||
property_id: propertyId,
|
property_id: propertyId,
|
||||||
user_id: userId,
|
user_id: userId,
|
||||||
@@ -868,11 +869,11 @@ export async function togglePropertyLike(
|
|||||||
// Get updated like count
|
// Get updated like count
|
||||||
const { data: likeCount } = await supabase.rpc('get_property_like_count', {
|
const { data: likeCount } = await supabase.rpc('get_property_like_count', {
|
||||||
property_id: propertyId,
|
property_id: propertyId,
|
||||||
})
|
} as any)
|
||||||
|
|
||||||
// Update the property's like count cache
|
// Update the property's like count cache
|
||||||
await supabase
|
await (supabase
|
||||||
.from('properties')
|
.from('properties') as any)
|
||||||
.update({ likes: likeCount || 0 })
|
.update({ likes: likeCount || 0 })
|
||||||
.eq('id', propertyId)
|
.eq('id', propertyId)
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,90 @@
|
|||||||
* Isolated from monorepo database schema
|
* Isolated from monorepo database schema
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Database table row types
|
||||||
|
export type DbProperty = {
|
||||||
|
id: string
|
||||||
|
name: string
|
||||||
|
owner_id: string
|
||||||
|
organization_id: string | null
|
||||||
|
address_id: string
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
is_private: boolean
|
||||||
|
views: number
|
||||||
|
likes: number
|
||||||
|
thumbnail_url: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DbPropertyAddress = {
|
||||||
|
id: string
|
||||||
|
street_number?: string
|
||||||
|
route?: string
|
||||||
|
city?: string
|
||||||
|
state?: string
|
||||||
|
postal_code?: string
|
||||||
|
country?: string
|
||||||
|
latitude?: string
|
||||||
|
longitude?: string
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DbPropertyModel = {
|
||||||
|
id: string
|
||||||
|
property_id: string
|
||||||
|
version: number
|
||||||
|
scene_graph: any
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
deleted_at: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DbPropertyLike = {
|
||||||
|
id: string
|
||||||
|
property_id: string
|
||||||
|
user_id: string
|
||||||
|
created_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Database schema type for Supabase
|
||||||
|
export type Database = {
|
||||||
|
public: {
|
||||||
|
Tables: {
|
||||||
|
properties: {
|
||||||
|
Row: DbProperty
|
||||||
|
Insert: Omit<DbProperty, 'created_at' | 'updated_at' | 'views' | 'likes'>
|
||||||
|
Update: Partial<Omit<DbProperty, 'id' | 'created_at' | 'updated_at'>>
|
||||||
|
}
|
||||||
|
properties_addresses: {
|
||||||
|
Row: DbPropertyAddress
|
||||||
|
Insert: Omit<DbPropertyAddress, 'created_at' | 'updated_at'>
|
||||||
|
Update: Partial<Omit<DbPropertyAddress, 'id' | 'created_at' | 'updated_at'>>
|
||||||
|
}
|
||||||
|
properties_models: {
|
||||||
|
Row: DbPropertyModel
|
||||||
|
Insert: Omit<DbPropertyModel, 'created_at' | 'updated_at' | 'deleted_at'>
|
||||||
|
Update: Partial<Omit<DbPropertyModel, 'id' | 'created_at' | 'updated_at'>>
|
||||||
|
}
|
||||||
|
property_likes: {
|
||||||
|
Row: DbPropertyLike
|
||||||
|
Insert: Omit<DbPropertyLike, 'created_at'>
|
||||||
|
Update: Partial<Omit<DbPropertyLike, 'id' | 'created_at'>>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Functions: {
|
||||||
|
increment_property_views: {
|
||||||
|
Args: { property_id: string }
|
||||||
|
Returns: undefined
|
||||||
|
}
|
||||||
|
get_property_like_count: {
|
||||||
|
Args: { property_id: string }
|
||||||
|
Returns: number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type Property = {
|
export type Property = {
|
||||||
id: string
|
id: string
|
||||||
name: string
|
name: string
|
||||||
|
|||||||
Reference in New Issue
Block a user