Frontend Introduction Project Overview OnMarket Landing is a comprehensive Angular-based e-commerce marketplace application. It provides a full-featured online shopping platform with product browsing, cart management, checkout, user profiles, affiliate program, and real-time chat functionality. Key Capabilities Product browsing and search Shopping cart and checkout User authentication and profile management Affiliate marketing program Store management Real-time chat via WebSockets Multiple payment integrations Order tracking and history Voucher and promotion system Technology Stack Core Framework Angular : v12.2.2 TypeScript : v4.3.5 RxJS : v6.6.3 (Reactive Programming) UI/UX Libraries Angular Material : v12.2.2 - Material Design components Angular Flex Layout : v12.0.0 - Responsive layout system Angular Animations : v12.2.2 - Animation support Font Awesome : v6.5.1 - Icon library SweetAlert2 : v10.3.3 - Beautiful alerts and modals Additional Libraries Socket.io Client : v4.7.5 - Real-time WebSocket communication Google Maps : v3.55.12 - Map integration ApexCharts : v3.35.0 - Interactive charts jwt-decode : v3.1.2 - JWT token decoding dayjs : v1.10.7 - Date manipulation ngx-translate : v13.0.0 - Internationalization (i18n) ngx-infinite-scroll : v10.0.1 - Infinite scrolling ngx-countdown : v11.0.3 - Countdown timers ngx-perfect-scrollbar : v10.1.1 - Custom scrollbars Development Tools Angular CLI : v12.2.2 Karma : v6.3.4 - Test runner Jasmine : v3.9.0 - Testing framework TSLint : v6.1.0 - Code linting Protractor : v7.0.0 - E2E testing Installation and setup Prerequisites Before you begin, ensure you have the following installed: Node.js : v12.x or higher (recommended v14.x or v16.x) npm : v6.x or higher (comes with Node.js) Angular CLI : v12.2.2 npm install -g @angular/cli@12.2.2 Installation & Setup 1. Clone the Repository git clone https://github.com/ondeliveroper/on-market-landing.git cd on-market-landing 2. Install Dependencies npm install 3. Environment Configuration The application uses environment files located in src/environments/ : environment.ts - Development environment environment.prod.ts - Production environment 4. Start Development Server npm start # or for Windows npm run startWindows The application will be available at http://localhost:4200/ Note : The start script uses NODE_OPTIONS='--openssl-legacy-provider' due to OpenSSL compatibility with Angular 12. Project structure on-market-landing/ ├── e2e/ # End-to-end tests ├── src/ │ ├── app/ │ │ ├── components/ # All UI components │ │ │ ├── accounts/ # Login, signup, profile │ │ │ ├── affiliate/ # Affiliate program │ │ │ ├── all-bills/ # Bill payment features │ │ │ ├── cart/ # Shopping cart │ │ │ ├── checkout/ # Checkout process │ │ │ ├── homepage/ # Home page │ │ │ ├── personal-store/ # Store management │ │ │ ├── product-details/ # Product detail pages │ │ │ ├── search-result/ # Search functionality │ │ │ └── ... # Other components │ │ ├── interceptors/ # HTTP interceptors │ │ │ └── auth.interceptor.ts │ │ ├── interfaces/ # TypeScript interfaces │ │ │ ├── affiliate.ts │ │ │ ├── balance.ts │ │ │ ├── bank.ts │ │ │ ├── products.ts │ │ │ └── user.ts │ │ ├── pipes/ # Custom pipes │ │ │ ├── phone-number.pipe.ts │ │ │ ├── short-number-pipe.pipe.ts │ │ │ ├── time-ago.pipe.ts │ │ │ └── transform-city.pipe.ts │ │ ├── services/ # Business logic services │ │ │ └── affiliate.service.ts │ │ ├── themes/ # Multiple theme layouts │ │ │ ├── theme-one/ │ │ │ ├── theme-two/ │ │ │ └── ... │ │ ├── api.service.ts # Main API service │ │ ├── app-routing.module.ts # Route definitions │ │ ├── app.component.ts # Root component │ │ ├── app.module.ts # Main module │ │ ├── auth.guard.ts # Route authentication │ │ ├── demo-material-module.ts # Material imports │ │ ├── logger.service.ts # Logging service │ │ ├── sockets.service.ts # WebSocket service │ │ └── utility.service.ts # Utility functions │ ├── assets/ # Static assets │ │ ├── css/ # Stylesheets │ │ ├── images/ # Images │ │ └── ... │ ├── environments/ # Environment configs │ │ ├── environment.ts │ │ └── environment.prod.ts │ ├── custom-theme.scss # Material theme │ ├── styles.scss # Global styles │ └── index.html # Main HTML file ├── angular.json # Angular configuration ├── package.json # Dependencies ├── tsconfig.json # TypeScript configuration ├── tslint.json # Linting rules └── karma.conf.js # Test configuration Key Directories Explained /src/app/components/ Contains all UI components organized by feature: accounts/ - User authentication and profile management affiliate/ - Affiliate marketing dashboard and features cart/ - Shopping cart functionality checkout/ - Checkout and payment process personal-store/ - Store owner features product-details/ - Product information display search-result/ - Search results page /src/app/services/ Business logic and reusable services: API integration services State management services Utility services /src/app/interceptors/ HTTP interceptors for: Adding authentication tokens Error handling Request/response transformation Core features 1. E-Commerce Functionality Product catalog browsing Advanced search and filtering Product details with images and specifications Shopping cart management Checkout process with multiple payment options Order tracking and history 2. User Management User registration and login Phone OTP verification Profile management Address book Password management Wishlist/favorites 3. Affiliate Program Affiliate registration Dashboard with earnings analytics Commission withdrawal Collection management Custom affiliate links Payment settings 4. Store Features Personal store creation Store profile management Product management Store reviews and ratings Store analytics 5. Communication Real-time chat via WebSockets WhatsApp integration Message notifications Order-related messaging 6. Additional Services Bill payments (Pulsa, PLN, PDAM, etc.) Vouchers and promotions Flash sales Campaign templates Reviews and ratings Development guidelines Architecture & Design Patterns Component-Based Architecture The application follows Angular's component-based architecture where each feature is encapsulated in its own component with clear responsibilities. Modular Design Feature Modules : Components are organized by feature Shared Module : Common components, pipes, and directives Core Module : Singleton services and app-wide functionality Design Patterns Used 1. Dependency Injection Services are injected into components via Angular's DI system: constructor( private apiService: ApiService, private router: Router ) {} 2. Observer Pattern (RxJS) Used extensively for handling asynchronous data: this.apiService.getProducts().subscribe( data => this.products = data, error => this.handleError(error) ); 3. Guard Pattern Route guards protect authenticated routes: { path: 'cart', canActivate: [AuthGuard], component: CartComponent } 4. Interceptor Pattern HTTP interceptors handle cross-cutting concerns: Authentication token injection Error handling Loading states 5. Service Locator Pattern Services are registered at the root level and accessed via DI: @Injectable({ providedIn: 'root' }) export class ApiService { } Services & API Integration ApiService ( api.service.ts ) The main service handling all API communications. Base URLs // Production BASEURL = "https://onmarket.id/"; API_USERSTATE_SERVER = "https://usapi.onindonesia.id/"; API_USERONDELIVERY_SERVER = "https://onapps-api.onindonesia.id/"; API_OSAS_SERVER = "https://api.ondelivery.id/"; API_ONMARKET_SERVER = "https://api.onmarket.id/"; API_ONBOOKING_SERVER = "https://apisat.ondelivery.id/"; API_STORAGE = "https://storage.onindonesia.id/onmarket/"; Key Methods // User Authentication getUser(uname: string, pwd: string): Observable verify(token: string): Observable // Products getProductList(payload: ProductListPayload): Observable getProductDetail(id: string): Observable // Cart Management addToCart(payload: AddCart): Observable getCart(): Observable updateCart(cartId: string, quantity: number): Observable deleteCart(cartId: string): Observable // Orders createOrder(payload: any): Observable getOrders(): Observable SocketsService ( sockets.service.ts ) Handles real-time WebSocket connections using Socket.io. // Connect to WebSocket connect(): void // Disconnect disconnect(): void // Emit events emitEvent(eventName: string, data?: any): void // Listen to events on(eventName: string): Observable AffiliateService ( services/affiliate.service.ts ) Manages affiliate-specific functionality. LoggerService ( logger.service.ts ) Handles application logging with configurable log levels. Routing Structure Main Routes The application uses Angular Router with the following main routes: // Home & Product Routes { path: "", component: HomePageComponent } { path: "search", component: SearchResultComponent } { path: "product", component: ProductDetailsComponent } { path: "category", component: CategoryProductComponent } // Authentication Routes { path: "login", component: LoginComponent } { path: "signup", component: SignupComponent } { path: "signup/otp", component: VerifyPhoneOtpComponent } { path: "reset", component: ResetComponent } // Shopping Routes (Protected) { path: "cart", canActivate: [AuthGuard], component: CartComponent } { path: "checkout", canActivate: [AuthGuard], component: CheckoutComponent } { path: "checkout-finish", canActivate: [AuthGuard], component: CheckoutConfirmationComponent } // User Profile Routes (Protected) { path: "user", canActivate: [AuthGuard], component: ProfileComponent, children: [ { path: "profile/detail-profile", component: DetailProfileComponent }, { path: "profile/address", component: AddressComponent }, { path: "order", component: OrderComponent }, { path: "change-password", component: ChangePasswordsComponent }, { path: "chats", component: ChatComponent }, { path: "favorite", component: FavoriteComponent }, { path: "voucher", component: VoucherListComponent }, { path: "voucher/history", component: VoucherHistoryComponent } ] } // Store Routes { path: "store", component: PersonalStoreComponent, children: [ { path: "store-profile", component: StoreProfileComponent }, { path: "store-review", component: ReviewComponent }, { path: "store-product", component: ProductComponent } ] } // Affiliate Routes (Protected) { path: "affiliate", canActivate: [AuthGuard], component: AffiliateComponent, children: [ { path: "register", component: RegisterComponent }, { path: "", component: DashboardComponent, children: [ { path: "dashboard", component: HomeComponent }, { path: "commision", component: AffiliateWithdrawComponent }, { path: "collection", component: CollectionComponent }, { path: "payment-setting", component: PaymentSettingComponent } ] } ] } // Additional Routes { path: "about-us", component: AboutUsComponent } { path: "help", component: HelpComponent } { path: "faq", component: FaqTwoComponent } { path: "contact", component: ContactPageComponent } // 404 Route { path: "**", redirectTo: "/not-found" } { path: "/not-found", component: PageNotFoundComponent } Route Guards AuthGuard ( auth.guard.ts ) protects routes that require authentication: Checks for JWT token in localStorage Verifies token with API Redirects to home page if not authenticated State Management BehaviorSubjects The application uses RxJS BehaviorSubjects for state management: ApiService State isUpdateCart = new BehaviorSubject(true); deletedFromCart = new BehaviorSubject(true); login = new BehaviorSubject(true); SocketsService State private chatOpenSubject = new BehaviorSubject(false); chatOpen$ = this.chatOpenSubject.asObservable(); Local Storage Persistent data is stored in browser localStorage: jwt - Authentication token user - User information cart - Shopping cart data (backup) Usage Pattern // Subscribe to state changes this.apiService.isUpdateCart.subscribe( shouldUpdate => { if (shouldUpdate) { this.loadCart(); } } ); // Update state this.apiService.isUpdateCart.next(true); Authentication & Security JWT Authentication The application uses JWT (JSON Web Token) for authentication: Login Flow : // User logs in this.apiService.getUser(username, password).subscribe( response => { // Store JWT token localStorage.setItem('jwt', response.token); // Navigate to home this.router.navigate(['/']); } ); Token Storage : JWT tokens are stored in localStorage with key 'jwt' Token Injection : The AuthInterceptor automatically adds the token to all requests: const token = localStorage.getItem("jwt") ? `Bearer ${localStorage.getItem("jwt")}` : ""; const authReq = req.clone({ headers: req.headers.set("authorization", token) }); Token Verification : AuthGuard verifies tokens before allowing access to protected routes HTTP Interceptor ( auth.interceptor.ts ) Handles authentication and error responses: Features: Automatically adds JWT token to request headers Handles 401/403 unauthorized responses Redirects to login on session expiration Shows user-friendly error messages Clears localStorage on auth failure Error Handling: private handleAuthError(err: HttpErrorResponse): Observable { if (err.status === 401 || err.status === 403) { // Show error notification this.Toast.fire({ title: "Sesi berakhir, mohon login kembali", icon: "error" }); // Redirect to login this.router.navigate(["/login"]); // Clear token localStorage.removeItem("jwt"); } return throwError(err); } Security Best Practices Route Guards : Protect sensitive routes with AuthGuard Token Expiration : Tokens are verified on each protected route access Secure Communication : All API calls use HTTPS XSS Protection : Angular's built-in sanitization CSRF Protection : Handled by backend API Key Components 1. Homepage Component Path : src/app/components/homepage/ Main landing page featuring: Banner slider Product categories Featured products Promotions Flash sales 2. Product Details Component Path : src/app/components/product-details/ Displays detailed product information: Product images gallery Price and stock information Product description Seller information Reviews and ratings Add to cart functionality 3. Cart Component Path : src/app/components/cart/ Shopping cart management: List of cart items Quantity adjustment Item removal Price calculation Checkout navigation 4. Checkout Component Path : src/app/components/checkout/ Order completion process: Shipping address selection Payment method selection Order summary Order confirmation 5. Profile Component Path : src/app/components/accounts/profile/ User profile management with nested routes: Personal information Address book Order history Password change Favorites/wishlist Vouchers 6. Affiliate Dashboard Path : src/app/components/affiliate/dashboard/ Affiliate program features: Earnings dashboard with charts Commission history Withdrawal requests Collection management Affiliate links generation Payment settings 7. Search Result Component Path : src/app/components/search-result/ Product search functionality: Search input Filters (category, price, rating) Sort options Infinite scroll Result grid/list view 8. Personal Store Component Path : src/app/components/personal-store/ Store management: Store profile Product listing Store reviews Store statistics Custom Pipes 1. PhoneNumberPipe File : src/app/pipes/phone-number.pipe.ts Formats phone numbers according to Indonesian format. Usage : {{ phoneNumber | phoneNumber }} 2. ShortNumberPipe File : src/app/pipes/short-number-pipe.pipe.ts Converts large numbers to shortened format (e.g., 1000 → 1K). Usage : {{ largeNumber | shortNumber }} 3. TimeAgoPipe File : src/app/pipes/time-ago.pipe.ts Converts timestamps to relative time (e.g., "2 hours ago"). Usage : {{ timestamp | timeAgo }} 4. TransformCityPipe File : src/app/pipes/transform-city.pipe.ts Formats city names according to application standards. Usage : {{ cityName | transformCity }} 5. SafePipe File : src/app/safe.pipe.ts Bypasses Angular's security for trusted content (URLs, HTML, etc.). Usage : 6. NumberPipe File : src/app/number.pipe.ts Custom number formatting for Indonesian locale. Usage : {{ price | number }} Development Workflow Starting Development Server # For Unix/Linux/Mac npm start # For Windows npm run startWindows The app will automatically reload when you make changes to source files. Code Scaffolding Generate new components, services, etc. using Angular CLI: # Generate a new component ng generate component components/new-component # Generate a new service ng generate service services/new-service # Generate a new module ng generate module modules/new-module # Generate a new pipe ng generate pipe pipes/new-pipe # Generate a new directive ng generate directive directives/new-directive Linting Check code quality and style: npm run lint Building for Production npm run build Build artifacts will be stored in the dist/ directory. Build & Deployment Development Build npm run build Production Build ng build --configuration production Build Configuration Configured in angular.json : { "configurations": { "production": { "fileReplacements": [{ "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" }], "optimization": true, "outputHashing": "all", "sourceMap": false, "namedChunks": false, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, "budgets": [...] } } } Environment Variables Update environment files before building: Development ( src/environments/environment.ts ): export const environment = { production: false, enableConsoleLogs: true }; Production ( src/environments/environment.prod.ts ): export const environment = { production: true, enableConsoleLogs: false }; Deployment Options 1. Static Hosting (Recommended) Deploy to static hosting services: Firebase Hosting Netlify Vercel AWS S3 + CloudFront GitHub Pages 2. Web Server Deploy to traditional web servers: Apache Nginx IIS Important : Configure server to redirect all routes to index.html for Angular routing to work. Nginx Configuration Example: server { listen 80; server_name onmarket.id; root /var/www/onmarket/dist/sapp; index index.html; location / { try_files $uri $uri/ /index.html; } } Testing Unit Tests Run unit tests via Karma: npm test Tests are written using Jasmine and located alongside components: *.spec.ts files End-to-End Tests Run e2e tests via Protractor: npm run e2e E2E tests are located in the e2e/ directory. Test Configuration Karma : karma.conf.js Protractor : e2e/protractor.conf.js TypeScript : tsconfig.spec.json Writing Tests Example component test: describe('CartComponent', () => { let component: CartComponent; let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [ CartComponent ] }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(CartComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); it('should load cart items', () => { component.loadCart(); expect(component.cartItems.length).toBeGreaterThan(0); }); }); Code Style & Conventions TypeScript Style Guide Follow Angular's TypeScript style guide: Use 2 spaces for indentation Use single quotes for strings Use camelCase for variables and functions Use PascalCase for classes and interfaces Use UPPER_CASE for constants Component Structure @Component({ selector: 'app-example', templateUrl: './example.component.html', styleUrls: ['./example.component.css'] }) export class ExampleComponent implements OnInit { // 1. Public properties public title: string; // 2. Private properties private data: any[]; // 3. Constructor with DI constructor( private apiService: ApiService, private router: Router ) {} // 4. Lifecycle hooks ngOnInit(): void { this.loadData(); } // 5. Public methods loadData(): void { // Implementation } // 6. Private methods private processData(data: any): void { // Implementation } } Naming Conventions Components : feature-name.component.ts Services : feature-name.service.ts Pipes : pipe-name.pipe.ts Guards : guard-name.guard.ts Interfaces : interface-name.ts Modules : module-name.module.ts Template Guidelines
Loading...
  • {{ item.name }}
