forked from mckaywrigley/o1-xml-parser
-
Notifications
You must be signed in to change notification settings - Fork 0
/
.cursorrules
207 lines (144 loc) · 5.36 KB
/
.cursorrules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# Project Instructions
Use the project specification and guidelines as you build the app.
Write the complete code for every step. Do not get lazy.
Your goal is to completely finish whatever I ask for.
## Overview
This is an XML parsing tool for XML responses from OpenAI's o1 pro model in ChatGPT.
## Tech Stack
- Frontend: Next.js, Tailwind, Shadcn, Framer Motion
## Project Structure
### General Structure
- `app` - Next.js app router
- `route` - An app route
- `_components` - One-off components for the route
- `layout.tsx` - Layout for the route
- `page.tsx` - Page for the route
- `components` - Shared components
- `ui` - UI components
- `utilities` - Utility components
- `lib` - Library code
- `hooks` - Custom hooks
- `prompts` - Prompt files
- `public` - Static assets
- `types` - Type definitions
## Rules
Follow these rules when building the project.
### General Rules
- Use `@` to import anything from the project unless otherwise specified
- Use kebab case for all files and folders unless otherwise specified
#### Env Rules
- If you update environment variables, update the `.env.example` file
- All environment variables should go in `.env.local`
- Do not expose environment variables to the frontend
- Use `NEXT_PUBLIC_` prefix for environment variables that need to be accessed from the frontend
- You may import environment variables in server actions and components by using `process.env.VARIABLE_NAME`
#### Type Rules
Follow these rules when working with types.
- When importing types, use `@/types`
- Name files like `example-types.ts`
- All types should go in `types`
- Make sure to export the types in `types/index.ts`
- Prefer interfaces over type aliases
An example of a type:
`types/actions-types.ts`
```ts
export type ActionState<T> = { isSuccess: true; message: string; data: T } | { isSuccess: false; message: string; data?: never };
```
And exporting it:
`types/index.ts`
```ts
export * from "./actions-types";
```
### Frontend Rules
Follow these rules when working on the frontend.
It uses Next.js, Tailwind, Shadcn, and Framer Motion.
#### General Rules
- Use `lucide-react` for icons
#### Components
- Use divs instead of other html tags unless otherwise specified
- Separate the main parts of a component's html with an extra blank line for visual spacing
- Use actions, not queries, in the app
- Always tag a component with either `use server` or `use client` at the top, including layouts and pages
##### Organization
- All components be named using kebab case like `example-component.tsx` unless otherwise specified
- Put components in `/_components` in the route if one-off components
- Put components in `/components` from the root if shared components
##### Data Fetching
- Fetch data in server components and pass the data down as props to client components.
- Use server actions from `/actions` to mutate data.
##### Server Components
- Use `"use server"` at the top of the file.
- Implement Suspense for asynchronous data fetching to show loading states while data is being fetched.
- If no asynchronous logic is required for a given server component, you do not need to wrap the component in `<Suspense>`. You can simply return the final UI directly since there is no async boundary needed.
- If asynchronous fetching is required, you can use a `<Suspense>` boundary and a fallback to indicate a loading state while data is loading.
Example of a server layout:
```tsx
"use server";
export default async function ExampleServerLayout({ children }: { children: React.ReactNode }) {
return children;
}
```
Example of a server page (with async logic):
```tsx
"use server";
import { Suspense } from "react";
import { SomeAction } from "@/actions/some-actions";
import SomeComponent from "./_components/some-component";
import SomeSkeleton from "./_components/some-skeleton";
export default async function ExampleServerPage() {
return (
<Suspense fallback={<SomeSkeleton className="some-class" />}>
<SomeComponentFetcher />
</Suspense>
);
}
async function SomeComponentFetcher() {
const { data } = await SomeAction();
return (
<SomeComponent
className="some-class"
initialData={data || []}
/>
);
}
```
Example of a server page (no async logic required):
```tsx
"use server";
import SomeClientComponent from "./_components/some-client-component";
// In this case, no asynchronous work is being done, so no Suspense or fallback is required.
export default async function ExampleServerPage() {
return <SomeClientComponent initialData={[]} />;
}
```
Example of a server component:
```tsx
"use server";
interface ExampleServerComponentProps {
// Your props here
}
export async function ExampleServerComponent({ props }: ExampleServerComponentProps) {
// Your code here
}
```
##### Client Components
- Use `"use client"` at the top of the file
- Client components can safely rely on props passed down from server components, or handle UI interactions without needing <Suspense> if there’s no async logic.
Example of a client page:
```tsx
"use client";
export default function ExampleClientPage() {
// Your code here
}
```
Example of a client component:
```tsx
"use client";
interface ExampleClientComponentProps {
initialData: any[];
}
export default function ExampleClientComponent({ initialData }: ExampleClientComponentProps) {
// Client-side logic here
return <div>{initialData.length} items</div>;
}
```