Skip to content

snoiclub/rekomendasi

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

15 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Rekomendasi

A web application for recommending Segway Ninebot scooters based on user preferences through an interactive quiz system.

Prerequisites

Before getting started, make sure you have installed:

  • Node.js
  • npm, yarn, or pnpm as package manager

Installation

  1. Clone the repository (if you haven't):
git clone https://github.com/snoiclub/rekomendasi.git
cd rekomendasi
  1. Install dependencies:
npm install

or if using yarn:

yarn install

or if using pnpm:

pnpm install

Running the Application

Development Mode

Run the application in development mode:

npm run dev

The application will run at http://localhost:3000

Open your browser and access the URL to view the application.

Build for Production

To create a production build:

npm run build

Running Production Build

After the build completes, run:

npm start

Linting

To check code with ESLint:

npm run lint

Type Checking

To check TypeScript types:

npm run type-check

πŸ“ Project Structure

rekomendasi/
β”œβ”€β”€ public/
β”‚   └── images/                 # Scooter images
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app/                    # Next.js App Router
β”‚   β”‚   β”œβ”€β”€ layout.tsx          # Main layout
β”‚   β”‚   β”œβ”€β”€ page.tsx            # Home page
β”‚   β”‚   └── globals.css         # Global styles
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   └── Recommendation.tsx  # Main quiz & recommendation component
β”‚   β”œβ”€β”€ data/
β”‚   β”‚   β”œβ”€β”€ quiz-questions.ts   # Quiz questions data
β”‚   β”‚   β”œβ”€β”€ scooters.ts         # Scooter list data
β”‚   β”‚   └── type/               # JSON files for each scooter
β”‚   β”‚       β”œβ”€β”€ e2_e.json
β”‚   β”‚       β”œβ”€β”€ e2_e_ii.json
β”‚   β”‚       └── ...
β”‚   └── utils/
β”‚       └── scoring.ts          # Scoring & recommendation algorithm
β”œβ”€β”€ next.config.js              # Next.js configuration
β”œβ”€β”€ tailwind.config.js          # Tailwind CSS configuration
β”œβ”€β”€ tsconfig.json               # TypeScript configuration
└── package.json                # Dependencies & scripts

Adding New Scooter Data

To add a new scooter to the system:

1. Create JSON File

Create a new file in src/data/type/ with the naming format: {model_name}.json

Example: src/data/type/e4_pro_e.json

2. Fill JSON Data

Use the following format as a template:

{
  "id": "e4_pro_e",
  "name": "Ninebot E4 Pro E",
  "brand": "Segway",
  "price_min_juta": 12,
  "price_max_juta": 15,
  "battery_capacity_wh": 350,
  "motor_power_nominal_w": 300,
  "motor_power_max_w": 500,
  "max_speed_kmh": 25,
  "max_range_km": 40,
  "max_payload_kg": 100,
  "unit_weight_kg": 16,
  "foldable": true,
  "front_brake": "mechanical_disc",
  "rear_brake": "drum",
  "tire_size_inch": 10,
  "tire_type": "tubeless",
  "suspension": "front",
  "ip_body": "IPX5",
  "ip_battery": "IPX5",
  "dimensions_open_mm": "1100 x 450 x 1200",
  "dimensions_folded_mm": "1100 x 450 x 520",
  "official_service": true,
  "image_url": "/images/e4_pro_e.png",
  "description": "Scooter description...",
  "pros": [
    "Advantage 1",
    "Advantage 2"
  ],
  "cons": [
    "Disadvantage 1"
  ],
  "warnings": []
}

3. Add Image

Add the scooter image to the public/images/ folder with a name matching the image_url in the JSON (example: e4_pro_e.png)

4. Import and Add to Array

Open src/data/scooters.ts and:

  1. Import the newly created JSON file:
import e4_pro_e from './type/e4_pro_e.json';
  1. Add it to the SCOOTERS array:
export const SCOOTERS: Scooter[] = [
  // ... other scooters
  e4_pro_e as Scooter,
];

5. Required and Optional Fields

Required Fields:

  • id: Unique scooter ID (string)
  • name: Scooter name (string)
  • brand: Scooter brand (string)
  • foldable: Whether it can be folded (boolean)
  • front_brake: Front brake type (string)
  • rear_brake: Rear brake type (string)
  • tire_type: Tire type (string)
  • suspension: Suspension type (string)
  • official_service: Whether official service is available (boolean)
  • description: Scooter description (string)
  • pros: Array of advantages (string[])
  • cons: Array of disadvantages (string[])

Optional Fields (can be null):

  • price_min_juta, price_max_juta
  • battery_capacity_wh
  • motor_power_nominal_w, motor_power_max_w
  • max_speed_kmh
  • max_range_km
  • max_payload_kg
  • unit_weight_kg
  • tire_size_inch
  • ip_body, ip_battery
  • dimensions_open_mm, dimensions_folded_mm
  • image_url
  • warnings: Array of warnings (string[])

Modifying Quiz Questions

To add or modify quiz questions, edit the src/data/quiz-questions.ts file.

Question Structure

{
  id: 'question_id',                // Unique question ID
  question: 'Question?',            // Question text
  description: 'Description...',    // Additional description (optional)
  type: 'single' | 'multiple',      // Type: single choice or multiple choice
  required: true,                   // Whether it's required
  options: [
    {
      id: 'option_id',
      label: 'Option Label',
      value: 'value',               // Value to be stored
      affects: [                    // Array of affected fields
        'max_range_km',
        'battery_capacity_wh'
      ]
    }
  ]
}

Example: Adding a New Question

{
  id: 'budget_range',
  question: 'What is your budget?',
  description: 'Budget affects model recommendations',
  type: 'single',
  required: true,
  options: [
    {
      id: 'budget_lt_10',
      label: '<10 million',
      value: 'lt_10',
      affects: ['price_min_juta', 'price_max_juta']
    },
    {
      id: 'budget_10_15',
      label: '10-15 million',
      value: '10_15',
      affects: ['price_min_juta', 'price_max_juta']
    }
  ]
}

Add the new question to the QUIZ_QUESTIONS array in the same file.

Scoring Algorithm

The scoring algorithm calculates the match between quiz answers and scooter specifications. Scores are calculated based on several categories with specific weights:

Scoring Categories

  1. Battery (30%): Matches scooter range with daily distance needs
  2. Motor (30%): Matches motor power with rider weight and road terrain
  3. Features (20%): Matches features like speed, tires, brakes, suspension, IP rating
  4. Size (10%): Matches size/weight with user preferences
  5. Usage (10%): Matches usage type (commuter, hobby, long distance)

Total Score Formula

Total Score = (Battery Γ— 0.30) + (Motor Γ— 0.30) + (Features Γ— 0.20) + (Size Γ— 0.10) + (Usage Γ— 0.10)

Matching Logic

  • Range Matching: If scooter range β‰₯ requirement, score 100. If less, proportional score.
  • Motor Power Matching: If motor power β‰₯ requirement, score 100. If less, proportional score.
  • Feature Matching: Each matching feature adds to score, mismatches generate warnings.
  • Size Matching: Matching size = 100, not matching = 50.
  • Usage Matching: Matching usage type = 100, not matching = 60.

Adjusting the Algorithm

To adjust the scoring algorithm, edit the src/utils/scoring.ts file:

  • Change category weights in the calculateScores() function (around line ~303-308)
  • Add new matching logic in the same function
  • Adjust helper functions like getRequiredRange(), getRequiredMotorPower(), etc.

Made with ❀️ by SNOI DevHub

About

Rekomendasi scooter untuk kebutuhan harianmu

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages