From 110ea948878c3e47e63f4f38b4da7abad0bd7002 Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Wed, 8 Jan 2025 17:39:38 +0300 Subject: [PATCH 1/3] docs: new contribution guideline for client structure --- apps/docs/mint.json | 1 + .../docs/contributing/client-structure.mdx | 152 ++++++++++++++++++ .../content/docs/contributing/meta.json | 2 +- 3 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 apps/engineering/content/docs/contributing/client-structure.mdx diff --git a/apps/docs/mint.json b/apps/docs/mint.json index e7ca397b1c..e6511c771e 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -414,6 +414,7 @@ "contributing/editor-setup", "contributing/testing", "contributing/sdk-development", + "contributing/client-structure", { "group": "Services", "pages": [ diff --git a/apps/engineering/content/docs/contributing/client-structure.mdx b/apps/engineering/content/docs/contributing/client-structure.mdx new file mode 100644 index 0000000000..7dc914b33b --- /dev/null +++ b/apps/engineering/content/docs/contributing/client-structure.mdx @@ -0,0 +1,152 @@ +--- +title: Client-Side Structure +description: How to structure your PR when contributing to Unkey dashboard +--- + +# Client-Side Structure Contribution Guidelines + +## Overview + +When contributing to the Unkey dashboard or any client app in the Unkey repository, we follow a feature-based architecture. This guide will help you understand how to structure your code to maintain consistency across the project. + +## Directory Structure + +Each feature (typically corresponding to a Next.js page) should be organized as a self-contained module with the following structure: + +``` +feature-name/ +├── components/ # Feature-specific React components +│ ├── component-name/ # Complex components get their own directory +│ │ ├── index.tsx +│ │ └── sub-component.tsx +│ └── simple-component.tsx +├── hooks/ # Custom hooks for the feature +│ ├── queries/ # API query hooks +│ │ ├── use-feature-list.ts +│ │ └── use-feature-details.ts +│ └── use-feature-logic.ts +├── actions/ # Server actions and API calls +│ └── feature-actions.ts +├── types/ # TypeScript types and interfaces +│ └── feature.ts +├── schemas/ # Validation schemas +│ └── feature.ts +├── utils/ # Helper functions +│ └── feature-helpers.ts +├── constants.ts # Feature-specific constants +└── page.tsx # Main page component +``` + +## Key Principles + +1. **Feature Isolation** + + - Keep all related code within the feature directory + - Don't import feature-specific components into other features + - Use shared components from the global `/components` directory or `unkey/ui` repo for common UI elements + +2. **Component Organization** + + - Simple components can be single files **(No need to break everything into 50 different files, follow your common sense)** + - Complex components should have their own directory with an index.tsx + - Keep component-specific styles, tests, and utilities close to the component + +3. **Code Colocation** + - Place related code as close as possible to where it's used + - If a utility is only used by one component, keep it in the component's directory + +## Example Page Structure + +Here's an example of how to structure a typical page component: + +```typescript +import { Navbar } from "@/components/navbar"; // Global shared component +import { PageContent } from "@/components/page-content"; +import { FeatureComponent } from "./components/feature-component"; +import { useFeatureData } from "./hooks/use-feature-data"; +import { featureAction } from "./actions/feature-actions"; + +export default function FeaturePage() { + // Page implementation + // This is also we where we do our server side data fetching. + return ( +
+ {/* Navigation content */} + + {/* Entry to our actual component. This one is usually a client-side component */} + + +
+ ); +} +``` + +## Best Practices + +1. **File Naming** + + - Use kebab-case for directory and file names + - The directory structure itself provides context, so explicit suffixes are optional + - If you choose to use suffixes for additional clarity, common patterns include: + - `.schema.ts` or just `.ts` for validation schemas + - `.type.ts` or just `.ts` for type definitions + - `.client.tsx` for client-specific components + - `.server.ts` for server-only code + - `.action.ts` for server actions + +2. **Code Organization** + + - Keep files focused and single-purpose + - Use index.ts files to expose public API of complex components + - Colocate tests with the code they test + - Place shared types in the feature's `types` directory + +3. **Imports and Exports** + - Use absolute imports for shared components (`@/components`) + - Use relative imports within a feature + - Export complex components through index files + - Avoid circular dependencies + +## Shared Code + +Global shared code should be placed in root-level directories: + +``` +/components # Shared React components +/hooks # Shared custom hooks +/utils # Shared utilities +/types # Shared TypeScript types +/constants # Global constants +``` + +Only place code in these directories if it's used across multiple features. + +## Example Feature Implementation + +Here's a practical example of how to structure a feature: + +```typescript +// /feature/components/feature-list/index.tsx +export function FeatureList() { + // Component implementation +} + +// /feature/hooks/queries/use-features.ts +export function useFeatures() { + // Hook implementation +} + +// /feature/actions/feature-actions.ts +export async function createFeature() { + // Server action implementation +} + +// /feature/types/feature.ts +export interface Feature { + // Type definitions +} +``` + +## Questions? + +If you're unsure about where to place certain code or how to structure your feature, please don't hesitate to ask in our Discord community or in your pull request. We're here to help! diff --git a/apps/engineering/content/docs/contributing/meta.json b/apps/engineering/content/docs/contributing/meta.json index 20bc193e01..2d533ed3db 100644 --- a/apps/engineering/content/docs/contributing/meta.json +++ b/apps/engineering/content/docs/contributing/meta.json @@ -3,5 +3,5 @@ "description": "oss/acc", "icon": "GitPullRequest", "root": true, - "pages": ["index", "sdk-development", "testing", "versions"] + "pages": ["index", "sdk-development", "testing", "versions", "client-structure"] } From f5e53484d227fd2eeab93b22e18536639a05d133 Mon Sep 17 00:00:00 2001 From: ogzhanolguncu Date: Wed, 8 Jan 2025 22:03:06 +0300 Subject: [PATCH 2/3] fix: styling issues and revert mint.json change --- apps/docs/mint.json | 6 ++-- .../docs/contributing/client-structure.mdx | 29 +++++++++---------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/apps/docs/mint.json b/apps/docs/mint.json index e6511c771e..4197e1aadd 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -124,7 +124,10 @@ { "group": "Identities", "icon": "fingerprint", - "pages": ["concepts/identities/overview", "concepts/identities/ratelimits"] + "pages": [ + "concepts/identities/overview", + "concepts/identities/ratelimits" + ] } ] }, @@ -414,7 +417,6 @@ "contributing/editor-setup", "contributing/testing", "contributing/sdk-development", - "contributing/client-structure", { "group": "Services", "pages": [ diff --git a/apps/engineering/content/docs/contributing/client-structure.mdx b/apps/engineering/content/docs/contributing/client-structure.mdx index 7dc914b33b..e976f286bb 100644 --- a/apps/engineering/content/docs/contributing/client-structure.mdx +++ b/apps/engineering/content/docs/contributing/client-structure.mdx @@ -16,25 +16,25 @@ Each feature (typically corresponding to a Next.js page) should be organized as ``` feature-name/ ├── components/ # Feature-specific React components -│ ├── component-name/ # Complex components get their own directory +│ ├── component-name/ # Complex components get their own directory │ │ ├── index.tsx │ │ └── sub-component.tsx │ └── simple-component.tsx -├── hooks/ # Custom hooks for the feature -│ ├── queries/ # API query hooks +├── hooks/ # Custom hooks for the feature +│ ├── queries/ # API query hooks │ │ ├── use-feature-list.ts │ │ └── use-feature-details.ts │ └── use-feature-logic.ts -├── actions/ # Server actions and API calls +├── actions/ # Server actions and API calls │ └── feature-actions.ts -├── types/ # TypeScript types and interfaces +├── types/ # TypeScript types and interfaces │ └── feature.ts -├── schemas/ # Validation schemas +├── schemas/ # Validation schemas │ └── feature.ts -├── utils/ # Helper functions +├── utils/ # Helper functions │ └── feature-helpers.ts -├── constants.ts # Feature-specific constants -└── page.tsx # Main page component +├── constants.ts # Feature-specific constants +└── page.tsx # Main page component ``` ## Key Principles @@ -43,7 +43,7 @@ feature-name/ - Keep all related code within the feature directory - Don't import feature-specific components into other features - - Use shared components from the global `/components` directory or `unkey/ui` repo for common UI elements + - Use shared components from the global `/components` directory or `unkey/ui` package for common UI elements 2. **Component Organization** @@ -63,8 +63,6 @@ Here's an example of how to structure a typical page component: import { Navbar } from "@/components/navbar"; // Global shared component import { PageContent } from "@/components/page-content"; import { FeatureComponent } from "./components/feature-component"; -import { useFeatureData } from "./hooks/use-feature-data"; -import { featureAction } from "./actions/feature-actions"; export default function FeaturePage() { // Page implementation @@ -88,8 +86,8 @@ export default function FeaturePage() { - Use kebab-case for directory and file names - The directory structure itself provides context, so explicit suffixes are optional - If you choose to use suffixes for additional clarity, common patterns include: - - `.schema.ts` or just `.ts` for validation schemas - - `.type.ts` or just `.ts` for type definitions + - `auth.schema.ts` or just `auth-schema.ts` for validation schemas + - `auth.type.ts` or just `auth-types.ts` for type definitions - `.client.tsx` for client-specific components - `.server.ts` for server-only code - `.action.ts` for server actions @@ -103,6 +101,7 @@ export default function FeaturePage() { 3. **Imports and Exports** - Use absolute imports for shared components (`@/components`) + - Never use default exports unless it's absolutely necessary - Use relative imports within a feature - Export complex components through index files - Avoid circular dependencies @@ -112,7 +111,7 @@ export default function FeaturePage() { Global shared code should be placed in root-level directories: ``` -/components # Shared React components +/components # Shared React components /hooks # Shared custom hooks /utils # Shared utilities /types # Shared TypeScript types From ede83479862dec547e0b93713562d9dcabd03178 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 19:05:54 +0000 Subject: [PATCH 3/3] [autofix.ci] apply automated fixes --- apps/docs/mint.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/apps/docs/mint.json b/apps/docs/mint.json index 4197e1aadd..e7ca397b1c 100644 --- a/apps/docs/mint.json +++ b/apps/docs/mint.json @@ -124,10 +124,7 @@ { "group": "Identities", "icon": "fingerprint", - "pages": [ - "concepts/identities/overview", - "concepts/identities/ratelimits" - ] + "pages": ["concepts/identities/overview", "concepts/identities/ratelimits"] } ] },