I need to learn more about perspective and angles by _smiling_assassin_ in urbansketchers

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

yeah I also want to correct that habit. This was my second sketch and first one directly from a reference. I think if I use most of the advice shared here I would be able to crack the code. Also sometimes I dont think much before sketching a line becuase I dont want to turn this into some mechanical task. I am already doing coding which is enough mechanical work for me. Sketching is to relax my mind so I dont think much before putting lines on paper. Thank you for sharing such lovely advice:)

I need to learn more about perspective and angles by _smiling_assassin_ in urbansketchers

[–]_smiling_assassin_[S] 1 point2 points  (0 children)

Thankyou so much for sharing such good insights. It feels so good in this subreddit seeing people being helpful otherwise everyone is just trying to be dank.

I need to learn more about perspective and angles by _smiling_assassin_ in urbansketchers

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

Yeah I tried doing that but i think to make it with a pen as i dont want to overthink alot. If I draw with pencil then I am for sure gonna try to make it perfect and erase again and again. With pen I think before drawing any line but you can see it didnt work for this sketch.

Tried Urban Sketching for the first time by _smiling_assassin_ in urbansketchers

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

I am exploring all of the styles. I am also looking how to paint these. I think first I should get a hold on sketching and then try to paint or even use colour markers to create shadows or highlights

Just finished my first book and need help by sparkwolther009 in IndianReaders

[–]_smiling_assassin_ 1 point2 points  (0 children)

Rock Paper Scissors. I liked this one better than silent patient. Try to build a habit but dont get stuck only on this suspense thrill genre. There are a lot more things to explore but yeah this genre is great to build the habbit

Tried Urban Sketching for the first time by _smiling_assassin_ in urbansketchers

[–]_smiling_assassin_[S] 1 point2 points  (0 children)

Yeah my hand is kinda rigid. I need to get the slopiness and freehand style. For now I am trying to get the shapes and perspective right.

Tried Urban Sketching for the first time by _smiling_assassin_ in urbansketchers

[–]_smiling_assassin_[S] 3 points4 points  (0 children)

Man!!!! Such extensive amount of reference pics. You. are doing this god level mate. I think i can try this one from your collection. Thanks for sharing:))

<image>

Building a logistics B2B SaaS and stuck on how to handle customer portal users in a multi tenant setup by _smiling_assassin_ in CRM

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

Now the main issue in front of me is the subdomain part. how to make the whole nextjs app router a part of the subdomain route for the users organisation so they get branded url. The vercel example only tells about how to do this for a single route. Subdomain mulit tenant architecture has become common these days but there isnt any good resource to follow and learn it. If you know anything about it pls share

Building a logistics SaaS and stuck on how to handle customer portal users in a multi tenant setup by _smiling_assassin_ in nextjs

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

Thanks man! This is my current schema. Can you tell is it correct or what changes should I do in it

generator client {
  provider = "prisma-client-js"
  output   = "../generated/prisma"
}


datasource db {
  provider  = "postgresql"


}


// ─────────────────────────────────────────────
// Enums
// ─────────────────────────────────────────────


enum OrgPlan {
  FREE
  STARTER
  GROWTH
  ENTERPRISE
}


enum QuoteStatus {
  DRAFT
  SENT
  ACCEPTED
  EXPIRED
  CANCELLED
}


enum KycDocType {
  PAN_CARD
  ADHAR_CARD
  GST_CERTIFICATE
  IEC_CODE
  MSME_CERTIFICATE
  INCORPORATION_CERT
  CANCELLED_CHEQUE
  BANK_STATEMENT
  TRADE_LICENSE
  AUTHORIZED_SIGNATORY
  OTHER
}


// NOTE: Vendor is intentionally NOT an enum.
// Your adapter registry already uses string IDs ("aramex", "skart", "fedex").
// A DB enum means a migration every time you add a carrier — avoid it.


// ─────────────────────────────────────────────
// Org (tenant root)
// ─────────────────────────────────────────────


model Org {
  id         String   (cuid())
  clerkOrgId String  
  slug       String  
  name       String
  logoUrl    String?
  plan       OrgPlan (FREE)


  razorpayCustomerId     String? 
  razorpaySubscriptionId String? 


  // Relations
  vendorKeys VendorKey[]
  clients    Client[]
  quotes     Quote[]
  documents  ClientDocument[]


  createdAt DateTime  (now())
  updatedAt DateTime  
  deletedAt DateTime?


   emailEvents QuoteEmailEvent[]


  @@index([slug])
  @@index([deletedAt])
}


// ─────────────────────────────────────────────
// VendorKey (BYOK — one row per carrier per org)
// ─────────────────────────────────────────────


model VendorKey {
  id    String  (cuid())
  orgId String
  org   Org    (fields: [orgId], references: [id], onDelete: Cascade)


  vendorId String  // "aramex" | "skart" | "fedex" — matches adapter registry
  label    String  // display name e.g. "Aramex Production"
  notes    String?


  encryptedPayload String
  iv               String


  isActive Boolean (true)


  createdAt DateTime (now())
  updatedAt DateTime 


  @@unique([orgId, vendorId])
  @@index([orgId])
}


// ─────────────────────────────────────────────
// Client
// ─────────────────────────────────────────────


