# Core Stores Documentation

This document provides comprehensive documentation for all stores and state management systems available in CS Admin Core.

## Table of Contents

- [Overview](#overview)
- [Store Architecture](#store-architecture)
- [Global Store](#global-store)
- [List Store](#list-store)
- [Current Store](#current-store)
- [Media Store](#media-store)
- [Core Context](#core-context)
- [Usage Examples](#usage-examples)
- [Best Practices](#best-practices)

---

## Overview

CS Admin Core provides a comprehensive state management system built on Zustand, offering stores for different aspects of the application:

- **Global Store**: Application-wide state and utilities
- **List Store**: Data listing and pagination management
- **Current Store**: Single record management and relationships
- **Media Store**: File and media asset management
- **Core Context**: Configuration and notification management

### Key Features

- **Zustand-based**: Lightweight and performant state management
- **TypeScript Support**: Full type definitions
- **API Integration**: Built-in API communication
- **Error Handling**: Comprehensive error management
- **Notifications**: Integrated notification system
- **Internationalization**: Multi-language support

---

## Store Architecture

### Store Structure

```jsx
// Store imports
import { useGlobalStore, useList, useCurrent, useMedia } from '@weareconceptstudio/cs-admin-core';

// Store usage
const globalState = useGlobalStore();
const listState = useList();
const currentState = useCurrent();
const mediaState = useMedia();
```

### Store Dependencies

```mermaid
graph TD
    A[Global Store] --> B[List Store]
    A --> C[Current Store]
    A --> D[Media Store]
    E[Core Context] --> A
    F[API Utils] --> B
    F --> C
    F --> D
```

---

## Global Store

The global store manages application-wide state and utilities.

### State Properties

| Property           | Type     | Description                      |
| ------------------ | -------- | -------------------------------- |
| `defaultLanguage`  | string   | Default application language     |
| `navigate`         | function | React Router navigation function |
| `openNotification` | function | Notification display function    |

### Methods

| Method           | Parameters | Description                       |
| ---------------- | ---------- | --------------------------------- |
| `setGlobalStore` | `callback` | Update global state with callback |

### Usage

```jsx
import { useGlobalStore } from '@weareconceptstudio/cs-admin-core';

const MyComponent = () => {
	const { defaultLanguage, navigate, openNotification } = useGlobalStore();

	const handleNavigate = () => {
		navigate('/admin/posts');
	};

	const handleNotification = () => {
		openNotification({
			type: 'success',
			message: 'Success',
			description: 'Operation completed',
		});
	};

	return (
		<div>
			<p>Current language: {defaultLanguage}</p>
			<button onClick={handleNavigate}>Navigate</button>
			<button onClick={handleNotification}>Show Notification</button>
		</div>
	);
};
```

### Initialization

```jsx
import { makeGlobalStore } from '@weareconceptstudio/cs-admin-core';

// Initialize global store
makeGlobalStore({
	defaultLanguage: 'en',
	openNotification: (notification) => {
		// Custom notification handler
	},
});
```

---

## List Store

The list store manages data listing, pagination, and list operations.

### State Properties

| Property     | Type    | Description            |
| ------------ | ------- | ---------------------- |
| `loading`    | boolean | Loading state          |
| `error`      | object  | Error information      |
| `list`       | object  | List data by path      |
| `pagination` | object  | Pagination information |

### Methods

| Method            | Parameters                              | Description        |
| ----------------- | --------------------------------------- | ------------------ |
| `getList`         | `{ path, params }`                      | Fetch list data    |
| `sortList`        | `{ path, model, oldIndex, newIndex }`   | Sort list items    |
| `replicateRecord` | `{ editPath, id, model }`               | Replicate a record |
| `handleDelete`    | `{ path, param, isSinglePage, params }` | Delete a record    |

### Usage

```jsx
import { useList } from '@weareconceptstudio/cs-admin-core';

const PostsList = () => {
	const { loading, list, pagination, getList, handleDelete } = useList();

	useEffect(() => {
		getList({
			path: 'posts',
			params: { page: 1, per_page: 10 },
		});
	}, []);

	const handleDeletePost = (id) => {
		handleDelete({
			path: 'posts',
			param: id,
			isSinglePage: false,
		});
	};

	if (loading) return <div>Loading...</div>;

	return (
		<div>
			{list.posts?.map((post) => (
				<div key={post.id}>
					<h3>{post.title}</h3>
					<button onClick={() => handleDeletePost(post.id)}>Delete</button>
				</div>
			))}
		</div>
	);
};
```

### Pagination

```jsx
const PaginatedList = () => {
	const { list, pagination, getList } = useList();

	const handlePageChange = (page) => {
		getList({
			path: 'posts',
			params: {
				page,
				per_page: pagination.pageSize,
			},
		});
	};

	return (
		<div>
			{/* List content */}
			<Pagination
				current={pagination.current}
				total={pagination.total}
				pageSize={pagination.pageSize}
				onChange={handlePageChange}
			/>
		</div>
	);
};
```

### Sorting

```jsx
const SortableList = () => {
	const { list, sortList } = useList();

	const handleSort = (oldIndex, newIndex) => {
		sortList({
			path: 'posts',
			model: 'posts',
			oldIndex,
			newIndex,
		});
	};

	return <DragDropContext onDragEnd={handleSort}>{/* Sortable items */}</DragDropContext>;
};
```

---

## Current Store

The current store manages single record operations and relationships.

### State Properties

| Property         | Type    | Description                 |
| ---------------- | ------- | --------------------------- |
| `loading`        | boolean | Loading state               |
| `current`        | object  | Current record data by path |
| `currentOptions` | object  | Current operation options   |
| `relations`      | object  | Related data                |

### Methods

| Method         | Parameters                                               | Description         |
| -------------- | -------------------------------------------------------- | ------------------- |
| `getOne`       | `{ path, param, params, lang, type }`                    | Fetch single record |
| `getSingle`    | `{ path, params, lang }`                                 | Fetch single data   |
| `getRelations` | `{ path, endpoints, type, params, func, handleLoading }` | Fetch related data  |
| `create`       | `{ path, data }`                                         | Create new record   |
| `update`       | `{ path, param, data, redirect, isList }`                | Update record       |
| `updateSingle` | `{ path, data }`                                         | Update single data  |

### Usage

```jsx
import { useCurrent } from '@weareconceptstudio/cs-admin-core';

const PostDetail = ({ postId }) => {
	const { loading, current, relations, getOne, getRelations, update } = useCurrent();

	useEffect(() => {
		// Load post and related data
		getRelations({
			path: 'posts',
			endpoints: ['categories', 'tags'],
			func: 'getOne',
		}).then(() => {
			getOne({
				path: 'posts',
				param: postId,
				params: { isEdit: true },
			});
		});
	}, [postId]);

	const handleUpdate = (data) => {
		update({
			path: 'posts',
			param: postId,
			data,
			redirect: true,
		});
	};

	if (loading) return <div>Loading...</div>;

	const post = current.posts;

	return (
		<div>
			<h1>{post?.title}</h1>
			<p>Category: {relations.categories?.find((c) => c.id === post?.category_id)?.name}</p>
			{/* Form for editing */}
		</div>
	);
};
```

### Creating Records

```jsx
const CreatePost = () => {
	const { create, getRelations } = useCurrent();

	useEffect(() => {
		getRelations({
			path: 'posts',
			endpoints: ['categories', 'tags'],
			func: 'getOne',
		});
	}, []);

	const handleCreate = (formData) => {
		create({
			path: 'posts',
			data: formData,
		});
	};

	return <form onSubmit={handleCreate}>{/* Form fields */}</form>;
};
```

### Updating Records

```jsx
const EditPost = ({ postId }) => {
	const { current, update } = useCurrent();

	const handleUpdate = (data) => {
		update({
			path: 'posts',
			param: postId,
			data,
			redirect: false, // Stay on current page
			isList: true, // Update list state
		});
	};

	return <form onSubmit={handleUpdate}>{/* Form fields with current.posts data */}</form>;
};
```

---

## Media Store

The media store manages file uploads, media assets, and media operations.

### State Properties

| Property        | Type    | Description             |
| --------------- | ------- | ----------------------- |
| `assets`        | array   | Available media assets  |
| `loading`       | boolean | Loading state           |
| `pendingAssets` | array   | Assets pending upload   |
| `assetToEdit`   | object  | Currently editing asset |

### Methods

| Method                  | Parameters               | Description             |
| ----------------------- | ------------------------ | ----------------------- |
| `getAssets`             | `params`                 | Fetch media assets      |
| `setAssetToEdit`        | `assetToEdit`            | Set asset for editing   |
| `updateAsset`           | `id, data`               | Update asset metadata   |
| `deleteAsset`           | `ids`                    | Delete assets           |
| `changeAssetDimensions` | `values`                 | Change asset dimensions |
| `addToPendingAssets`    | `nextAssets`             | Add assets to pending   |
| `updatePendingAsset`    | `nextAsset`              | Update pending asset    |
| `removePendingAsset`    | `assetToRemove`          | Remove pending asset    |
| `replaceAsset`          | `nextAsset`              | Replace existing asset  |
| `downloadAsset`         | -                        | Download current asset  |
| `getSelectedAssets`     | `ids`                    | Get selected assets     |
| `addUploadedFile`       | `newAsset, pendingAsset` | Add uploaded file       |
| `updateMediaState`      | `callback`               | Update media state      |

### Usage

```jsx
import { useMedia } from '@weareconceptstudio/cs-admin-core';

const MediaManager = () => {
	const { assets, loading, getAssets, deleteAsset, updateAsset } = useMedia();

	useEffect(() => {
		getAssets({ acceptTypes: ['image/*'] });
	}, []);

	const handleDelete = (ids) => {
		deleteAsset(ids);
	};

	const handleUpdate = (id, data) => {
		updateAsset(id, data);
	};

	if (loading) return <div>Loading media...</div>;

	return (
		<div className='media-grid'>
			{assets.map((asset) => (
				<div
					key={asset.id}
					className='media-item'>
					<img
						src={asset.url}
						alt={asset.filename}
					/>
					<button onClick={() => handleDelete([asset.id])}>Delete</button>
				</div>
			))}
		</div>
	);
};
```

### File Upload

```jsx
const FileUpload = () => {
	const { addToPendingAssets, addUploadedFile } = useMedia();

	const handleFileSelect = (files) => {
		const fileArray = Array.from(files);
		addToPendingAssets(fileArray);
	};

	const handleUpload = async (file) => {
		const formData = new FormData();
		formData.append('file', file);

		try {
			const response = await fetch('/api/upload', {
				method: 'POST',
				body: formData,
			});
			const newAsset = await response.json();
			addUploadedFile(newAsset, file);
		} catch (error) {
			console.error('Upload failed:', error);
		}
	};

	return (
		<input
			type='file'
			multiple
			onChange={(e) => handleFileSelect(e.target.files)}
		/>
	);
};
```

### Asset Management

```jsx
const AssetEditor = ({ assetId }) => {
	const { assets, assetToEdit, setAssetToEdit, updateAsset, downloadAsset } = useMedia();

	const asset = assets.find((a) => a.id === assetId);

	const handleUpdate = (data) => {
		updateAsset(assetId, data);
	};

	const handleDownload = () => {
		setAssetToEdit(asset);
		downloadAsset();
	};

	return (
		<div>
			<img
				src={asset?.url}
				alt={asset?.filename}
			/>
			<button onClick={handleDownload}>Download</button>
			{/* Edit form */}
		</div>
	);
};
```

---

## Core Context

The core context provides configuration and notification management.

### Context Properties

| Property          | Type   | Description         |
| ----------------- | ------ | ------------------- |
| `siteName`        | string | Site name           |
| `logo`            | string | Site logo           |
| `defaultLanguage` | string | Default language    |
| `languages`       | array  | Available languages |
| `adminPrefix`     | string | Admin URL prefix    |
| `apiPrefix`       | string | API URL prefix      |
| `menu`            | object | Menu configuration  |
| `inputConfig`     | object | Input configuration |

### Methods

| Method             | Parameters     | Description       |
| ------------------ | -------------- | ----------------- |
| `updateCoreState`  | `callback`     | Update core state |
| `openNotification` | `notification` | Show notification |

### Usage

```jsx
import { useCoreContext } from '@weareconceptstudio/cs-admin-core';

const MyComponent = () => {
	const { siteName, defaultLanguage, openNotification, updateCoreState } = useCoreContext();

	const handleNotification = () => {
		openNotification({
			type: 'success',
			message: 'Success',
			description: 'Operation completed',
			duration: 5,
		});
	};

	const handleConfigUpdate = () => {
		updateCoreState((state, setState) => {
			setState({
				...state,
				siteName: 'New Site Name',
			});
		});
	};

	return (
		<div>
			<h1>{siteName}</h1>
			<p>Language: {defaultLanguage}</p>
			<button onClick={handleNotification}>Show Notification</button>
			<button onClick={handleConfigUpdate}>Update Config</button>
		</div>
	);
};
```

### Configuration

```jsx
import { CoreProvider } from '@weareconceptstudio/cs-admin-core';

const App = () => {
	const config = {
		siteName: 'My Admin Panel',
		defaultLanguage: 'en',
		languages: [
			{ id: 'en', name: 'English' },
			{ id: 'es', name: 'Spanish' },
		],
		adminPrefix: '/admin',
		apiPrefix: '/api/admin',
		menu: {
			main: [
				{
					title: 'Content',
					children: [{ title: 'Posts', path: '/admin/posts', key: 'posts' }],
				},
			],
		},
	};

	return <CoreProvider {...config}>{/* Your app content */}</CoreProvider>;
};
```

---

## Usage Examples

### Complete Data Management

```jsx
import { useList, useCurrent, useMedia, useGlobalStore } from '@weareconceptstudio/cs-admin-core';

const PostsManager = () => {
	const { getList, list, loading } = useList();
	const { getOne, current, create, update } = useCurrent();
	const { getAssets, assets } = useMedia();
	const { openNotification } = useGlobalStore();

	useEffect(() => {
		// Load posts and media
		Promise.all([getList({ path: 'posts' }), getAssets({ acceptTypes: ['image/*'] })]);
	}, []);

	const handleCreatePost = async (data) => {
		try {
			await create({ path: 'posts', data });
			openNotification({
				type: 'success',
				message: 'Post created successfully',
			});
			getList({ path: 'posts' }); // Refresh list
		} catch (error) {
			openNotification({
				type: 'error',
				message: 'Failed to create post',
			});
		}
	};

	const handleEditPost = async (id, data) => {
		try {
			await update({ path: 'posts', param: id, data });
			openNotification({
				type: 'success',
				message: 'Post updated successfully',
			});
		} catch (error) {
			openNotification({
				type: 'error',
				message: 'Failed to update post',
			});
		}
	};

	return <div>{/* Posts list and management UI */}</div>;
};
```

### Store Integration

```jsx
const IntegratedComponent = () => {
	// List operations
	const { getList, list, pagination } = useList();

	// Current record operations
	const { getOne, current, relations, getRelations } = useCurrent();

	// Media operations
	const { getAssets, assets, addToPendingAssets } = useMedia();

	// Global operations
	const { navigate, openNotification } = useGlobalStore();

	const handleCompleteWorkflow = async () => {
		try {
			// 1. Load related data
			await getRelations({
				path: 'posts',
				endpoints: ['categories', 'tags'],
			});

			// 2. Load current post
			await getOne({
				path: 'posts',
				param: '123',
			});

			// 3. Load media
			await getAssets({ acceptTypes: ['image/*'] });

			// 4. Show success notification
			openNotification({
				type: 'success',
				message: 'Data loaded successfully',
			});

			// 5. Navigate to edit page
			navigate('/admin/posts/edit/123');
		} catch (error) {
			openNotification({
				type: 'error',
				message: 'Failed to load data',
			});
		}
	};

	return (
		<div>
			<button onClick={handleCompleteWorkflow}>Load Complete Workflow</button>
		</div>
	);
};
```

---

## Best Practices

### 1. Store Organization

```jsx
// Group related store operations
const usePostOperations = () => {
	const listStore = useList();
	const currentStore = useCurrent();
	const globalStore = useGlobalStore();

	const createPost = async (data) => {
		try {
			await currentStore.create({ path: 'posts', data });
			await listStore.getList({ path: 'posts' }); // Refresh list
			globalStore.openNotification({
				type: 'success',
				message: 'Post created',
			});
		} catch (error) {
			globalStore.openNotification({
				type: 'error',
				message: 'Failed to create post',
			});
		}
	};

	return { createPost, ...listStore, ...currentStore };
};
```

### 2. Error Handling

```jsx
const useErrorHandling = () => {
	const { openNotification } = useGlobalStore();

	const handleError = (error, context = '') => {
		console.error(`Error in ${context}:`, error);

		openNotification({
			type: 'error',
			message: 'An error occurred',
			description: error.message || 'Please try again',
		});
	};

	return { handleError };
};
```

### 3. Loading States

```jsx
const useLoadingStates = () => {
	const { loading: listLoading } = useList();
	const { loading: currentLoading } = useCurrent();
	const { loading: mediaLoading } = useMedia();

	const isLoading = listLoading || currentLoading || mediaLoading;

	return { isLoading, listLoading, currentLoading, mediaLoading };
};
```

### 4. Performance Optimization

```jsx
// Use selectors to prevent unnecessary re-renders
const useOptimizedList = () => {
	const list = useList((state) => state.list);
	const loading = useList((state) => state.loading);
	const getList = useList((state) => state.getList);

	return { list, loading, getList };
};
```

### 5. TypeScript Integration

```tsx
interface Post {
	id: number;
	title: string;
	content: string;
	status: 'draft' | 'published';
}

const useTypedList = () => {
	const list = useList<Record<string, Post[]>>((state) => state.list);
	const getList = useList((state) => state.getList);

	return { list, getList };
};
```

This documentation covers all the core stores and state management systems available in CS Admin Core. These stores provide a comprehensive foundation for managing application state, data operations, and user interactions.
