add svg icons. running into scroll issue. will upgrade packages.
This commit is contained in:
@ -1,191 +1,274 @@
|
||||
import { createSelector, createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { Id, Product } from '@/lib/product';
|
||||
import { dimensions_t, } from "@/lib/dimensions";
|
||||
import { createSelector, createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||
import { attributesAsList, Id, Product } from "@/lib/product";
|
||||
import { dimensions_t, length_t } from "@/lib/dimensions";
|
||||
import uuid from "react-native-uuid";
|
||||
import { RootState } from '@/app/store';
|
||||
import { Length } from 'convert';
|
||||
import { AppStore, RootState } from "@/app/store";
|
||||
import { Length } from "convert";
|
||||
|
||||
const initialState = {
|
||||
products: [] as Product[],
|
||||
units: "ft",
|
||||
export const DEFAULT_UNITS: Length = "ft";
|
||||
|
||||
export type PlywoodCalculationState = {
|
||||
product?: Id | null;
|
||||
units: Length;
|
||||
};
|
||||
|
||||
export type CarpetCalculationState = {
|
||||
product?: Id | null;
|
||||
length: length_t;
|
||||
inner_d: length_t;
|
||||
outer_d: length_t;
|
||||
};
|
||||
|
||||
export type AppStoreState = {
|
||||
products: Product[];
|
||||
calculations?: {
|
||||
plywood: PlywoodCalculationState;
|
||||
carpet: CarpetCalculationState;
|
||||
};
|
||||
};
|
||||
|
||||
export const DEFAULT_PRELOADED_STATE = {
|
||||
products: [] as Product[],
|
||||
calculations: {
|
||||
plywood: {
|
||||
product: undefined,
|
||||
units: DEFAULT_UNITS,
|
||||
},
|
||||
carpet: {
|
||||
product: undefined,
|
||||
length: {
|
||||
l: 0,
|
||||
u: DEFAULT_UNITS,
|
||||
},
|
||||
inner_d: {
|
||||
l: 0,
|
||||
u: DEFAULT_UNITS,
|
||||
},
|
||||
outer_d: {
|
||||
l: 0,
|
||||
u: DEFAULT_UNITS,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as AppStoreState;
|
||||
|
||||
const initialState: AppStoreState = DEFAULT_PRELOADED_STATE;
|
||||
|
||||
export type UpdateAttribute = {
|
||||
product_id: Id,
|
||||
attributeKey: string,
|
||||
attributeValue: any,
|
||||
}
|
||||
product_id: Id;
|
||||
attributeKey: string;
|
||||
attributeValue: any;
|
||||
};
|
||||
|
||||
export type UpdateAttributeKey = {
|
||||
product_id: Id,
|
||||
oldKey: string,
|
||||
newKey: string,
|
||||
}
|
||||
product_id: Id;
|
||||
oldKey: string;
|
||||
newKey: string;
|
||||
};
|
||||
|
||||
export type AddAttribute = {
|
||||
product_id: Id,
|
||||
}
|
||||
product_id: Id;
|
||||
};
|
||||
|
||||
const cp = (obj: any) => JSON.parse(JSON.stringify(obj));
|
||||
|
||||
const productsState = createSlice({
|
||||
name: 'products-slice',
|
||||
initialState,
|
||||
reducers: {
|
||||
setUnits(state, action : PayloadAction<Length>) {
|
||||
state.units = action.payload;
|
||||
},
|
||||
createProduct(state, action: PayloadAction<ProductData>) {
|
||||
if (!state) {
|
||||
return initialState
|
||||
}
|
||||
const product = action.payload;
|
||||
if (!product.id) product.id = uuid.v4().toString();
|
||||
state.products = [...state.products, action.payload];
|
||||
return state;
|
||||
},
|
||||
deleteProduct(state, action: PayloadAction<Id>) {
|
||||
if (!state) return initialState;
|
||||
return {
|
||||
...state,
|
||||
products: [...state.products.filter((prod) => {
|
||||
return prod.id?.valueOf() !== action.payload.valueOf();
|
||||
})],
|
||||
}
|
||||
},
|
||||
updateAttribute(state, action: PayloadAction<UpdateAttribute>) {
|
||||
const { product_id, attributeKey, attributeValue } = action.payload
|
||||
if (!state) return initialState;
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map(prod => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
const attributes = cp(prod.attributes);
|
||||
attributes[attributeKey] = attributeValue;
|
||||
return {
|
||||
...prod,
|
||||
attributes,
|
||||
}
|
||||
})
|
||||
};
|
||||
},
|
||||
changeKey(state, action: PayloadAction<UpdateAttributeKey>) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, oldKey, newKey } = action.payload
|
||||
name: "products-slice",
|
||||
initialState,
|
||||
reducers: {
|
||||
setPlywoodCalculation(
|
||||
state,
|
||||
action: PayloadAction<PlywoodCalculationState>
|
||||
) {
|
||||
if (!state) {
|
||||
return initialState;
|
||||
}
|
||||
const newCalc = action.payload;
|
||||
state.calculations.plywood = newCalc;
|
||||
return state;
|
||||
},
|
||||
setCarpetCalculation(state, action: PayloadAction<CarpetCalculationState>) {
|
||||
if (!state) {
|
||||
return initialState;
|
||||
}
|
||||
const newCalc = action.payload;
|
||||
state.calculations.carpet = newCalc;
|
||||
return state;
|
||||
},
|
||||
createProduct(state, action: PayloadAction<Product>) {
|
||||
if (!state) {
|
||||
return initialState;
|
||||
}
|
||||
const product = action.payload;
|
||||
if (!product.id) product.id = uuid.v4().toString();
|
||||
state.products = [...state.products, action.payload];
|
||||
return state;
|
||||
},
|
||||
deleteProduct(state, action: PayloadAction<Id>) {
|
||||
if (!state) return initialState;
|
||||
return {
|
||||
...state,
|
||||
products: [
|
||||
...state.products.filter((prod) => {
|
||||
return prod.id?.valueOf() !== action.payload.valueOf();
|
||||
}),
|
||||
],
|
||||
};
|
||||
},
|
||||
updateAttribute(state, action: PayloadAction<UpdateAttribute>) {
|
||||
const { product_id, attributeKey, attributeValue } = action.payload;
|
||||
if (!state) return initialState;
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map((prod) => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
const attributes = cp(prod.attributes);
|
||||
attributes[attributeKey] = attributeValue;
|
||||
return {
|
||||
...prod,
|
||||
attributes,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
changeKey(state, action: PayloadAction<UpdateAttributeKey>) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, oldKey, newKey } = action.payload;
|
||||
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map(prod => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map((prod) => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
|
||||
const attributes = cp(prod.attributes);
|
||||
attributes[newKey] = attributes[oldKey];
|
||||
delete attributes[oldKey];
|
||||
attributes.id = prod.id;
|
||||
return {
|
||||
...prod,
|
||||
attributes,
|
||||
}
|
||||
})
|
||||
};
|
||||
},
|
||||
addAttribute(state, action: PayloadAction<Id>) {
|
||||
if (!state) return initialState;
|
||||
const product_id = action.payload;
|
||||
state.products = state.products.map(prod => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
const i = (Object.keys(prod.attributes || {}).filter(k => k.match(/attribute [\d]+/)) || []).length;
|
||||
const newAttribute = `attribute ${i + 1}`;
|
||||
return {
|
||||
...prod,
|
||||
attributes: {
|
||||
...prod.attributes,
|
||||
[newAttribute]: `value`,
|
||||
}
|
||||
}
|
||||
});
|
||||
return state;
|
||||
},
|
||||
const attributes = cp(prod.attributes);
|
||||
attributes[newKey] = attributes[oldKey];
|
||||
delete attributes[oldKey];
|
||||
attributes.id = prod.id;
|
||||
return {
|
||||
...prod,
|
||||
attributes,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
addAttribute(state, action: PayloadAction<Id>) {
|
||||
if (!state) return initialState;
|
||||
const product_id = action.payload;
|
||||
state.products = state.products.map((prod) => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
const i = (
|
||||
Object.keys(prod.attributes || {}).filter((k) =>
|
||||
k.match(/attribute [\d]+/)
|
||||
) || []
|
||||
).length;
|
||||
const newAttribute = `attribute ${i + 1}`;
|
||||
return {
|
||||
...prod,
|
||||
attributes: {
|
||||
...prod.attributes,
|
||||
[newAttribute]: `value`,
|
||||
},
|
||||
};
|
||||
});
|
||||
return state;
|
||||
},
|
||||
|
||||
deleteAttribute(state, action: PayloadAction<{ product_id: Id, attribute: string }>) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, attribute } = action.payload;
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map(prod => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
const attributes = Object.fromEntries(Object.entries(prod).filter(([k, v]) => (k !== attribute)));
|
||||
return {
|
||||
...prod,
|
||||
attributes,
|
||||
}
|
||||
}),
|
||||
};
|
||||
},
|
||||
updatePrice(state, action: PayloadAction<{ product_id: Id, pricePerUnit: number }>) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, pricePerUnit } = action.payload;
|
||||
state.products = state.products.map(prod => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
prod.pricePerUnit = pricePerUnit;
|
||||
return prod;
|
||||
});
|
||||
return state;
|
||||
},
|
||||
updateDimensions(state, action: PayloadAction<{ product_id: Id, dimensions: dimensions_t }>) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, dimensions } = action.payload;
|
||||
console.log("Changing dimensions: %o", action.payload);
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map(prod => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
return {
|
||||
...prod,
|
||||
dimensions,
|
||||
}
|
||||
}),
|
||||
};
|
||||
},
|
||||
|
||||
}
|
||||
deleteAttribute(
|
||||
state,
|
||||
action: PayloadAction<{ product_id: Id; attribute: string }>
|
||||
) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, attribute } = action.payload;
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map((prod) => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
const attributes = Object.fromEntries(
|
||||
Object.entries(prod).filter(([k, v]) => k !== attribute)
|
||||
);
|
||||
return {
|
||||
...prod,
|
||||
attributes,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
updatePrice(
|
||||
state,
|
||||
action: PayloadAction<{ product_id: Id; pricePerUnit: number }>
|
||||
) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, pricePerUnit } = action.payload;
|
||||
state.products = state.products.map((prod) => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
prod.pricePerUnit = pricePerUnit;
|
||||
return prod;
|
||||
});
|
||||
return state;
|
||||
},
|
||||
updateDimensions(
|
||||
state,
|
||||
action: PayloadAction<{ product_id: Id; dimensions: dimensions_t }>
|
||||
) {
|
||||
if (!state) return initialState;
|
||||
const { product_id, dimensions } = action.payload;
|
||||
console.log("Changing dimensions: %o", action.payload);
|
||||
return {
|
||||
...state,
|
||||
products: state.products.map((prod) => {
|
||||
if (prod.id !== product_id) return prod;
|
||||
return {
|
||||
...prod,
|
||||
dimensions,
|
||||
};
|
||||
}),
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const selectProducts = (state: RootState) => {
|
||||
return state.products;
|
||||
}
|
||||
return state.products;
|
||||
};
|
||||
|
||||
export const selectUnits = (state : RootState) => {
|
||||
return (state.units || "ft") as Length;
|
||||
}
|
||||
export const selectPlywoodCalc = (state: RootState) => {
|
||||
return state.calculations.plywood;
|
||||
};
|
||||
|
||||
export const selectProductIds = createSelector([selectProducts], products => {
|
||||
return products.map(p => p.id);
|
||||
})
|
||||
export const selectCarpetCalc = (state: RootState) => {
|
||||
return state.calculations.carpet;
|
||||
};
|
||||
|
||||
export const selectProductAttributes = createSelector([selectProducts], products => {
|
||||
return Object.fromEntries(products.map(p => {
|
||||
return [
|
||||
p.id,
|
||||
p.attributesAsList,
|
||||
]
|
||||
}))
|
||||
})
|
||||
export const selectProductIds = createSelector([selectProducts], (products) => {
|
||||
return products.map((p) => p.id);
|
||||
});
|
||||
|
||||
export const selectProductAttributes = createSelector(
|
||||
[selectProducts],
|
||||
(products) => {
|
||||
return Object.fromEntries(
|
||||
products.map((p) => {
|
||||
return [p.id, p.attributes ? attributesAsList(p.attributes) : []];
|
||||
})
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const actions = {
|
||||
...productsState.actions
|
||||
...productsState.actions,
|
||||
};
|
||||
|
||||
export const {
|
||||
setUnits,
|
||||
createProduct,
|
||||
deleteProduct,
|
||||
changeKey,
|
||||
updateAttribute,
|
||||
addAttribute,
|
||||
deleteAttribute,
|
||||
updatePrice,
|
||||
updateDimensions,
|
||||
setCarpetCalculation,
|
||||
setPlywoodCalculation,
|
||||
createProduct,
|
||||
deleteProduct,
|
||||
changeKey,
|
||||
updateAttribute,
|
||||
addAttribute,
|
||||
deleteAttribute,
|
||||
updatePrice,
|
||||
updateDimensions,
|
||||
} = productsState.actions;
|
||||
|
||||
export default productsState.reducer;
|
||||
|
Reference in New Issue
Block a user