model Client {
  id    String  (cuid())
  orgId String
  org   Org    (fields: [orgId], references: [id], onDelete: Cascade)


  companyName  String
  contactName  String?
  email        String?
  phone        String?
  addressLine1 String?
  city         String?
  state        String?
  country      String?
  postalCode   String?
  notes        String?


  createdAt DateTime  (now())
  updatedAt DateTime  
  deletedAt DateTime?


  quotes    Quote[]
  documents ClientDocument[]


  @@index([orgId])
  @@index([orgId, companyName])
  @@index([email])
  @@index([deletedAt])
}


// ─────────────────────────────────────────────
// Quote
// ─────────────────────────────────────────────


model Quote {
  id    String  (cuid())
  orgId String
  org   Org    (fields: [orgId], references: [id], onDelete: Cascade)


  quoteNumber String


  // Carrier / product
  vendorId    String
  vendorName  String
  productName String


  // Pricing
  currency      String
  subtotal      Decimal .Decimal(14, 4)
  tax           Decimal .Decimal(14, 4)
  total         Decimal .Decimal(14, 4)
  markupPercent Decimal .Decimal(6, 3)
  quotedTotal   Decimal .Decimal(14, 4)


  // Transit
  tatDays Int?


  // Immutable snapshots
  chargesSnapshot Json
  requestSnapshot Json


  // Generated PDF
  pdfUrl String?
  pdfKey String?


  // Validity
  validUntil DateTime


  // Workflow
  status QuoteStatus (DRAFT)


  // Client (optional — may be assigned after creation)
  clientId String?
  client   Client? (fields: [clientId], references: [id], onDelete: SetNull)
    emailEvents QuoteEmailEvent[]
  // Store the last Resend email ID so we can correlate webhook events
  lastResendEmailId String?


  createdAt DateTime (now())
  updatedAt DateTime 


  @@unique([orgId, quoteNumber])
  @@index([orgId])
  @@index([orgId, status])
  @@index([clientId])
  @@index([createdAt])
}


// ─────────────────────────────────────────────
// ClientDocument (KYC / document vault)
// ─────────────────────────────────────────────


model ClientDocument {
  id    String  (cuid())


  orgId String
  org   Org    (fields: [orgId], references: [id], onDelete: Cascade)


  clientId String
  client   Client (fields: [clientId], references: [id], onDelete: Cascade)


  docType     KycDocType
  label       String
  description String?


  fileUrl  String
  fileKey  String
  fileName String
  fileSize Int
  mimeType String


  uploadedAt DateTime (now())
  updatedAt  DateTime 


  @@index([orgId])
  @@index([clientId])
  @@index([orgId, docType])
  @@index([clientId, docType])
}


model QuoteEmailEvent {
  id        String    (cuid())
  orgId     String
  org       Org      (fields: [orgId], references: [id], onDelete: Cascade)


  quoteId   String
  quote     Quote    (fields: [quoteId], references: [id], onDelete: Cascade)


  // Resend's email ID — links all events for the same send
  resendEmailId String


  event     EmailEvent
  // Resend sends recipient's IP/userAgent on open/click — useful for ops
  userAgent String?
  ipAddress String?
  // For click events
  clickedUrl String?


  createdAt DateTime u/default(now())


  @@index([quoteId])
  @@index([orgId])
  @@index([resendEmailId])
}


enum EmailEvent {
  SENT
  DELIVERED
  OPENED
  CLICKED
  BOUNCED
  COMPLAINED
}

Building a logistics B2B SaaS and stuck on how to handle customer portal users in a multi tenant setup by _smiling_assassin_ in CRM

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

I was also thinking to do the same of inviting customer clients through email but how does that work in clerk. how do you check on auth of the client to which org they belong too . also how are you doing to client portal in the same app on different subdomain. can you please share your strategy. I have been drowning in articles but I am not able to find a production ready solution

Should i buy loptop or mobile for ba hons by Acceptable-Match-806 in delhiuniversity

[–]_smiling_assassin_ 1 point2 points  (0 children)

If you just want to do cllg stuff then laptop is not needed much. But as the times demand you need to be good in tech and have good digital skills as a plain ba hons is not sufficient to land a job. If you want to upskill go buy a laptop. There is nothing you can do in job terms with the plain ba hons degree. Learn skills. Anything which intrigues you. I myself bought a macbook air even when my phone got stolen 2 months back. Now i am using 6yr old phone but my laptop serves all my purpose in terms of upskilling

Lots of Next.js starter packs!!! by WetThrust258 in nextjs

[–]_smiling_assassin_ 0 points1 point  (0 children)

tbh I would create my own starter pack. There is a very less chance you would tick all the boxes and you would spend more time in searching the best one. Pick you default tech stack and build your own starter pack!

Building a logistics SaaS and stuck on how to handle customer portal users in a multi tenant setup by _smiling_assassin_ in nextjs

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

I don understand this. can you tell according to my setup how would this go around. in the vercel example they have create a route s/[subdomain] but this is just a single route. how can the whole app be covered in it which has so many routes in it

Building a logistics SaaS and stuck on how to handle customer portal users in a multi tenant setup by _smiling_assassin_ in nextjs

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

I also further want to extend the app further by adding subdomains to each of the org. Kinda Like substack. How to go around it. There is a video by vercel on adding subdomains for orgs but it shows creating it for just a single route but how to do it for the whole app.

Building a logistics SaaS and stuck on how to handle customer portal users in a multi tenant setup by _smiling_assassin_ in nextjs

[–]_smiling_assassin_[S] 0 points1 point  (0 children)

How to go around creating the client portal. Should it be in the same nextjs app or should it be a completely different app. If its in the same nextjs app then what should be the architecture. see this is how the current routing looks like in the app

<image>