SCSS/CSS Guidelines Use component-scoped styles Follow BEM naming convention for complex components Use Angular Material theming Avoid !important unless absolutely necessary Troubleshooting Common Issues and Solutions 1. OpenSSL Error on npm start Error : Error: error:0308010C:digital envelope routines::unsupported Solution : The project already includes the fix in package.json: NODE_OPTIONS='--openssl-legacy-provider' ng serve 2. Module Not Found Errors Solution : Clear cache and reinstall: rm -rf node_modules package-lock.json npm cache clean --force npm install 3. Port Already in Use Error : Port 4200 is already in use Solution : Kill the process or use a different port: # Kill process on port 4200 (Unix/Mac) lsof -ti:4200 | xargs kill -9 # Or use different port ng serve --port 4300 4. CORS Errors Issue : API requests blocked by CORS policy Solution : Configure backend to allow frontend origin Use proxy configuration during development: Create proxy.conf.json : { "/api": { "target": "https://api.onmarket.id", "secure": true, "changeOrigin": true } } Update angular.json : "serve": { "options": { "proxyConfig": "proxy.conf.json" } } 5. JWT Token Expired Issue : Session expired errors Solution : Token verification happens on each protected route User is automatically redirected to login No manual intervention needed 6. WebSocket Connection Issues Issue : Socket.io connection fails Solution : Check if WebSocket server is running Verify JWT token is valid Check network connectivity Verify API_ONMARKET_SERVER URL 7. Angular Material Theme Not Applied Solution : Ensure custom-theme.scss is imported in angular.json : "styles": [ "src/custom-theme.scss", "src/styles.scss" ] 8. Build Memory Issues Error : JavaScript heap out of memory Solution : Increase Node.js memory limit: export NODE_OPTIONS="--max-old-space-size=4096" npm run build Additional resources Official Documentation Angular Documentation Angular Material RxJS TypeScript Key Dependencies Documentation Socket.io Client ApexCharts SweetAlert2 Google Maps JavaScript API Learning Resources Angular Tutorial Angular University RxJS Marbles Community Angular GitHub Stack Overflow - Angular