diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchController.java b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchController.java
index 167b19df6fce765706dc4f6945e12407ee7f87ca..7187714d98bf0645345a1cc3befbd6055567acba 100644
--- a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchController.java
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchController.java
@@ -2,11 +2,8 @@ package uk.ac.cf.spring.demo.sports.match;
 
 import org.springframework.beans.factory.annotation.Autowired;
 //import org.springframework.stereotype.Controller;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.bind.annotation.*;
+//import org.springframework.web.servlet.ModelAndView;
 
 import java.util.List;
 @RestController
@@ -23,11 +20,33 @@ public class MatchController {
     public List<MatchItem> getAllMenuItems() {
         return matchService.getMatchItems();
     }
+    //  get Match by id
     @GetMapping("/{id}")
     public MatchItem getMenuItem(@PathVariable Long id) {
         return matchService.getMatchItemById(id);
     }
-//    @GetMapping("/match")
+
+    // add
+    @PostMapping
+    public void addMatchItem(@RequestBody MatchItem matchItem) {
+        matchService.addMatchItem(matchItem);
+    }
+
+    // update
+    @PutMapping("/{id}")
+    public void updateMatchItem(@PathVariable Long id, @RequestBody MatchItem matchItem) {
+        matchItem.setId(id);
+        matchService.updateMatchItem(matchItem);
+    }
+
+    //delete
+    @DeleteMapping("/{id}")
+    public void deleteMatchItem(@PathVariable Long id) {
+        matchService.deleteMatchItem(id);
+    }
+
+
+    //    @GetMapping("/match")
 //    public ModelAndView getMatch() {
 //        ModelAndView modelAndView = new ModelAndView("match/allMatchList");
 //        List<MatchItem> matchItems = matchService.getMatchItems();
@@ -41,39 +60,38 @@ public class MatchController {
 //        MatchItem matchItem = matchService.getMatchItemById(id);
 //        modelAndView.addObject("matchItem", matchItem);
 //        return modelAndView;
+//    }//matchItemForm add match
+//    @GetMapping("/match/add")
+//    public ModelAndView addMatchItem() {
+//        ModelAndView modelAndView = new ModelAndView("match/matchItemForm");
+//        MatchItemForm emptyMatchItem = new MatchItemForm();
+//        modelAndView.addObject("matchItem", emptyMatchItem);
+//        return modelAndView;
 //    }
-    //matchItemForm add match
-    @GetMapping("/match/add")
-    public ModelAndView addMatchItem() {
-        ModelAndView modelAndView = new ModelAndView("match/matchItemForm");
-        MatchItemForm emptyMatchItem = new MatchItemForm();
-        modelAndView.addObject("matchItem", emptyMatchItem);
-        return modelAndView;
-    }
 
     //
-    @GetMapping("/match/edit/{id}")
-    public ModelAndView editMatchItemTh(@PathVariable("id") Long id) {
-        ModelAndView modelAndView = new ModelAndView("match/matchItemForm");
-        // construct matchToUpdate object to get matchItem by id
-        MatchItem matchToUpdate = matchService.getMatchItemById(id);
-        // Create the form object for the match
-        MatchItemForm matchItemForm = new MatchItemForm(
-                matchToUpdate.getId(),
-                matchToUpdate.getSport(),
-                matchToUpdate.getPlayerAId(),
-                matchToUpdate.getPlayerBId(),
-                matchToUpdate.getPlanTime(),
-                matchToUpdate.getStatus(),
-                matchToUpdate.getScoreA(),
-                matchToUpdate.getScoreB(),
-                matchToUpdate.getConfirmByA(),
-                matchToUpdate.getConfirmByB(),
-                matchToUpdate.getWinnerId()
-        );
-
-        modelAndView.addObject("matchItem", matchItemForm);
-        return modelAndView;
-    }
+//    @GetMapping("/match/edit/{id}")
+//    public ModelAndView editMatchItemTh(@PathVariable("id") Long id) {
+//        ModelAndView modelAndView = new ModelAndView("match/matchItemForm");
+//        // construct matchToUpdate object to get matchItem by id
+//        MatchItem matchToUpdate = matchService.getMatchItemById(id);
+//        // Create the form object for the match
+//        MatchItemForm matchItemForm = new MatchItemForm(
+//                matchToUpdate.getId(),
+//                matchToUpdate.getSport(),
+//                matchToUpdate.getPlayerAId(),
+//                matchToUpdate.getPlayerBId(),
+//                matchToUpdate.getPlanTime(),
+//                matchToUpdate.getStatus(),
+//                matchToUpdate.getScoreA(),
+//                matchToUpdate.getScoreB(),
+//                matchToUpdate.getConfirmByA(),
+//                matchToUpdate.getConfirmByB(),
+//                matchToUpdate.getWinnerId()
+//        );
+//
+//        modelAndView.addObject("matchItem", matchItemForm);
+//        return modelAndView;
+//    }
 
 }
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepository.java b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepository.java
index e25408f8bf46eb57b5b6a25e5a1ad04ed6352e49..cdce9b7b21fef6deebe0059a0648f9a000ec4415 100644
--- a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepository.java
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepository.java
@@ -11,5 +11,9 @@ public interface MatchRepository {
     List<MatchItem> getMatchItemBySport(String sport);
 //   add MatchItem
     void addMatchItem(MatchItem matchItem);
+//    update MatchItem
+    void updateMatchItem(MatchItem matchItem);
+//    delete MatchItem
+    void deleteMatchItem(Long id);
 
 }
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepositoryImpl.java b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepositoryImpl.java
index 03556e55369d344ef0c2afd62a2269e99a5686cd..ec8c33707ebfb0fbe4c0a0776915d32745ea44fe 100644
--- a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepositoryImpl.java
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchRepositoryImpl.java
@@ -9,7 +9,7 @@ import java.util.List;
 @Repository
 public class MatchRepositoryImpl implements MatchRepository{
 //    jdbcTemplate - dependency injection
-    private JdbcTemplate jdbc;
+    private final JdbcTemplate jdbc;
     private RowMapper<MatchItem> matchItemMapper;
     public MatchRepositoryImpl(JdbcTemplate aJdbc) {
         this.jdbc = aJdbc;
@@ -70,4 +70,28 @@ public class MatchRepositoryImpl implements MatchRepository{
                 matchItem.getWinnerId()
         );
     }
+
+    @Override
+    public void updateMatchItem(MatchItem matchItem) {
+        String sql = "update match_item set sport = ?, player_AId = ?, player_BId = ?, plan_Time = ?, status = ?, score_a = ?, score_b = ?, confirm_a = ?, confirm_b = ?, winner_id = ? where id = ?";
+        jdbc.update(sql,
+                matchItem.getSport(),
+                matchItem.getPlayerAId(),
+                matchItem.getPlayerBId(),
+                Timestamp.valueOf(matchItem.getPlanTime()),
+                matchItem.getStatus(),
+                matchItem.getScoreA(),
+                matchItem.getScoreB(),
+                matchItem.getConfirmByA(),
+                matchItem.getConfirmByB(),
+                matchItem.getWinnerId(),
+                matchItem.getId()
+        );
+    }
+
+    @Override
+    public void deleteMatchItem(Long id) {
+        String sql = "DELETE FROM match_item WHERE id = ?";
+        jdbc.update(sql, id);
+    }
 }
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchService.java b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchService.java
index 9b784ce149c64ad144f365af77a07c4a16037d81..bd0900e3b2dda196774ed77f2e6cd77276bcfda7 100644
--- a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchService.java
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchService.java
@@ -11,4 +11,8 @@ public interface MatchService {
     List<MatchItem> getMatchItemBySport(String sport);
     //   add MatchItem
     void addMatchItem(MatchItem matchItem);
+    //  update MatchItem
+    void updateMatchItem(MatchItem matchItem);
+    // delete MatchItem
+    void deleteMatchItem(Long id);
 }
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchServiceListImpl.java b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchServiceListImpl.java
index 723d174b5062bd4815e92c776db5d5fc750ccc66..8c17f955a87680877d0aa9a74bc5535d4f501f0f 100644
--- a/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchServiceListImpl.java
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/match/MatchServiceListImpl.java
@@ -27,9 +27,28 @@ public class MatchServiceListImpl implements MatchService{
     public List<MatchItem> getMatchItemBySport(String sport) {
         return matchRepository.getMatchItemBySport(sport);
     }
-
+    //    add
     @Override
     public void addMatchItem(MatchItem matchItem) {
         matchRepository.addMatchItem(matchItem);
     }
+    // update
+    @Override
+    public void updateMatchItem(MatchItem matchItem) {
+        if (matchItem.getId() == null || matchItem.getId() <= 0) {
+            throw new IllegalArgumentException("Invalid Match Item ID");
+        }
+        MatchItem existingItem = matchRepository.getMatchItemById(matchItem.getId());
+        if (existingItem != null) {
+            matchRepository.updateMatchItem(matchItem);
+        } else {
+            throw new IllegalArgumentException("Match item not found");
+        }
+
+    }
+    // delete
+    @Override
+    public void deleteMatchItem(Long id) {
+            matchRepository.deleteMatchItem(id);
+    }
 }
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingController.java b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingController.java
new file mode 100644
index 0000000000000000000000000000000000000000..51b0dbb4d593a1d6d8aa744cc12a77a65eaaa06c
--- /dev/null
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingController.java
@@ -0,0 +1,48 @@
+package uk.ac.cf.spring.demo.sports.rankingtable;
+
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/rankings") // 公共路径
+public class RankingController {
+    private final RankingService rankingService;
+
+    public RankingController(RankingService rankingService) {
+        this.rankingService = rankingService;
+    }
+
+    /**
+     * get all rankings
+     *
+     * @return all rankings
+     */
+    @GetMapping
+    public List<RankingTable> getAllRankings() {
+        return rankingService.getAllRankings();
+    }
+    @GetMapping("/byallandsort")
+    public List<TotalWinsDTO> getRankingsByAllSort(String order) {
+        //rankingService.processCompletedMatches();
+        return rankingService.getTotalWinsByAll(order);
+
+    }
+
+    /**
+     * get rankings filtered by sports and wins
+     *
+     * @return rankings
+     */
+    @GetMapping("/bysportandsort")
+    public List<RankingTable> getRankingsBySportAndOrder(
+            @RequestParam(required = false) String sport,
+            @RequestParam(defaultValue = "desc") String order
+    ) {
+        //rankingService.processCompletedMatches();
+        return rankingService.getRankingsBySportAndOrder(sport, order);
+    }
+
+
+
+}
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingRepository.java b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingRepository.java
new file mode 100644
index 0000000000000000000000000000000000000000..884f5637d825fd96543d89ef23b96a02ba025b2c
--- /dev/null
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingRepository.java
@@ -0,0 +1,133 @@
+package uk.ac.cf.spring.demo.sports.rankingtable;
+
+import lombok.Getter;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+@Repository
+
+public class RankingRepository {
+    public List<RankingTable> findBySportAndOrder(String sport, String order) {
+        // 确保 order 参数是有效值
+        if (!"asc".equalsIgnoreCase(order) && !"desc".equalsIgnoreCase(order)) {
+            order = "desc";
+        }
+
+        String sql = "SELECT * FROM ranking WHERE sport = ? ORDER BY wins " + order.toUpperCase();
+        return jdbcTemplate.query(sql, mapRowToRanking(), sport);
+    }
+
+
+    @Getter
+    public static class MatchResult {
+        private final Long winnerId;
+        private final String sport;
+
+        public MatchResult(Long winnerId, String sport) {
+            this.winnerId = winnerId;
+            this.sport = sport;
+        }
+
+    }
+
+    private final JdbcTemplate jdbcTemplate;
+
+
+    public RankingRepository(JdbcTemplate jdbcTemplate) {
+        this.jdbcTemplate = jdbcTemplate;
+    }
+
+    // get all rankings sql code
+    public List<RankingTable> findAll() {
+        String sql = "SELECT * FROM ranking";
+        return jdbcTemplate.query(sql, mapRowToRanking());
+    }
+
+    public List<RankingTable> findBySport(String sport) {
+        System.out.println(sport);
+        String sql = "SELECT * FROM ranking WHERE sport = ?";
+        return jdbcTemplate.query(sql, mapRowToRanking(), sport);
+    }
+
+
+    // get ranking by userid and sport
+    public RankingTable findByUserIdAndSport(Long userId, String sport) {
+        String sql = "SELECT * FROM ranking WHERE user_id = ? AND sport = ?";
+        return jdbcTemplate.queryForObject(sql, mapRowToRanking(), userId, sport);
+    }
+
+    // update rankings
+    public void saveOrUpdate(Long userId, String sport, int newWins) {
+        String sql = """
+            INSERT INTO ranking (user_id, sport, wins)
+            VALUES (?, ?, ?)
+            ON DUPLICATE KEY UPDATE wins = ?
+        """;
+        jdbcTemplate.update(sql, userId, sport, newWins, newWins);
+    }
+
+
+    // get result from match where status is completed
+    public List<MatchResult> findWinnersAndSportsFromCompletedMatches() {
+        String sql = """
+            SELECT winner_id, sport
+            FROM match_item
+            WHERE status = 'completed'
+        """;
+        return jdbcTemplate.query(sql, (rs, rowNum) -> new MatchResult(
+                rs.getLong("winnerId"),
+                rs.getString("sport")
+
+        ));
+    }
+    public List<RankingTable> findAllSortedByWins(String order) {
+        // 确保order参数的值是"asc"或"desc",如果不是则默认为"desc"
+        if (order == null || (!order.equalsIgnoreCase("asc") && !order.equalsIgnoreCase("desc"))) {
+            order = "asc";  // 默认降序
+        }
+
+        String sql = "SELECT * FROM ranking ORDER BY wins " + order.toUpperCase();
+        return jdbcTemplate.query(sql, mapRowToRanking());
+    }
+    //总胜利数查询
+    public List<TotalWinsDTO> findTotalWinsByAll(String order) {
+        // 验证 order 参数是否合法,只允许 "asc" 或 "desc"
+        String sortOrder = "desc"; // 默认值
+        if ("asc".equalsIgnoreCase(order)) {
+            sortOrder = "asc";
+        }
+
+        String sql = "SELECT user_id,username,'totalwins' AS sport, SUM(wins) AS wins FROM ranking GROUP BY user_id ORDER BY wins "  + sortOrder;
+
+
+        return jdbcTemplate.query(sql, mapRowToTotalWinsDTO());
+    }
+
+    // a function can merge result into a ranking
+    private RowMapper<RankingTable> mapRowToRanking() {
+        return (rs, rowNum) -> {
+            RankingTable ranking = new RankingTable();
+            ranking.setId(rs.getLong("id"));  // 映射 id
+            ranking.setUserId(rs.getLong("user_id"));  // 映射 user_id
+            ranking.setSport(rs.getString("sport"));  // 映射 sport
+            ranking.setWins(rs.getInt("wins"));  // 映射 wins
+            ranking.setUsername(rs.getString("username"));  // 映射 username
+            return ranking;
+        };
+    }
+    //聚合查询专用映射方法
+    private RowMapper<TotalWinsDTO> mapRowToTotalWinsDTO() {
+        return (rs, rowNum) -> {
+            TotalWinsDTO dto = new TotalWinsDTO();
+            dto.setUsername(rs.getString("username"));
+            dto.setUserId(rs.getLong("user_id"));
+            dto.setSport("totalwins"); // 聚合查询时 sport 固定为 "totalwins"
+            dto.setWins(rs.getInt("wins"));
+            return dto;
+        };
+    }
+
+}
+
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingService.java b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingService.java
new file mode 100644
index 0000000000000000000000000000000000000000..9eacf144a6cb4bc211c818881e09fa789fa405b1
--- /dev/null
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingService.java
@@ -0,0 +1,28 @@
+package uk.ac.cf.spring.demo.sports.rankingtable;
+
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+@Service
+
+public interface RankingService {
+
+    List<RankingTable> getAllRankings();
+
+
+    List<RankingTable> getRankingsBySport(String sport);
+
+
+    void updateRanking(Long userId, String sport, int wins);
+
+
+    void processCompletedMatches();
+
+    List<RankingTable> getAllRankingsSortedByWins(String order);
+
+    List<RankingTable> getRankingsBySportAndOrder(String sport, String order);
+
+    List<TotalWinsDTO> getTotalWinsByAll(String order);
+
+
+}
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingServiceImpl.java b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f352391d40b2050a2878b0442538d623ad2156b
--- /dev/null
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingServiceImpl.java
@@ -0,0 +1,72 @@
+package uk.ac.cf.spring.demo.sports.rankingtable;
+
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class RankingServiceImpl implements RankingService {
+    private final RankingRepository rankingRepository;
+
+    public RankingServiceImpl(RankingRepository rankingRepository) {
+        this.rankingRepository = rankingRepository;
+    }
+
+
+    @Override
+    public List<RankingTable> getAllRankings() {
+        return rankingRepository.findAll();
+    }
+
+
+    @Override
+    public List<RankingTable> getRankingsBySport(String sport) {
+        return rankingRepository.findBySport(sport);
+    }
+
+
+    @Override
+    public void updateRanking(Long userId, String sport, int wins) {
+        rankingRepository.saveOrUpdate(userId, sport, wins);
+    }
+
+
+    @Override
+    public void processCompletedMatches() {
+
+        List<RankingRepository.MatchResult> completedMatches = rankingRepository.findWinnersAndSportsFromCompletedMatches();
+
+        // loop every match result
+        for (RankingRepository.MatchResult result : completedMatches) {
+            Long winnerId = result.getWinnerId();
+            String sport = result.getSport();
+
+            // current user wins in particular sport
+            RankingTable currentRanking = rankingRepository.findByUserIdAndSport(winnerId, sport);
+            int currentWins = currentRanking != null ? currentRanking.getWins() : 0;
+
+            // update
+            rankingRepository.saveOrUpdate(winnerId, sport, currentWins + 1);
+        }
+    }
+    @Override
+    public List<RankingTable> getAllRankingsSortedByWins(String order) {
+        return rankingRepository.findAllSortedByWins(order);
+    }
+
+    @Override
+    public List<RankingTable> getRankingsBySportAndOrder(String sport, String order) {
+        if (sport == null || sport.equalsIgnoreCase("all")) {
+            // 如果没有选择特定运动,则按总胜利数排序
+            return rankingRepository.findAllSortedByWins(order);
+        } else {
+            // 按特定运动和排序方式筛选
+            return rankingRepository.findBySportAndOrder(sport, order);
+        }
+    }
+    public List<TotalWinsDTO> getTotalWinsByAll(String order) {
+        return rankingRepository.findTotalWinsByAll(order);
+    }
+
+}
+
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingTable.java b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingTable.java
new file mode 100644
index 0000000000000000000000000000000000000000..f483afac15c65f4f23af743f9b9574b68ecb38cf
--- /dev/null
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/RankingTable.java
@@ -0,0 +1,17 @@
+package uk.ac.cf.spring.demo.sports.rankingtable;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+@Data
+@NoArgsConstructor
+
+public class RankingTable {
+    //create entity class
+    private Long id;       //
+    private Long userId;   // 用户 ID
+    private int wins;      // 获胜场次
+    private String sport;
+    private String username;
+
+}
+
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/TotalWinsDTO.java b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/TotalWinsDTO.java
new file mode 100644
index 0000000000000000000000000000000000000000..2107882393bd1837776695ff41475fdea3a11927
--- /dev/null
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/rankingtable/TotalWinsDTO.java
@@ -0,0 +1,12 @@
+package uk.ac.cf.spring.demo.sports.rankingtable;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+@Data
+@NoArgsConstructor
+
+public class TotalWinsDTO {
+    private Long userId;
+    private String sport;
+    private Integer wins;
+    private String username;
+}
diff --git a/src/main/java/uk/ac/cf/spring/demo/sports/security/SecurityConfig.java b/src/main/java/uk/ac/cf/spring/demo/sports/security/SecurityConfig.java
index 7080a81636a8aac0d2384a24959029f1bd257a58..8069727926f844c9599be21513619f97ad7444df 100644
--- a/src/main/java/uk/ac/cf/spring/demo/sports/security/SecurityConfig.java
+++ b/src/main/java/uk/ac/cf/spring/demo/sports/security/SecurityConfig.java
@@ -27,7 +27,8 @@ public class SecurityConfig {
             "/html/**",         // static HTML
             "/html/register.html",        // register
             "/html/login.html",  // login
-            "/rankings",
+            "/html/login.html" , // login
+            "/rankings",          //ranking data path
             "/rankings/**"
     };
 
diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql
index a972476b4317082773551cdcacb0cec991ddce5c..20f0049e108b141d5cabd5e5a74c4afb4ee87063 100644
--- a/src/main/resources/data.sql
+++ b/src/main/resources/data.sql
@@ -1,4 +1,5 @@
 delete from match_item;
+delete from ranking;
 insert into match_item (sport, player_AId, player_BId, plan_Time, status, score_a, score_b, confirm_a, confirm_b, winner_id)
 values
 --     test data
@@ -14,3 +15,9 @@ values
     ('Darts', 1, 2, '2024-11-29 15:30:00', 'completed', 300, 280, TRUE, TRUE, 2),
 -- 6: Confirmed status, Player 1 wins
     ('TableTennis', 1, 2, '2024-11-30 17:00:00', 'confirmed', 3, 1, TRUE, TRUE, 1);
+INSERT INTO ranking (user_id,username,sport, wins) VALUES
+                                                (1, 'xzc','Pools', 5),
+                                                (2, 'shy','Darts', 3),
+                                                (3, 'xx','TableTennis', 10),
+                                                (2, 'shy','TableTennis', 4);
+
diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql
index cdaafc342af5058ecb92c48686a23aaa4732fe7c..5b0ebe8fc11112f5182b1a8e7c81f6628c3c0efb 100644
--- a/src/main/resources/schema.sql
+++ b/src/main/resources/schema.sql
@@ -1,4 +1,5 @@
 drop table if exists match_item;
+drop table if exists rankings;
 create table if not exists match_item (
     -- Match ID
     id BIGINT AUTO_INCREMENT PRIMARY KEY,
@@ -24,4 +25,21 @@ CREATE TABLE information (
                              email VARCHAR(50) UNIQUE NOT NULL,
                              password VARCHAR(255) NOT NULL,
                              role VARCHAR(20) DEFAULT 'USER' NOT NULL
-);
\ No newline at end of file
+);
+CREATE TABLE IF NOT EXISTS ranking (
+                                        id INT AUTO_INCREMENT PRIMARY KEY,
+                                        user_id INT NOT NULL,
+                                        sport ENUM('Pools', 'Darts', 'TableTennis') NOT NULL,
+                                        wins INT DEFAULT 0,
+                                        username VARCHAR(255)DEFAULT NULL
+
+
+
+
+);
+CREATE TABLE images (
+                        id INT AUTO_INCREMENT PRIMARY KEY,
+                        filename VARCHAR(255) NOT NULL,  -- 图片文件名或路径
+                        uploader VARCHAR(100) NOT NULL,  -- 上传者名称
+                        upload_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 上传时间
+);
diff --git a/src/main/resources/static/css/backGroundMatch.css b/src/main/resources/static/css/backGroundMatch.css
new file mode 100644
index 0000000000000000000000000000000000000000..8e40e3b8970e757b6914c9eb8b94ae2915a08468
--- /dev/null
+++ b/src/main/resources/static/css/backGroundMatch.css
@@ -0,0 +1,46 @@
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+}
+h1, h2 {
+    color: darkblue;
+}
+#matchForm {
+    /*display: grid;*/
+    align-items: center;
+}
+form input, form button {
+    margin: 5px;
+    padding: 10px;
+    font-size: 14px;
+
+}
+
+table {
+    width: 100%;
+    border-collapse: collapse;
+    margin-top: 20px;
+    border: 1px solid white;
+}
+
+th, td {
+    padding: 10px;
+    text-align: left;
+    border: 1px solid white;
+}
+
+button {
+    background-color: dodgerblue;
+    color: white;
+    border: none;
+    border-radius: 10px;
+    cursor: pointer;
+    margin: 5px;
+    padding: 10px;
+    width: 60px;
+}
+
+button:hover {
+    background-color: cornflowerblue;
+}
diff --git a/src/main/resources/static/css/footer.css b/src/main/resources/static/css/footer.css
index 9e7d27ae331e6de627995dafb11679dd7e8849c2..c4616f08f9410f2f4966569a942f600258905f4e 100644
--- a/src/main/resources/static/css/footer.css
+++ b/src/main/resources/static/css/footer.css
@@ -1,4 +1,3 @@
-
 * {
     margin: 0;
     padding: 0;
diff --git a/src/main/resources/static/css/matchDetail.css b/src/main/resources/static/css/matchDetail.css
new file mode 100644
index 0000000000000000000000000000000000000000..d46cdf49bc4bab984e61f67a36a39187d8ba85d4
--- /dev/null
+++ b/src/main/resources/static/css/matchDetail.css
@@ -0,0 +1,93 @@
+
+* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+}
+
+body {
+    font-family: Arial, sans-serif;
+    background-color: #f4f4f4;
+    color: #333;
+}
+.title-h1{
+    h1 {
+        background-color: #4a4a4a;
+        p {
+            font-size: 36px;
+            color: white;
+
+            font-weight: bold;
+            text-align: center;
+        }
+
+    }
+}
+.container {
+    width: 80%;
+    margin: 20px auto;
+}
+
+header {
+    text-align: center;
+    margin-bottom: 30px;
+}
+#matchDetails {
+    margin-left: 45px;
+    align-items: center;
+    background-color: #fff;
+    border-radius: 12px;
+    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+    width: 100%;
+    max-width: 900px;
+    padding: 30px;
+    box-sizing: border-box;
+    margin-top: 30px;
+}
+
+h2 {
+    text-align: center;
+    font-size: 2.5em;
+    color: #333;
+    margin-bottom: 20px;
+}
+
+#matchScore {
+    font-size: 2.4em;
+    line-height: 1.6;
+    color: #444;
+    margin: 20px 0;
+}
+
+#matchScore p {
+    text-align: center;
+}
+
+#matchInfo {
+    font-size: 1.2em;
+    line-height: 1.6;
+    color: #444;
+}
+
+#matchInfo p {
+    margin: 15px 0;
+    padding: 10px;
+    background-color: #f9f9f9;
+    border-radius: 6px;
+}
+
+strong {
+    color: #2d2d2d;
+}
+/*adjust for phone*/
+@media screen and (max-width: 768px) {
+    .container {
+        width: 95%;
+    }
+
+    .match-item {
+        flex-direction: column;
+        align-items: flex-start;
+    }
+}
+
diff --git a/src/main/resources/static/css/matchSchedule.css b/src/main/resources/static/css/matchSchedule.css
index 2d0d859800442c5317c8b46829f6e15ad1f9709e..e408266f605ac005e4092e405b59bf9096448c3c 100644
--- a/src/main/resources/static/css/matchSchedule.css
+++ b/src/main/resources/static/css/matchSchedule.css
@@ -99,6 +99,7 @@ button {
     justify-content: space-between;
     align-items: center;
     gap: 20px;
+    cursor: pointer;
 }
 
 .match-item p {
diff --git a/src/main/resources/static/css/navBar.css b/src/main/resources/static/css/navBar.css
index 379656e02c12ad690733b5e8e3b14d2c2f39b4ad..d82debcbde6a3b8dc4b8aa938a5e4a0cd1d9aeed 100644
--- a/src/main/resources/static/css/navBar.css
+++ b/src/main/resources/static/css/navBar.css
@@ -93,7 +93,7 @@ body {
 .navbar .auth-buttons .login-btn {
     background-color: #007BFF;
     width: 100px;
-    text-align-all: center;
+    text-align: center;
     margin-bottom: 5px;
     color: white;
     font-weight: bold;
@@ -102,7 +102,7 @@ body {
 .navbar .auth-buttons .signup-btn {
     background-color: #28a745;
     width: 100px;
-    text-align-all: center;
+    text-align: center;
     margin-bottom: 5px;
     color: white;
     font-weight: bold;
@@ -110,7 +110,7 @@ body {
 .navbar .auth-buttons .subscribe-btn {
     background-color: #d68418;
     width: 100px;
-    text-align-all: center;
+    text-align: center;
     margin-bottom: 5px;
     color: white;
     font-weight: bold;
diff --git a/src/main/resources/static/css/rankingTable.css b/src/main/resources/static/css/rankingTable.css
new file mode 100644
index 0000000000000000000000000000000000000000..f116967ca25363ea131a73e83416651cbaa0d185
--- /dev/null
+++ b/src/main/resources/static/css/rankingTable.css
@@ -0,0 +1,117 @@
+/* 全局样式重置 */
+body {
+    font-family: Arial, sans-serif;
+    background-color: #f8f9fa;
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+    color: #333;
+}
+
+/* 滤镜部分 */
+.filter-container {
+    text-align: center;
+    margin: 20px 0;
+    font-size: 14px;
+}
+
+.filter-container label {
+    margin: 0 10px;
+    font-weight: bold;
+    color: #555;
+}
+
+.filter-container select {
+    padding: 8px 12px;
+    border-radius: 25px;
+    border: 2px solid #ff758c;
+    outline: none;
+    font-size: 14px;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    background: white;
+}
+
+.filter-container select:hover {
+    background: #ff758c;
+    color: white;
+}
+
+/* 表格容器样式 */
+.table-container {
+    width: 90%;
+    margin: 20px auto;
+    text-align: center; /* 子元素居中 */
+}
+
+/* 表格标题 */
+.table-title {
+    font-size: 24px;
+    font-weight: bold;
+    color: #333;
+    margin-bottom: 10px;
+    text-transform: uppercase;
+    letter-spacing: 1px;
+}
+
+/* 表格样式 */
+table {
+    width: 100%;
+    border-collapse: collapse;
+    margin: 0 auto;
+    background: #2d2d2d;
+    color: #f9f9f9;
+    border-radius: 10px;
+    overflow: hidden;
+    box-shadow: 0 8px 15px rgba(0, 0, 0, 0.2);
+    transition: all 0.3s ease;
+}
+
+thead {
+    background: linear-gradient(90deg, #ff7eb3, #ff758c);
+    color: white;
+    font-weight: bold;
+}
+
+thead th {
+    padding: 12px 15px;
+    text-align: left;
+}
+
+tbody tr:nth-child(odd) {
+    background: rgba(255, 255, 255, 0.05);
+}
+
+tbody tr:nth-child(even) {
+    background: rgba(0, 0, 0, 0.05);
+}
+
+tbody tr:hover {
+    background: #ff7eb3;
+    color: white;
+    cursor: pointer;
+    transform: scale(1.02);
+    transition: all 0.2s ease-in-out;
+}
+
+tbody td {
+    padding: 10px 15px;
+    text-align: left;
+}
+
+/* 动画效果 */
+.fade-in {
+    animation: fadeIn 0.5s ease-in-out forwards;
+}
+
+@keyframes fadeIn {
+    from {
+        opacity: 0;
+        transform: translateY(10px);
+    }
+    to {
+        opacity: 1;
+        transform: translateY(0);
+    }
+}
+
diff --git a/src/main/resources/static/html/backGroundMatch.html b/src/main/resources/static/html/backGroundMatch.html
new file mode 100644
index 0000000000000000000000000000000000000000..68434033b4d832d1f3feaa880a7a436630a0def4
--- /dev/null
+++ b/src/main/resources/static/html/backGroundMatch.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Match Management</title>
+    <link rel="stylesheet" href="/css/backGroundMatch.css">
+</head>
+<body>
+    <h1>Match Management</h1>
+    <h2>Match List</h2>
+    <table id="matchTable">
+        <thead>
+        <tr>
+            <th>ID</th>
+            <th>Sport</th>
+            <th>Player A ID</th>
+            <th>Player B ID</th>
+            <th>Plan Time</th>
+            <th>Status</th>
+            <th>Score A</th>
+            <th>Score B</th>
+            <th>Confirm A</th>
+            <th>Confirm B</th>
+            <th>Winner ID</th>
+        </tr>
+        </thead>
+        <tbody>
+        <!-- matches show threr ++ -->
+        </tbody>
+    </table>
+    <hr>
+    <div id="addMatchForm">
+        <h2>Add Match</h2>
+        <form id="matchForm">
+            <label for="sport">Sport: </label>
+            <input type="text" id="sport" name="sport" required><br>
+            <label for="playerAId">Player A ID: </label>
+            <input type="number" id="playerAId" name="playerAId" required><br>
+            <label for="playerBId">Player B ID: </label>
+            <input type="number" id="playerBId" name="playerBId" required><br>
+            <label for="planTime">Plan Time: </label>
+            <input type="datetime-local" id="planTime" name="planTime" required><br>
+            <label for="status">Status: </label>
+            <input type="text" id="status" name="status" required><br>
+            <label for="scoreA">Score A: </label>
+            <input type="number" id="scoreA" name="scoreA" required><br>
+            <label for="scoreB">Score B: </label>
+            <input type="number" id="scoreB" name="scoreB" required><br>
+            <label for="confirmByA">Confirm by A: </label>
+            <input type="checkbox" id="confirmByA" name="confirmByA"><br>
+            <label for="confirmByB">Confirm by B: </label>
+            <input type="checkbox" id="confirmByB" name="confirmByB"><br>
+            <label for="winnerId">Winner ID: </label>
+            <input type="number" id="winnerId" name="winnerId"><br>
+            <button type="button" onclick="addMatch()">Add Match</button>
+        </form>
+    </div>
+    <script src="/js/backGroundMatch.js"></script>
+</body>
+</html>
diff --git a/src/main/resources/static/html/matchDetail.html b/src/main/resources/static/html/matchDetail.html
index 504dfd3ce4e338089fa40908e5e6c84ddf699fa1..5b992d0ed09f8b69d18433b9de41c0159d482c6b 100644
--- a/src/main/resources/static/html/matchDetail.html
+++ b/src/main/resources/static/html/matchDetail.html
@@ -3,100 +3,7 @@
 <head>
     <meta charset="UTF-8">
     <title>Match Detail</title>
-    <style>
-        * {
-            margin: 0;
-            padding: 0;
-            box-sizing: border-box;
-        }
-
-        body {
-            font-family: Arial, sans-serif;
-            background-color: #f4f4f4;
-            color: #333;
-        }
-        .title-h1{
-            h1 {
-                background-color: #4a4a4a;
-                p {
-                    font-size: 36px;
-                    color: white;
-
-                    font-weight: bold;
-                    text-align: center;
-                }
-
-            }
-        }
-        .container {
-            width: 80%;
-            margin: 20px auto;
-        }
-
-        header {
-            text-align: center;
-            margin-bottom: 30px;
-        }
-        #matchDetails {
-            margin-left: 45px;
-            align-items: center;
-            background-color: #fff;
-            border-radius: 12px;
-            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
-            width: 100%;
-            max-width: 900px;
-            padding: 30px;
-            box-sizing: border-box;
-            margin-top: 30px;
-        }
-
-        h2 {
-            text-align: center;
-            font-size: 2.5em;
-            color: #333;
-            margin-bottom: 20px;
-        }
-
-        #matchScore {
-            font-size: 2.4em;
-            line-height: 1.6;
-            color: #444;
-            margin: 20px 0;
-        }
-
-        #matchScore p {
-            text-align: center;
-        }
-
-        #matchInfo {
-            font-size: 1.2em;
-            line-height: 1.6;
-            color: #444;
-        }
-
-        #matchInfo p {
-            margin: 15px 0;
-            padding: 10px;
-            background-color: #f9f9f9;
-            border-radius: 6px;
-        }
-
-        strong {
-            color: #2d2d2d;
-        }
-        /*adjust for phone*/
-        @media screen and (max-width: 768px) {
-            .container {
-                width: 95%;
-            }
-
-            .match-item {
-                flex-direction: column;
-                align-items: flex-start;
-            }
-        }
-
-    </style>
+    <link rel="stylesheet" href="/css/matchDetail.css">
     <link rel="stylesheet" href="/css/navBar.css">
     <link rel="stylesheet" href="/css/footer.css">
 </head>
@@ -123,33 +30,5 @@
         loadFooter('footer-container');
     </script>
 </body>
-<script>
-    const urlParams = new URLSearchParams(window.location.search);
-    const matchId = urlParams.get(`id`);
-    // 获取比赛详情
-    async function fetchMatchDetails(id) {
-        try {
-            const response = await fetch(`/match/${id}`);
-            const matchData = await response.json();
-
-            const matchInfo = document.getElementById('matchInfo');
-            const matchScore = document.getElementById('matchScore');
-            matchScore.innerHTML = `<p><strong></strong>${matchData.scoreA} - ${matchData.scoreB}</p>
-`
-            matchInfo.innerHTML = `
-                <p><strong>Sport: </strong>${matchData.sport}</p>
-                <p><strong>Players: </strong>${matchData.playerAId} vs ${matchData.playerBId}</p>
-                <p><strong>Scheduled Time: </strong>${new Date(matchData.planTime).toLocaleString()}</p>
-                <p><strong>Status: </strong>${matchData.status}</p>
-                <p><strong>Winner: </strong>${matchData.winnerId ? matchData.winnerId : 'N/A'}</p>
-            `;
-        } catch (error) {
-            console.error('Error fetching match details:', error);
-        }
-    }
-
-    // 加载比赛详情
-    fetchMatchDetails(matchId);
-</script>
-
+<script src="/js/matchDetail.js"></script>
 </html>
\ No newline at end of file
diff --git a/src/main/resources/static/html/matchSchedule.html b/src/main/resources/static/html/matchSchedule.html
index 2ee5d891cc708d532beb131f431090d7e3620bb9..884a117f7dbd436c7aa1778c3730cb8e66e65d44 100644
--- a/src/main/resources/static/html/matchSchedule.html
+++ b/src/main/resources/static/html/matchSchedule.html
@@ -17,7 +17,6 @@
 
     <div class="container">
 <!--        <h1>Sports League Schedule</h1>-->
-
         <!-- Filter -->
         <div class="filter-panel">
             <label for="sportSelect">Filter by Sport:</label>
@@ -38,7 +37,7 @@
         <!-- time sort button -->
             <button id="sortTimeBtn">Sort by Time</button>
         </div>
-        <!-- 搜索框 -->
+        <!-- search -->
         <input type="text" id="searchInput" placeholder="Search matches id or player id" />
         <!-- Matches List -->
         <div id="matchesList" class="matches-list">
diff --git a/src/main/resources/static/html/navBar.html b/src/main/resources/static/html/navBar.html
index 061922a6868a12548c21868511595645c181a042..fa6157844d83f9834b3f8cb2e2cfae1b8a22d941 100644
--- a/src/main/resources/static/html/navBar.html
+++ b/src/main/resources/static/html/navBar.html
@@ -9,7 +9,7 @@
         <li><a href="#">Rules</a></li>
         <li><a href="#">Players</a></li>
         <li><a href="http://localhost:8080/html/matchSchedule.html">Matches</a></li>
-        <li><a href="#">Rankings</a></li>
+        <li><a href="http://localhost:8080/html/ranking.html">Rankings</a></li>
     </ul>
     <!--    put login、 signup subscribe links here-->
     <div class="auth-buttons">
diff --git a/src/main/resources/static/html/ranking.html b/src/main/resources/static/html/ranking.html
new file mode 100644
index 0000000000000000000000000000000000000000..c9ff9753da94074d46005e75bb706310c07c6d9c
--- /dev/null
+++ b/src/main/resources/static/html/ranking.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Sports league rankings</title>
+  <link rel="stylesheet" href="/css/navBar.css">
+  <link rel="stylesheet" href="/css/footer.css">
+  <link rel="stylesheet" href="/css/rankingTable.css">
+</head>
+<body>
+<div id="navbar-container"></div>
+
+<div class="filter-container">
+  <label for="filter-sport">Filter by Sport:</label>
+  <select id="filter-sport" onchange="loadRankings()">
+    <option value="all">All</option>
+    <option value="TableTennis">Table Tennis</option>
+    <option value="Darts">Dart</option>
+    <option value="Pools">Pools</option>
+  </select>
+
+  <label for="sort-option">Sort by:</label>
+  <select id="sort-option" onchange="loadRankings()">
+    <option value="asc">Ascending</option>
+    <option value="desc">Descending</option>
+  </select>
+</div>
+<div class="table-container">
+  <h1 class="table-title">Rankings</h1>
+
+<table>
+  <thead>
+  <tr>
+    <th>Ranking</th>
+    <th>Username</th>
+    <th>Wins</th>
+    <th>sport</th>
+
+  </tr>
+  </thead>
+  <tbody id="ranking-table">
+  <!-- Data will be dynamically inserted here -->
+  </tbody>
+</table>
+</div>
+
+<div id="footer-container"></div>
+<script src="/js/navBar.js"></script>
+<script src="/js/footer.js"></script>
+<script>
+  loadNavbar('navbar-container');
+  loadFooter('footer-container');
+</script>
+<script src="/js/rankingTable.js"></script>
+<script src="/js/matchSchedule.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/main/resources/static/js/backGroundMatch.js b/src/main/resources/static/js/backGroundMatch.js
new file mode 100644
index 0000000000000000000000000000000000000000..7e5948c1a690fe7768d9b7c2957869dcdd0a61fb
--- /dev/null
+++ b/src/main/resources/static/js/backGroundMatch.js
@@ -0,0 +1,183 @@
+const MATCHES_API_URL = '/match';
+// let matches = []
+window.onload = function() {
+    fetchMatchItems();
+};
+// // get all match items
+// async function fetchMatch() {
+//     function displayMatch(match) {
+//
+//     }
+//
+//     try {
+//         const res = await  fetch(MATCHES_API_URL);
+//         matches = await res.json();
+//         displayMatch(matches);
+//     }catch(err){
+//         console.error('error fetching match data', err)
+//     }
+// }
+// function displayMatch(matches) {
+//     // generate the match in tbody
+//     const tableBody = document.querySelector('#matchTable tbody');
+//     // Clear previous rows
+//     tableBody.innerHTML = '';
+//     // all match
+//     matches.forEach(match => {
+//         const row = document.createElement('tr');
+//         row.innerHTML = `
+//                     <td>${match.id}</td>
+//                     <td>${match.sport}</td>
+//                     <td>${match.playerAId}</td>
+//                     <td>${match.playerBId}</td>
+//                     <td>${match.planTime}</td>
+//                     <td>${match.status}</td>
+//                     <td>${match.scoreA}</td>
+//                     <td>${match.scoreB}</td>
+//                     <td>${match.confirmByA}</td>
+//                     <td>${match.confirmByB}</td>
+//                     <td>${match.winnerId}</td>
+//                     <td>
+//                         <!-- edit button   -->
+//                         <button onclick="editMatch(${match.id})">Edit</button>
+//                         <!-- delete  button -->
+//                         <button onclick="deleteMatch(${match.id})">Delete</button>
+//                     </td>
+//                 `;
+//         tableBody.appendChild(row);
+//     });
+// }
+
+// show all matches
+function fetchMatchItems() {
+    fetch(MATCHES_API_URL)
+        .then(res => res.json())
+        .then(data => {
+            // console.log(data)
+            // generate the match in tbody
+            const tableBody = document.querySelector('#matchTable tbody');
+            // Clear previous rows
+            tableBody.innerHTML = '';
+            // all match
+            data.forEach(match => {
+                const matchItem = document.createElement('tr');
+                matchItem.innerHTML = `
+                    <td>${match.id}</td>
+                    <td>${match.sport}</td>
+                    <td>${match.playerAId}</td>
+                    <td>${match.playerBId}</td>
+                    <td>${match.planTime}</td>
+                    <td>${match.status}</td>
+                    <td>${match.scoreA}</td>
+                    <td>${match.scoreB}</td>
+                    <td>${match.confirmByA}</td>
+                    <td>${match.confirmByB}</td>
+                    <td>${match.winnerId}</td>
+                    <td>
+                        <!-- edit button   -->
+                        <button onclick="editMatch(${match.id})">Edit</button>
+                        <!-- delete  button -->
+                        <button onclick="deleteMatch(${match.id})">Delete</button>
+                    </td>
+                `;
+                tableBody.appendChild(matchItem);
+            });
+        })
+        .catch(err => console.error('error:', err));
+}
+
+// Add a new match
+function addMatch() {
+    const matchForm = document.getElementById('matchForm');
+    // formData object
+    const formData = new FormData(matchForm);
+    const matchData = {};
+
+    formData.forEach((value, key) => {
+        matchData[key] = value;
+    });
+    fetch(MATCHES_API_URL, {
+        method: 'POST',
+        // for post must set headers for json
+        headers: {
+            'Content-Type': 'application/json',
+        },
+        // json => string
+        body: JSON.stringify(matchData),
+    })
+        .then(res => res.json())
+        .then(() => {
+            alert('Match added successfully!');
+            // refresh form
+            fetchMatchItems();
+            matchForm.reset();
+        })
+        .catch(err => console.error('error when add match:', err));
+}
+
+// delete a match by id
+function deleteMatch(id) {
+    fetch(`/match/${id}`, {
+        method: 'DELETE',
+    })
+        .then(res => res.json())
+        .then(() => {
+            alert('match deleted successfully!');
+            fetchMatchItems(); // Refresh match list
+        })
+        .catch(err => console.error('error when delete match:', err));
+}
+
+// edit a match and show it in the same palce as add
+function editMatch(id) {
+    fetch(`/match/${id}`)
+        .then(res => res.json())
+        .then(match => {
+            document.getElementById('sport').value = match.sport;
+            document.getElementById('playerAId').value = match.playerAId;
+            document.getElementById('playerBId').value = match.playerBId;
+            document.getElementById('planTime').value = match.planTime;
+            document.getElementById('status').value = match.status;
+            document.getElementById('scoreA').value = match.scoreA;
+            document.getElementById('scoreB').value = match.scoreB;
+            document.getElementById('confirmByA').checked = match.confirmByA;
+            document.getElementById('confirmByB').checked = match.confirmByB;
+            document.getElementById('winnerId').value = match.winnerId;
+            // change the add button to an update button
+            const addButton = document.querySelector('#matchForm button');
+            addButton.textContent = 'Update Match';
+            //  update an existing match
+            addButton.setAttribute('onclick', `updateMatch(${id})`);
+        })
+        .catch(error => console.error('error when edit match:', error));
+}
+
+// update an existing match
+function updateMatch(id) {
+    const matchForm = document.getElementById('matchForm');
+    const formData = new FormData(matchForm);
+    const matchData = {};
+
+    formData.forEach((value, key) => {
+        matchData[key] = value;
+    });
+
+    fetch(`/match/${id}`, {
+        method: 'PUT',
+        headers: {
+            'Content-Type': 'application/json',
+        },
+        body: JSON.stringify(matchData),
+    })
+        .then(res => res.json())
+        .then(() => {
+            alert('match updated successfully!');
+            fetchMatchItems();
+            matchForm.reset();
+            // change the Update button back to Add button
+            const addButton = document.querySelector('#matchForm button');
+            addButton.textContent = 'Add Match';
+            addButton.setAttribute('onclick', 'addMatch()');
+        })
+        .catch(err => console.error('error update match:', err));
+}
diff --git a/src/main/resources/static/js/matchDetail.js b/src/main/resources/static/js/matchDetail.js
new file mode 100644
index 0000000000000000000000000000000000000000..85ae5c2c7fd346128501164f943e6b6cc2029765
--- /dev/null
+++ b/src/main/resources/static/js/matchDetail.js
@@ -0,0 +1,24 @@
+    const urlParams = new URLSearchParams(window.location.search);
+    const matchId = urlParams.get(`id`);
+    // 获取比赛详情
+    async function fetchMatchDetails(id) {
+    try {
+    const response = await fetch(`/match/${id}`);
+    const matchData = await response.json();
+
+    const matchInfo = document.getElementById('matchInfo');
+    const matchScore = document.getElementById('matchScore');
+    matchScore.innerHTML = `<p><strong></strong>${matchData.scoreA} - ${matchData.scoreB}</p>
+`
+    matchInfo.innerHTML = `
+                <p><strong>Sport: </strong>${matchData.sport}</p>
+                <p><strong>Players: </strong>${matchData.playerAId} vs ${matchData.playerBId}</p>
+                <p><strong>Scheduled Time: </strong>${new Date(matchData.planTime).toLocaleString()}</p>
+                <p><strong>Status: </strong>${matchData.status}</p>
+                <p><strong>Winner: </strong>${matchData.winnerId ? matchData.winnerId : 'N/A'}</p>
+            `;
+} catch (error) {
+    console.error('Error fetching match details:', error);
+}
+}
+    fetchMatchDetails(matchId);
\ No newline at end of file
diff --git a/src/main/resources/static/js/rankingTable.js b/src/main/resources/static/js/rankingTable.js
new file mode 100644
index 0000000000000000000000000000000000000000..4fc73715d56666ebf495744b70e9ecc44d899a4f
--- /dev/null
+++ b/src/main/resources/static/js/rankingTable.js
@@ -0,0 +1,55 @@
+// Function to add fade-in animation
+function applyFadeIn() {
+    const tableBody = document.getElementById('ranking-table');
+    tableBody.classList.add('fade-in'); // Add animation class
+    setTimeout(() => tableBody.classList.remove('fade-in'), 500); // Remove class after animation
+}
+
+async function loadRankings() {
+    const sport = document.getElementById('filter-sport').value;
+    const sortOption = document.getElementById('sort-option').value;
+
+    let apiUrl;
+
+    if (sport === "all") {
+        apiUrl = `/rankings/byallandsort?order=${sortOption}`;
+    } else {
+        apiUrl = `/rankings/bysportandsort?sport=${sport}&order=${sortOption}`;
+    }
+    try {
+        const response = await fetch(apiUrl);
+        if (!response.ok) {
+            throw new Error(`HTTP error! Status: ${response.status}`);
+        }
+
+        const rankings = await response.json();
+
+        const tableBody = document.getElementById('ranking-table');
+        tableBody.innerHTML = ''; // Clear current table content
+
+        // Add rows to the table
+        rankings.forEach((ranking, index) => {
+            const row = document.createElement('tr');
+            row.innerHTML = `
+                <td>${index + 1}</td>
+                <td>${ranking.username || 'N/A'}</td>
+                <td>${ranking.wins || 0}</td>
+                <td>${ranking.sport || 'All'}</td>
+            `;
+            tableBody.appendChild(row);
+        });
+
+        // Apply fade-in effect
+        applyFadeIn();
+    } catch (error) {
+        console.error('Error fetching rankings:', error);
+    }
+}
+
+// Add event listeners
+document.getElementById('filter-sport').addEventListener('change', loadRankings);
+document.getElementById('sort-option').addEventListener('change', loadRankings);
+
+window.onload = loadRankings;
+
+
diff --git a/src/main/resources/templates/ranking/ranking.html b/src/main/resources/templates/ranking/ranking.html
new file mode 100644
index 0000000000000000000000000000000000000000..566549bdf8fae810809c1a81066000687cb338f6
--- /dev/null
+++ b/src/main/resources/templates/ranking/ranking.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+</head>
+<body>
+
+</body>
+</html>
\ No newline at end of file