@salesforce/webapp-template-app-react-sample-b2x-experimental 1.36.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/LICENSE.txt +82 -0
  2. package/dist/.a4drules/build-validation.md +81 -0
  3. package/dist/.a4drules/code-quality.md +150 -0
  4. package/dist/.a4drules/graphql/tools/knowledge/lds-explore-graphql-schema.md +227 -0
  5. package/dist/.a4drules/graphql/tools/knowledge/lds-generate-graphql-mutationquery.md +212 -0
  6. package/dist/.a4drules/graphql/tools/knowledge/lds-generate-graphql-readquery.md +185 -0
  7. package/dist/.a4drules/graphql/tools/knowledge/lds-guide-graphql.md +205 -0
  8. package/dist/.a4drules/graphql/tools/schemas/shared.graphqls +1150 -0
  9. package/dist/.a4drules/graphql.md +408 -0
  10. package/dist/.a4drules/images.md +13 -0
  11. package/dist/.a4drules/react.md +361 -0
  12. package/dist/.a4drules/react_image_processing.md +45 -0
  13. package/dist/.a4drules/skills/install-feature/SKILL.md +67 -0
  14. package/dist/.a4drules/skills/install-feature/scripts/copy-feature-assets.sh +36 -0
  15. package/dist/.a4drules/typescript.md +224 -0
  16. package/dist/.forceignore +15 -0
  17. package/dist/.husky/pre-commit +4 -0
  18. package/dist/.prettierignore +11 -0
  19. package/dist/.prettierrc +17 -0
  20. package/dist/CHANGELOG.md +533 -0
  21. package/dist/README.md +18 -0
  22. package/dist/config/project-scratch-def.json +13 -0
  23. package/dist/force-app/main/default/digitalExperienceConfigs/appreactsampleb2x1.digitalExperienceConfig +8 -0
  24. package/dist/force-app/main/default/digitalExperiences/site/appreactsampleb2x1/appreactsampleb2x1.digitalExperience-meta.xml +11 -0
  25. package/dist/force-app/main/default/digitalExperiences/site/appreactsampleb2x1/sfdc_cms__site/appreactsampleb2x1/_meta.json +5 -0
  26. package/dist/force-app/main/default/digitalExperiences/site/appreactsampleb2x1/sfdc_cms__site/appreactsampleb2x1/content.json +10 -0
  27. package/dist/force-app/main/default/networks/appreactsampleb2x.network +60 -0
  28. package/dist/force-app/main/default/package.xml +20 -0
  29. package/dist/force-app/main/default/sites/appreactsampleb2x.site +31 -0
  30. package/dist/force-app/main/default/webapplications/appreactsampleb2x/.graphqlrc.yml +2 -0
  31. package/dist/force-app/main/default/webapplications/appreactsampleb2x/.prettierignore +9 -0
  32. package/dist/force-app/main/default/webapplications/appreactsampleb2x/.prettierrc +11 -0
  33. package/dist/force-app/main/default/webapplications/appreactsampleb2x/appreactsampleb2x.webapplication-meta.xml +7 -0
  34. package/dist/force-app/main/default/webapplications/appreactsampleb2x/build/vite.config.d.ts +2 -0
  35. package/dist/force-app/main/default/webapplications/appreactsampleb2x/build/vite.config.js +94 -0
  36. package/dist/force-app/main/default/webapplications/appreactsampleb2x/codegen.yml +12 -0
  37. package/dist/force-app/main/default/webapplications/appreactsampleb2x/e2e/app.spec.ts +24 -0
  38. package/dist/force-app/main/default/webapplications/appreactsampleb2x/eslint.config.js +141 -0
  39. package/dist/force-app/main/default/webapplications/appreactsampleb2x/index.html +13 -0
  40. package/dist/force-app/main/default/webapplications/appreactsampleb2x/package-lock.json +12805 -0
  41. package/dist/force-app/main/default/webapplications/appreactsampleb2x/package.json +57 -0
  42. package/dist/force-app/main/default/webapplications/appreactsampleb2x/playwright.config.ts +24 -0
  43. package/dist/force-app/main/default/webapplications/appreactsampleb2x/scripts/get-graphql-schema.mjs +68 -0
  44. package/dist/force-app/main/default/webapplications/appreactsampleb2x/scripts/rewrite-e2e-assets.mjs +23 -0
  45. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/graphql-operations-types.ts +129 -0
  46. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/utils/accounts.ts +33 -0
  47. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/api/utils/query/highRevenueAccountsQuery.graphql +29 -0
  48. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/app.tsx +41 -0
  49. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/appLayout.tsx +161 -0
  50. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/book.svg +3 -0
  51. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/copy.svg +4 -0
  52. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/rocket.svg +3 -0
  53. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/icons/star.svg +3 -0
  54. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/images/codey-1.png +0 -0
  55. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/images/codey-2.png +0 -0
  56. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/images/codey-3.png +0 -0
  57. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/assets/images/vibe-codey.svg +194 -0
  58. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/alert.tsx +65 -0
  59. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/button.tsx +54 -0
  60. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/card.tsx +77 -0
  61. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/field.tsx +111 -0
  62. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/index.ts +71 -0
  63. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/input.tsx +19 -0
  64. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/label.tsx +19 -0
  65. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/pagination.tsx +99 -0
  66. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/select.tsx +151 -0
  67. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/skeleton.tsx +7 -0
  68. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/spinner.tsx +26 -0
  69. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/table.tsx +114 -0
  70. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/components/ui/tabs.tsx +115 -0
  71. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/lib/utils.ts +6 -0
  72. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/About.tsx +8 -0
  73. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Application.tsx +101 -0
  74. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Dashboard.tsx +101 -0
  75. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/HelpCenter.tsx +29 -0
  76. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Home.tsx +30 -0
  77. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/Maintenance.tsx +132 -0
  78. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/NotFound.tsx +14 -0
  79. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertyDetails.tsx +68 -0
  80. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/pages/PropertyListings.tsx +84 -0
  81. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/routes.tsx +62 -0
  82. package/dist/force-app/main/default/webapplications/appreactsampleb2x/src/styles/global.css +80 -0
  83. package/dist/force-app/main/default/webapplications/appreactsampleb2x/tsconfig.json +36 -0
  84. package/dist/force-app/main/default/webapplications/appreactsampleb2x/tsconfig.node.json +13 -0
  85. package/dist/force-app/main/default/webapplications/appreactsampleb2x/vite-env.d.ts +1 -0
  86. package/dist/force-app/main/default/webapplications/appreactsampleb2x/vite.config.ts +102 -0
  87. package/dist/force-app/main/default/webapplications/appreactsampleb2x/vitest-env.d.ts +2 -0
  88. package/dist/force-app/main/default/webapplications/appreactsampleb2x/vitest.config.ts +11 -0
  89. package/dist/force-app/main/default/webapplications/appreactsampleb2x/vitest.setup.ts +1 -0
  90. package/dist/force-app/main/default/webapplications/appreactsampleb2x/webapplication.json +7 -0
  91. package/dist/jest.config.js +6 -0
  92. package/dist/package.json +38 -0
  93. package/dist/scripts/apex/hello.apex +10 -0
  94. package/dist/scripts/soql/account.soql +6 -0
  95. package/dist/sfdx-project.json +12 -0
  96. package/package.json +28 -0
@@ -0,0 +1,101 @@
1
+ import { Link } from "react-router";
2
+ import { Button } from "../components/ui/button";
3
+ import { Input } from "../components/ui/input";
4
+ import { Label } from "../components/ui/label";
5
+ import { Card, CardHeader, CardTitle, CardContent } from "../components/ui/card";
6
+ import { Tabs, TabsList, TabsTrigger, TabsContent } from "../components/ui/tabs";
7
+
8
+ export default function Application() {
9
+ return (
10
+ <div className="mx-auto max-w-[800px]">
11
+ <Card className="mb-6 flex gap-4 p-6">
12
+ <div className="size-[200px] shrink-0 rounded-xl bg-muted" />
13
+ <div className="min-w-0 flex-1">
14
+ <h2 className="mb-1 text-lg font-semibold text-primary">Verdana Apartments</h2>
15
+ <p className="text-sm text-muted-foreground">301 Bryant St, San Francisco, CA 94107</p>
16
+ <p className="mt-2 text-sm text-muted-foreground">
17
+ I have read and agree to the Terms & Conditions.
18
+ </p>
19
+ </div>
20
+ <div className="flex gap-2">
21
+ <Button variant="outline" size="sm">
22
+ Cancel Application
23
+ </Button>
24
+ <Button size="sm">Save for Later</Button>
25
+ </div>
26
+ </Card>
27
+ <Tabs defaultValue="applicants" className="mb-6">
28
+ <TabsList className="mb-4 flex h-auto flex-wrap gap-4 border-b border-border bg-transparent p-0">
29
+ <TabsTrigger
30
+ value="applicants"
31
+ className="rounded-none border-b-2 border-primary bg-transparent px-0 pb-1 data-[state=active]:shadow-none"
32
+ >
33
+ APPLICANTS & OCCUPANTS
34
+ </TabsTrigger>
35
+ <TabsTrigger
36
+ value="details"
37
+ className="rounded-none border-b-0 bg-transparent px-0 pb-1 text-muted-foreground data-[state=active]:shadow-none"
38
+ >
39
+ YOUR DETAILS
40
+ </TabsTrigger>
41
+ <TabsTrigger
42
+ value="screening"
43
+ className="rounded-none border-b-0 bg-transparent px-0 pb-1 text-muted-foreground data-[state=active]:shadow-none"
44
+ >
45
+ SCREENING
46
+ </TabsTrigger>
47
+ <TabsTrigger
48
+ value="submit"
49
+ className="rounded-none border-b-0 bg-transparent px-0 pb-1 text-muted-foreground data-[state=active]:shadow-none"
50
+ >
51
+ FINISH & SUBMIT
52
+ </TabsTrigger>
53
+ </TabsList>
54
+ <TabsContent value="applicants" className="mt-0" />
55
+ </Tabs>
56
+ <Card>
57
+ <CardContent className="pt-6">
58
+ <h3 className="mb-4 text-xs font-semibold uppercase tracking-wider text-foreground">
59
+ YOUR INFO
60
+ </h3>
61
+ <div className="mb-4 grid grid-cols-1 gap-4 md:grid-cols-2">
62
+ <div className="space-y-2">
63
+ <Label>First Name *</Label>
64
+ <Input type="text" defaultValue="Sarah" />
65
+ </div>
66
+ <div className="space-y-2">
67
+ <Label>Last Name</Label>
68
+ <Input type="text" />
69
+ </div>
70
+ </div>
71
+ <div className="mb-4 space-y-2">
72
+ <Label>Email Address</Label>
73
+ <Input type="email" />
74
+ </div>
75
+ <div className="mb-4 space-y-2">
76
+ <Label>Phone Number</Label>
77
+ <Input type="tel" />
78
+ </div>
79
+ <h3 className="mb-4 mt-6 text-xs font-semibold uppercase tracking-wider text-foreground">
80
+ MOVE IN
81
+ </h3>
82
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
83
+ <div className="space-y-2">
84
+ <Label>MOVE IN DATE</Label>
85
+ <Input type="text" placeholder="Select Date" />
86
+ </div>
87
+ <div className="space-y-2">
88
+ <Label>PREFERRED TERM</Label>
89
+ <select className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs outline-none focus-visible:ring-2 focus-visible:ring-ring">
90
+ <option>Select One</option>
91
+ <option>1 month</option>
92
+ <option>6 months</option>
93
+ <option>12 months</option>
94
+ </select>
95
+ </div>
96
+ </div>
97
+ </CardContent>
98
+ </Card>
99
+ </div>
100
+ );
101
+ }
@@ -0,0 +1,101 @@
1
+ import { Button } from "../components/ui/button";
2
+ import {
3
+ Card,
4
+ CardHeader,
5
+ CardTitle,
6
+ CardContent,
7
+ CardFooter,
8
+ } from "../components/ui/card";
9
+ import { Link } from "react-router";
10
+
11
+ export default function Dashboard() {
12
+ return (
13
+ <div className="mx-auto grid max-w-[1100px] grid-cols-1 gap-6 md:grid-cols-2">
14
+ <div className="space-y-6">
15
+ <Card>
16
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
17
+ <CardTitle className="text-base text-primary">Community News</CardTitle>
18
+ </CardHeader>
19
+ <CardContent className="space-y-2">
20
+ <h3 className="text-lg font-semibold text-gray-700">
21
+ Sip & Skyline: Rooftop Wine Tasting Mixer
22
+ </h3>
23
+ <p className="text-sm text-muted-foreground">Thursday, January 22nd, at 6:30 PM</p>
24
+ <p className="text-sm leading-relaxed text-foreground">
25
+ We're partnering with local favorite Mission Cellars to bring you a curated selection
26
+ of Bay Area wines paired with artisanal charcuterie.
27
+ </p>
28
+ <div className="mt-4 h-36 rounded-xl bg-muted" aria-hidden />
29
+ </CardContent>
30
+ </Card>
31
+ <Card>
32
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
33
+ <CardTitle className="text-base text-primary">Maintenance</CardTitle>
34
+ <Button size="sm">+ New Request</Button>
35
+ </CardHeader>
36
+ <CardContent className="space-y-4">
37
+ <div className="flex items-start gap-4 border-b border-border py-3">
38
+ <div className="size-14 shrink-0 rounded-lg bg-muted" />
39
+ <div className="min-w-0 flex-1">
40
+ <p className="font-semibold text-foreground">Heater Broken</p>
41
+ <p className="text-xs text-muted-foreground">Submitted Mar 23, 2026.</p>
42
+ <div className="my-2 h-1.5 overflow-hidden rounded-full bg-muted">
43
+ <div className="h-full w-1/4 rounded-full bg-primary" aria-hidden />
44
+ </div>
45
+ <p className="text-xs text-primary">25% In Progress</p>
46
+ </div>
47
+ </div>
48
+ <div className="flex items-start gap-4 py-3">
49
+ <div className="size-14 shrink-0 rounded-lg bg-muted" />
50
+ <div className="min-w-0 flex-1">
51
+ <p className="font-semibold text-foreground">Replace Shower Head</p>
52
+ <p className="text-xs text-muted-foreground">Completed Nov 17, 2025.</p>
53
+ <div className="my-2 h-1.5 overflow-hidden rounded-full bg-muted">
54
+ <div className="h-full w-full rounded-full bg-primary" aria-hidden />
55
+ </div>
56
+ <p className="text-xs text-green-600">100% Completed</p>
57
+ </div>
58
+ </div>
59
+ </CardContent>
60
+ <CardFooter className="justify-end pt-2">
61
+ <Link to="/maintenance" className="text-sm font-medium text-primary hover:underline">
62
+ See All
63
+ </Link>
64
+ </CardFooter>
65
+ </Card>
66
+ </div>
67
+ <div>
68
+ <Card>
69
+ <CardHeader>
70
+ <CardTitle className="text-primary">Weather</CardTitle>
71
+ <p className="text-sm text-muted-foreground">26 March 2026</p>
72
+ </CardHeader>
73
+ <CardContent className="space-y-4">
74
+ <p className="text-base text-foreground">Cloudy</p>
75
+ <p className="text-4xl font-bold text-foreground">72°F</p>
76
+ <div className="flex flex-wrap gap-4 text-sm text-muted-foreground">
77
+ <span>10 m/s Wind</span>
78
+ <span>98% Humidity</span>
79
+ <span>100% Rain</span>
80
+ </div>
81
+ <div className="flex gap-2 border-b border-border pb-2">
82
+ <span className="border-b-2 border-primary pb-1 text-sm font-semibold text-primary">
83
+ Today
84
+ </span>
85
+ <span className="text-sm text-muted-foreground">Tomorrow</span>
86
+ <span className="text-sm text-muted-foreground">Next 3 Days</span>
87
+ </div>
88
+ <div className="flex flex-wrap gap-4">
89
+ {["10 am", "11 am", "12 pm", "01 pm"].map((t, i) => (
90
+ <div key={t} className="min-w-[60px] rounded-lg bg-muted/50 p-2 text-center">
91
+ <p className="text-xs text-muted-foreground">{t}</p>
92
+ <p className="text-base font-semibold text-foreground">{72 - i}°</p>
93
+ </div>
94
+ ))}
95
+ </div>
96
+ </CardContent>
97
+ </Card>
98
+ </div>
99
+ </div>
100
+ );
101
+ }
@@ -0,0 +1,29 @@
1
+ import { Card, CardHeader, CardTitle, CardContent } from "../components/ui/card";
2
+
3
+ export default function HelpCenter() {
4
+ return (
5
+ <div className="mx-auto max-w-[800px]">
6
+ <h1 className="mb-6 text-2xl font-semibold text-primary">Help Center</h1>
7
+ <Card className="mb-4">
8
+ <CardHeader>
9
+ <CardTitle>Frequently Asked Questions</CardTitle>
10
+ </CardHeader>
11
+ <CardContent>
12
+ <p className="m-0 leading-relaxed text-foreground">
13
+ Placeholder content for help and FAQs.
14
+ </p>
15
+ </CardContent>
16
+ </Card>
17
+ <Card>
18
+ <CardHeader>
19
+ <CardTitle>Contact Support</CardTitle>
20
+ </CardHeader>
21
+ <CardContent>
22
+ <p className="m-0 leading-relaxed text-foreground">
23
+ Reach out to the property management team for assistance.
24
+ </p>
25
+ </CardContent>
26
+ </Card>
27
+ </div>
28
+ );
29
+ }
@@ -0,0 +1,30 @@
1
+ import { Button } from "../components/ui/button";
2
+ import { Input } from "../components/ui/input";
3
+
4
+ export default function Home() {
5
+ return (
6
+ <div className="mx-auto max-w-[1100px]">
7
+ <div className="mb-6 rounded-2xl bg-primary px-8 py-10 text-primary-foreground shadow-md">
8
+ <p className="mb-2 text-xs uppercase tracking-widest opacity-90">THE ZEN WAY TO LEASE</p>
9
+ <h1 className="mb-2 text-3xl font-bold leading-tight">Your Dream Place Starts Here</h1>
10
+ <p className="mb-6 text-[0.95rem] opacity-90">
11
+ Luxury Properties, Managed With Uncompromising Care
12
+ </p>
13
+ <Button size="lg" className="font-semibold">
14
+ Browse All Properties
15
+ </Button>
16
+ </div>
17
+ <div className="flex flex-wrap items-center gap-3 rounded-xl bg-primary/10 p-5">
18
+ <Input
19
+ type="text"
20
+ placeholder="Search by address, city, location, or zipcode"
21
+ aria-label="Search"
22
+ className="min-w-[200px] flex-1 flex-[1_1_240px]"
23
+ />
24
+ <Button variant="secondary" className="font-semibold">
25
+ Find Home
26
+ </Button>
27
+ </div>
28
+ </div>
29
+ );
30
+ }
@@ -0,0 +1,132 @@
1
+ import { Button } from "../components/ui/button";
2
+ import { Input } from "../components/ui/input";
3
+ import { Label } from "../components/ui/label";
4
+ import { Card, CardHeader, CardTitle, CardContent } from "../components/ui/card";
5
+ import {
6
+ Table,
7
+ TableBody,
8
+ TableCell,
9
+ TableHead,
10
+ TableHeader,
11
+ TableRow,
12
+ } from "../components/ui/table";
13
+ import { Calendar, Upload, ArrowRight } from "lucide-react";
14
+
15
+ export default function Maintenance() {
16
+ return (
17
+ <div className="mx-auto max-w-[900px]">
18
+ <Card className="mb-6">
19
+ <CardHeader>
20
+ <CardTitle className="text-2xl text-primary">Maintenance</CardTitle>
21
+ </CardHeader>
22
+ <CardContent className="space-y-4">
23
+ <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
24
+ <div className="space-y-2">
25
+ <Label>Date Reported</Label>
26
+ <div className="relative">
27
+ <Input
28
+ type="text"
29
+ readOnly
30
+ value="Today"
31
+ className="pr-10"
32
+ aria-label="Date reported"
33
+ />
34
+ <span className="absolute right-3 top-1/2 -translate-y-1/2">
35
+ <Calendar className="size-[18px] text-muted-foreground" />
36
+ </span>
37
+ </div>
38
+ </div>
39
+ <div className="space-y-2">
40
+ <Label>Urgency</Label>
41
+ <select
42
+ className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-2 focus-visible:ring-ring"
43
+ aria-label="Urgency"
44
+ defaultValue="urgent"
45
+ >
46
+ <option value="urgent">Urgent</option>
47
+ <option value="normal">Normal</option>
48
+ <option value="low">Low</option>
49
+ </select>
50
+ </div>
51
+ </div>
52
+ <div className="space-y-2">
53
+ <Label>Room</Label>
54
+ <select
55
+ className="flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-2 focus-visible:ring-ring"
56
+ aria-label="Room"
57
+ defaultValue="living-room"
58
+ >
59
+ <option value="living-room">Living Room</option>
60
+ <option value="bathroom">Bathroom</option>
61
+ <option value="bedroom">Bedroom</option>
62
+ <option value="kitchen">Kitchen</option>
63
+ </select>
64
+ </div>
65
+ <div className="space-y-2">
66
+ <Label>Description</Label>
67
+ <textarea
68
+ rows={4}
69
+ placeholder="Input text"
70
+ className="min-h-[100px] w-full resize-y rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-xs outline-none focus-visible:ring-2 focus-visible:ring-ring"
71
+ aria-label="Description"
72
+ />
73
+ </div>
74
+ <div className="grid grid-cols-2 gap-4">
75
+ <div />
76
+ <div className="flex flex-col items-center justify-center rounded-xl border-2 border-dashed border-border bg-muted/30 p-6 text-center">
77
+ <Upload className="mx-auto mb-2 size-10 text-muted-foreground" />
78
+ <p className="m-0 text-xs text-muted-foreground">
79
+ Choose a file or drag & drop for reference here.
80
+ </p>
81
+ <p className="mt-1 text-[0.75rem] text-muted-foreground">
82
+ JPEG, PNG, PDF, and MP4 formats, up to 50MB
83
+ </p>
84
+ </div>
85
+ </div>
86
+ <div className="flex justify-end">
87
+ <Button className="gap-2">
88
+ Submit Request
89
+ <ArrowRight className="size-[18px]" />
90
+ </Button>
91
+ </div>
92
+ </CardContent>
93
+ </Card>
94
+ <Card>
95
+ <CardContent className="p-0">
96
+ <div className="overflow-x-auto">
97
+ <Table>
98
+ <TableHeader>
99
+ <TableRow>
100
+ {["Description", "Work Order", "Type", "Room", "Date", "Status"].map((h) => (
101
+ <TableHead key={h} className="font-semibold text-primary">
102
+ {h}
103
+ </TableHead>
104
+ ))}
105
+ </TableRow>
106
+ </TableHeader>
107
+ <TableBody>
108
+ <TableRow>
109
+ <TableCell>
110
+ <div className="flex items-center gap-2">
111
+ <div className="size-10 shrink-0 rounded-lg bg-muted" />
112
+ <span>Shower head leaking</span>
113
+ </div>
114
+ </TableCell>
115
+ <TableCell>#12548796</TableCell>
116
+ <TableCell>Plumbing</TableCell>
117
+ <TableCell>Bathroom</TableCell>
118
+ <TableCell>28 Jan, 12.30 AM</TableCell>
119
+ <TableCell>
120
+ <span className="inline-block rounded-full bg-green-100 px-3 py-1 text-xs font-medium text-green-700">
121
+ Completed
122
+ </span>
123
+ </TableCell>
124
+ </TableRow>
125
+ </TableBody>
126
+ </Table>
127
+ </div>
128
+ </CardContent>
129
+ </Card>
130
+ </div>
131
+ );
132
+ }
@@ -0,0 +1,14 @@
1
+ import { Link } from "react-router";
2
+ import { Button } from "../components/ui/button";
3
+
4
+ export default function NotFound() {
5
+ return (
6
+ <div className="mx-auto max-w-[800px] px-6 py-12 text-center">
7
+ <h1 className="mb-2 text-4xl font-bold text-foreground">404</h1>
8
+ <p className="mb-8 text-lg text-muted-foreground">Page not found</p>
9
+ <Button asChild>
10
+ <Link to="/">Go to Home</Link>
11
+ </Button>
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1,68 @@
1
+ import { useParams, Link } from "react-router";
2
+ import { Button } from "../components/ui/button";
3
+ import { Card, CardHeader, CardContent } from "../components/ui/card";
4
+
5
+ export default function PropertyDetails() {
6
+ const { id } = useParams();
7
+
8
+ return (
9
+ <div className="mx-auto max-w-[900px]">
10
+ <div className="mb-4">
11
+ <Link to="/properties" className="text-sm text-primary no-underline hover:underline">
12
+ ← Back to listings
13
+ </Link>
14
+ </div>
15
+ <div className="mb-4 grid grid-cols-1 gap-4 md:grid-cols-2">
16
+ <div className="h-72 rounded-xl bg-muted" />
17
+ <div className="flex flex-col gap-2">
18
+ {[1, 2, 3, 4, 5].map((i) => (
19
+ <div key={i} className="h-12 rounded-lg bg-muted" />
20
+ ))}
21
+ </div>
22
+ </div>
23
+ <div className="mb-4 flex flex-wrap gap-2">
24
+ <Button size="sm">23 Photos</Button>
25
+ <Button size="sm" variant="outline">
26
+ 8 Virtual Tours
27
+ </Button>
28
+ <Button size="sm" variant="outline">
29
+ Property Map
30
+ </Button>
31
+ </div>
32
+ <Card className="mb-4">
33
+ <CardContent className="pt-6">
34
+ <p className="mb-2 text-sm text-primary">
35
+ California / San Francisco County / San Francisco / South Beach
36
+ </p>
37
+ <p className="mb-1 text-2xl font-bold text-foreground">$4,600 / Month</p>
38
+ <p className="mb-4 text-sm text-muted-foreground">
39
+ 301 Bryant St. Unit 5B, San Francisco, CA 94107
40
+ </p>
41
+ <div className="flex flex-wrap gap-3">
42
+ {["2 Bedroom", "2 Baths", "1040 sq ft", "Now Available"].map((s) => (
43
+ <span key={s} className="rounded-lg bg-primary/10 px-3 py-1.5 text-sm text-primary">
44
+ {s}
45
+ </span>
46
+ ))}
47
+ </div>
48
+ </CardContent>
49
+ </Card>
50
+ <Card>
51
+ <CardHeader>
52
+ <CardTitle className="text-base">Contact Property</CardTitle>
53
+ </CardHeader>
54
+ <CardContent className="flex flex-col gap-2">
55
+ <Button variant="outline" className="justify-start">
56
+ Request Tour
57
+ </Button>
58
+ <Button variant="outline" className="justify-start">
59
+ Send Message
60
+ </Button>
61
+ <Button asChild variant="secondary" className="justify-center">
62
+ <Link to="/application?property=1">Fill out an application</Link>
63
+ </Button>
64
+ </CardContent>
65
+ </Card>
66
+ </div>
67
+ );
68
+ }
@@ -0,0 +1,84 @@
1
+ import { Link } from "react-router";
2
+ import { Button } from "../components/ui/button";
3
+ import { Input } from "../components/ui/input";
4
+ import { Card, CardContent } from "../components/ui/card";
5
+
6
+ const listings = [
7
+ {
8
+ id: "1",
9
+ name: "Verdana Apartments",
10
+ address: "301 Bryant St, San Francisco, CA 94107",
11
+ price: "$4,600+",
12
+ beds: "2 Beds",
13
+ phone: "(650) 440-1111",
14
+ },
15
+ {
16
+ id: "2",
17
+ name: "South Beach Lofts",
18
+ address: "250 Brannan St, San Francisco, CA 94107",
19
+ price: "$5,379+",
20
+ beds: "2 Beds",
21
+ phone: "(650) 555-0123",
22
+ },
23
+ ];
24
+
25
+ export default function PropertyListings() {
26
+ return (
27
+ <div className="grid min-h-[500px] grid-cols-1 gap-6 lg:grid-cols-[320px_1fr]">
28
+ <div className="min-h-[400px] rounded-xl bg-muted" aria-label="Map placeholder" />
29
+ <div>
30
+ <div className="mb-4 flex flex-wrap gap-3">
31
+ <Input
32
+ type="text"
33
+ defaultValue="San Francisco, CA"
34
+ className="min-w-[200px] flex-1 flex-[1_1_200px]"
35
+ />
36
+ <Button variant="outline">Price</Button>
37
+ <Button variant="outline">Beds/Bath</Button>
38
+ <Button>All Filters</Button>
39
+ </div>
40
+ <h2 className="mb-1 text-lg font-semibold text-foreground">
41
+ 2 Bedroom Apartments for Rent in San Francisco CA
42
+ </h2>
43
+ <p className="mb-4 text-sm text-muted-foreground">1,181 Rentals Available</p>
44
+ <div className="space-y-4">
45
+ {listings.map((p) => (
46
+ <Card key={p.name}>
47
+ <CardContent className="flex gap-4 p-4">
48
+ <Link
49
+ to={`/property/${p.id}`}
50
+ className="relative block size-[200px] shrink-0 rounded-xl bg-muted"
51
+ >
52
+ <span className="absolute left-2 top-2 rounded-md bg-primary px-2 py-1 text-xs text-primary-foreground">
53
+ Virtual Tours
54
+ </span>
55
+ </Link>
56
+ <div className="min-w-0 flex-1">
57
+ <h3 className="mb-1 text-base font-semibold">
58
+ <Link
59
+ to={`/property/${p.id}`}
60
+ className="text-primary no-underline hover:underline"
61
+ >
62
+ {p.name}
63
+ </Link>
64
+ </h3>
65
+ <p className="mb-2 text-sm text-muted-foreground">{p.address}</p>
66
+ <p className="mb-1 text-sm text-foreground">
67
+ {p.price} {p.beds}
68
+ </p>
69
+ <p className="mb-2 text-sm text-muted-foreground">
70
+ In Unit Washer & Dryer, Pets Allowed, Fitness Center
71
+ </p>
72
+ <p className="mb-2 text-sm text-primary">{p.phone}</p>
73
+ <Button asChild size="sm">
74
+ <Link to={`/property/${p.id}`}>Email Property</Link>
75
+ </Button>
76
+ </div>
77
+ </CardContent>
78
+ </Card>
79
+ ))}
80
+ </div>
81
+ </div>
82
+ </div>
83
+ );
84
+ }
@@ -0,0 +1,62 @@
1
+ import type { RouteObject } from 'react-router';
2
+ import AppLayout from './appLayout';
3
+ import Home from '@/pages/Home';
4
+ import About from './pages/About';
5
+ import NotFound from '@/pages/NotFound';
6
+ import Dashboard from "@/pages/Dashboard";
7
+ import Maintenance from "@/pages/Maintenance";
8
+ import PropertyListings from "@/pages/PropertyListings";
9
+ import PropertyDetails from "@/pages/PropertyDetails";
10
+ import Application from "@/pages/Application";
11
+ import HelpCenter from "@/pages/HelpCenter";
12
+
13
+ export const routes: RouteObject[] = [
14
+ {
15
+ path: "/",
16
+ element: <AppLayout />,
17
+ children: [
18
+ {
19
+ index: true,
20
+ element: <Home />,
21
+ handle: { showInNavigation: true, label: "Home" }
22
+ },
23
+ {
24
+ path: 'about',
25
+ element: <About />,
26
+ handle: { showInNavigation: true, label: 'About' }
27
+ },
28
+ {
29
+ path: "*",
30
+ element: <NotFound />
31
+ },
32
+ {
33
+ path: "dashboard",
34
+ element: <Dashboard />,
35
+ handle: { showInNavigation: true, label: "Dashboard" }
36
+ },
37
+ {
38
+ path: "properties",
39
+ element: <PropertyListings />,
40
+ handle: { showInNavigation: true, label: "Property Search" }
41
+ },
42
+ {
43
+ path: "property/:id",
44
+ element: <PropertyDetails />
45
+ },
46
+ {
47
+ path: "maintenance",
48
+ element: <Maintenance />,
49
+ handle: { showInNavigation: true, label: "Maintenance" }
50
+ },
51
+ {
52
+ path: "application",
53
+ element: <Application />
54
+ },
55
+ {
56
+ path: "help",
57
+ element: <HelpCenter />,
58
+ handle: { showInNavigation: true, label: "Help Center" }
59
+ }
60
+ ]
61
+ }
62
+ ];