File size: 4,387 Bytes
9a92a42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
import LocationHistory from "../model/locationHistory.model";
import User from "../model/user.model";
import { Request, Response } from "express";

// Helper to get current date in YYYY-MM-DD format
const getTodayDateString = (): string => {
  const now = new Date();
  return now.toISOString().split('T')[0];
};

// GET /location/users/latest
export const getAllUsersLatest = async (req: Request, res: Response) => {
  try {
    const users = await User.find({ isActive: true }).select('location lastActive username profilePhoto role');
    return res.json(users.filter(u => u.location && u.location.coordinates && u.location.coordinates.length === 2));
  } catch (err) {
    console.error(err);
    return res.status(500).json({ message: 'Server error' });
  }
};

export const updateLocation = async (req: Request, res: Response) => {
  try {
    const userId = req.userId;
    const { longitude, latitude } = req.body;

    if (!longitude || !latitude) {
      return res.status(400).json({ message: "Location missing" });
    }

    const today = getTodayDateString();
    const coordinates: [number, number] = [longitude, latitude];

    // 1) Update latest location in User model
    await User.findByIdAndUpdate(userId, {
      location: {
        type: "Point",
        coordinates
      },
      lastActive: new Date()
    });

    // 2) Upsert location history for today
    await LocationHistory.findOneAndUpdate(
      { user: userId, date: today },
      {
        $push: {
          locations: {
            coordinates,
            timestamp: new Date()
          }
        },
        $set: {
          lastLocation: {
            type: "Point",
            coordinates
          }
        }
      },
      { upsert: true, new: true }
    );

    return res.json({ message: "Location updated" });
  } catch (err) {
    console.error(err);
    return res.status(500).json({ message: "Server error" });
  }
};

// Get user's location history for a specific date
export const getLocationHistory = async (req: Request, res: Response) => {
  try {
    const userId = req.userId;
    const { date } = req.query; // Expected format: YYYY-MM-DD

    if (!date || typeof date !== 'string') {
      return res.status(400).json({ message: "Date required (YYYY-MM-DD)" });
    }

    const history = await LocationHistory.findOne({ user: userId, date });

    if (!history) {
      return res.status(404).json({ message: "No location data for this date" });
    }

    return res.json({
      date: history.date,
      locations: history.locations,
      totalPoints: history.locations.length
    });
  } catch (err) {
    console.error(err);
    return res.status(500).json({ message: "Server error" });
  }
};

// Get user's location history for a date range
export const getLocationHistoryRange = async (req: Request, res: Response) => {
  try {
    const userId = req.userId;
    const { startDate, endDate } = req.query;

    if (!startDate || !endDate || typeof startDate !== 'string' || typeof endDate !== 'string') {
      return res.status(400).json({ message: "startDate and endDate required (YYYY-MM-DD)" });
    }

    const history = await LocationHistory.find({
      user: userId,
      date: { $gte: startDate, $lte: endDate }
    }).sort({ date: 1 });

    return res.json({
      days: history.length,
      history: history.map(h => ({
        date: h.date,
        locationCount: h.locations.length,
        lastLocation: h.lastLocation
      }))
    });
  } catch (err) {
    console.error(err);
    return res.status(500).json({ message: "Server error" });
  }
};

// Get nearby users based on their last known location
export const getNearbyUsers = async (req: Request, res: Response) => {
  try {
    const userId = req.userId;
    const { maxDistance = 5000 } = req.query; // default 5km

    const user = await User.findById(userId);
    if (!user?.location) {
      return res.status(400).json({ message: "User location not set" });
    }

    const nearbyUsers = await User.find({
      _id: { $ne: userId },
      location: {
        $near: {
          $geometry: user.location,
          $maxDistance: Number(maxDistance)
        }
      }
    }).limit(20).select('username profilePhoto location role');

    return res.json({ nearbyUsers });
  } catch (err) {
    console.error(err);
    return res.status(500).json({ message: "Server error" });
  }
};